diff options
Diffstat (limited to 'tests')
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() {} |
