diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 051660be9c4..71f6eae45aa 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -2321,11 +2321,10 @@ fn assoc_ty_own_obligations<'cx, 'tcx>( nested: &mut Vec>, ) { let tcx = selcx.tcx(); - for predicate in tcx + let own = tcx .predicates_of(obligation.predicate.item_def_id) - .instantiate_own(tcx, obligation.predicate.substs) - .predicates - { + .instantiate_own(tcx, obligation.predicate.substs); + for (predicate, span) in std::iter::zip(own.predicates, own.spans) { let normalized = normalize_with_depth_to( selcx, obligation.param_env, @@ -2334,9 +2333,30 @@ fn assoc_ty_own_obligations<'cx, 'tcx>( predicate, nested, ); + + let nested_cause = if matches!( + obligation.cause.code(), + super::CompareImplItemObligation { .. } + | super::CheckAssociatedTypeBounds { .. } + | super::AscribeUserTypeProvePredicate(..) + ) { + obligation.cause.clone() + } else if span.is_dummy() { + ObligationCause::new( + obligation.cause.span, + obligation.cause.body_id, + super::ItemObligation(obligation.predicate.item_def_id), + ) + } else { + ObligationCause::new( + obligation.cause.span, + obligation.cause.body_id, + super::BindingObligation(obligation.predicate.item_def_id, span), + ) + }; nested.push(Obligation::with_depth( tcx, - obligation.cause.clone(), + nested_cause, obligation.recursion_depth + 1, obligation.param_env, normalized, diff --git a/src/test/ui/generic-associated-types/own-bound-span.rs b/src/test/ui/generic-associated-types/own-bound-span.rs new file mode 100644 index 00000000000..3699f7296f5 --- /dev/null +++ b/src/test/ui/generic-associated-types/own-bound-span.rs @@ -0,0 +1,17 @@ +struct S; + +trait D { + type P; + //~^ NOTE required by this bound in `D::P` + //~| NOTE required by a bound in `D::P` +} + +impl D for S { + type P = (); +} + +fn main() { + let _: ::P; + //~^ ERROR the trait bound `String: Copy` is not satisfied + //~| NOTE the trait `Copy` is not implemented for `String` +} diff --git a/src/test/ui/generic-associated-types/own-bound-span.stderr b/src/test/ui/generic-associated-types/own-bound-span.stderr new file mode 100644 index 00000000000..8ab8ea623b2 --- /dev/null +++ b/src/test/ui/generic-associated-types/own-bound-span.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/own-bound-span.rs:14:12 + | +LL | let _: ::P; + | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `D::P` + --> $DIR/own-bound-span.rs:4:15 + | +LL | type P; + | ^^^^ required by this bound in `D::P` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr b/src/test/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr index c1aaad31e81..f05b0cd6538 100644 --- a/src/test/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr +++ b/src/test/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr @@ -3,10 +3,10 @@ error[E0311]: the parameter type `Self` may not live long enough = help: consider adding an explicit lifetime bound `Self: 'a`... = note: ...so that the type `Self` will meet its required lifetime bounds... note: ...that is required by this bound - --> $DIR/object-safety-supertrait-mentions-GAT.rs:9:39 + --> $DIR/object-safety-supertrait-mentions-GAT.rs:6:15 | -LL | trait SuperTrait: for<'a> GatTrait = T> { - | ^^^^^^^^^^^ +LL | Self: 'a; + | ^^ error: associated item referring to unboxed trait object for its own trait --> $DIR/object-safety-supertrait-mentions-GAT.rs:10:20