diff options
| author | Michael Goulet <michael@errs.io> | 2021-12-25 22:45:05 -0800 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2022-03-14 15:35:06 -0700 |
| commit | f14a5fd7127af1e774b76deea5a749ced33b23a1 (patch) | |
| tree | 28d6da30010cf9e2fb9e77e8396c0822dafe10b0 | |
| parent | 285fa7ecd05dcbfdaf2faaf20400f5f92b39b3c6 (diff) | |
| download | rust-f14a5fd7127af1e774b76deea5a749ced33b23a1.tar.gz rust-f14a5fd7127af1e774b76deea5a749ced33b23a1.zip | |
check Projection supertrait bounds when confirming dyn candidate
3 files changed, 53 insertions, 1 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index c7e0c35436a..8fd7664d578 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -468,7 +468,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .predicates .into_iter() { - if let ty::PredicateKind::Trait(..) = super_trait.kind().skip_binder() { + if let ty::PredicateKind::Trait(..) | ty::PredicateKind::Projection(..) = + super_trait.kind().skip_binder() + { let normalized_super_trait = normalize_with_depth_to( self, obligation.param_env, diff --git a/src/test/ui/traits/object/enforce-supertrait-projection.rs b/src/test/ui/traits/object/enforce-supertrait-projection.rs new file mode 100644 index 00000000000..0ea944ec2df --- /dev/null +++ b/src/test/ui/traits/object/enforce-supertrait-projection.rs @@ -0,0 +1,24 @@ +trait SuperTrait { + type A; + type B; +} + +trait Trait: SuperTrait<A = <Self as SuperTrait>::B> {} + +fn transmute<A, B>(x: A) -> B { + foo::<A, B, dyn Trait<A = A, B = B>>(x) + //~^ ERROR type mismatch resolving `<dyn Trait<A = A, B = B> as SuperTrait>::A == B` +} + +fn foo<A, B, T: ?Sized>(x: T::A) -> B +where + T: Trait<B = B>, +{ + x +} + +static X: u8 = 0; +fn main() { + let x = transmute::<&u8, &[u8; 1_000_000]>(&X); + println!("{:?}", x[100_000]); +} diff --git a/src/test/ui/traits/object/enforce-supertrait-projection.stderr b/src/test/ui/traits/object/enforce-supertrait-projection.stderr new file mode 100644 index 00000000000..a3d17fabbe4 --- /dev/null +++ b/src/test/ui/traits/object/enforce-supertrait-projection.stderr @@ -0,0 +1,26 @@ +error[E0271]: type mismatch resolving `<dyn Trait<A = A, B = B> as SuperTrait>::A == B` + --> $DIR/enforce-supertrait-projection.rs:9:5 + | +LL | fn transmute<A, B>(x: A) -> B { + | - - expected type parameter + | | + | found type parameter +LL | foo::<A, B, dyn Trait<A = A, B = B>>(x) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `B`, found type parameter `A` + | + = note: expected type parameter `B` + found type parameter `A` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters +note: required by a bound in `foo` + --> $DIR/enforce-supertrait-projection.rs:15:8 + | +LL | fn foo<A, B, T: ?Sized>(x: T::A) -> B + | --- required by a bound in this +LL | where +LL | T: Trait<B = B>, + | ^^^^^^^^^^^^ required by this bound in `foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. |
