about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/traits/trait-upcasting/fewer-associated.rs25
-rw-r--r--tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.current.stderr14
-rw-r--r--tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.next.stderr14
-rw-r--r--tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs23
-rw-r--r--tests/ui/traits/trait-upcasting/normalization.rs20
5 files changed, 96 insertions, 0 deletions
diff --git a/tests/ui/traits/trait-upcasting/fewer-associated.rs b/tests/ui/traits/trait-upcasting/fewer-associated.rs
new file mode 100644
index 00000000000..8228eea2681
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/fewer-associated.rs
@@ -0,0 +1,25 @@
+// check-pass
+// issue: 114035
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
+
+#![feature(trait_upcasting)]
+
+trait A: B {
+    type Assoc;
+}
+
+trait B {}
+
+fn upcast(a: &dyn A<Assoc = i32>) -> &dyn B {
+    a
+}
+
+// Make sure that we can drop the existential projection `A::Assoc = i32`
+// when upcasting `dyn A<Assoc = i32>` to `dyn B`. Before, we used some
+// complicated algorithm which required rebuilding a new object type with
+// different bounds in order to test that an upcast was valid, but this
+// didn't allow upcasting to t that have fewer associated types
+// than the source type.
+
+fn main() {}
diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.current.stderr b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.current.stderr
new file mode 100644
index 00000000000..59c9d573705
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.current.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/illegal-upcast-from-impl.rs:16:66
+   |
+LL | fn illegal(x: &dyn Sub<Assoc = ()>) -> &dyn Super<Assoc = i32> { x }
+   |                                        -----------------------   ^ expected trait `Super`, found trait `Sub`
+   |                                        |
+   |                                        expected `&dyn Super<Assoc = i32>` because of return type
+   |
+   = note: expected reference `&dyn Super<Assoc = i32>`
+              found reference `&dyn Sub<Assoc = ()>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.next.stderr b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.next.stderr
new file mode 100644
index 00000000000..59c9d573705
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.next.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/illegal-upcast-from-impl.rs:16:66
+   |
+LL | fn illegal(x: &dyn Sub<Assoc = ()>) -> &dyn Super<Assoc = i32> { x }
+   |                                        -----------------------   ^ expected trait `Super`, found trait `Sub`
+   |                                        |
+   |                                        expected `&dyn Super<Assoc = i32>` because of return type
+   |
+   = note: expected reference `&dyn Super<Assoc = i32>`
+              found reference `&dyn Sub<Assoc = ()>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs
new file mode 100644
index 00000000000..774474281ea
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs
@@ -0,0 +1,23 @@
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
+
+#![feature(trait_upcasting)]
+
+trait Super {
+    type Assoc;
+}
+
+trait Sub: Super {}
+
+impl<T: ?Sized> Super for T {
+    type Assoc = i32;
+}
+
+fn illegal(x: &dyn Sub<Assoc = ()>) -> &dyn Super<Assoc = i32> { x }
+//~^ ERROR mismatched types
+
+// Want to make sure that we can't "upcast" to a supertrait that has a different
+// associated type that is instead provided by a blanket impl (and doesn't come
+// from the object bounds).
+
+fn main() {}
diff --git a/tests/ui/traits/trait-upcasting/normalization.rs b/tests/ui/traits/trait-upcasting/normalization.rs
new file mode 100644
index 00000000000..c78338b0da9
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/normalization.rs
@@ -0,0 +1,20 @@
+// check-pass
+// issue: 114113
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
+
+#![feature(trait_upcasting)]
+
+trait Mirror {
+    type Assoc;
+}
+impl<T> Mirror for T {
+    type Assoc = T;
+}
+
+trait Bar<T> {}
+trait Foo<T>: Bar<<T as Mirror>::Assoc> {}
+
+fn upcast<T>(x: &dyn Foo<T>) -> &dyn Bar<T> { x }
+
+fn main() {}