diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index f9abd3185052758220cee090c33c3f66762c558b..84bcec6bd199f0a6c2c92da4879fbe197aed0aab 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -170,55 +170,67 @@ fn compute_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>, elaborate: Elabo let cause = self.cause(traits::MiscObligation); let param_env = self.param_env; - if let Elaborate::All = elaborate { - let trait_assoc_items = tcx.associated_items(trait_ref.def_id); - - let predicates = obligations.iter() - .map(|obligation| obligation.predicate.clone()) - .collect(); - let implied_obligations = traits::elaborate_predicates(tcx, predicates); - let item_span: Option = self.item.map(|i| i.span); - let item = &self.item; - let implied_obligations = implied_obligations.map(|pred| { - let mut cause = cause.clone(); - match &pred { - ty::Predicate::Projection(proj) => { - if let Some(hir::ItemKind::Impl(.., impl_items)) = item.map(|i| &i.kind) { - let trait_assoc_item = tcx.associated_item(proj.projection_def_id()); - if let Some(impl_item) = impl_items.iter().filter(|item| { - item.ident == trait_assoc_item.ident - }).next() { - cause.span = impl_item.span; - cause.code = traits::AssocTypeBound( - item_span, - trait_assoc_item.ident.span, - ); - } + let item = &self.item; + let extend_cause_with_original_assoc_item_obligation = | + cause: &mut traits::ObligationCause<'_>, + pred: &ty::Predicate<'_>, + trait_assoc_items: ty::AssocItemsIterator<'_>, + | { + let item_span = item.map(|i| tcx.sess.source_map().def_span(i.span)); + match pred { + ty::Predicate::Projection(proj) => { + if let Some(hir::ItemKind::Impl(.., impl_items)) = item.map(|i| &i.kind) { + let trait_assoc_item = tcx.associated_item(proj.projection_def_id()); + if let Some(impl_item) = impl_items.iter().filter(|item| { + item.ident == trait_assoc_item.ident + }).next() { + cause.span = impl_item.span; + cause.code = traits::AssocTypeBound( + item_span, + trait_assoc_item.ident.span, + ); } } - ty::Predicate::Trait(proj) => { + } + ty::Predicate::Trait(proj) => { if let ( ty::Projection(ty::ProjectionTy { item_def_id, .. }), - Some(hir::ItemKind::Impl(.., impl_items)), - ) = (&proj.skip_binder().self_ty().kind, item.map(|i| &i.kind)) { - if let Some((impl_item, trait_assoc_item)) = trait_assoc_items.clone() + Some(hir::ItemKind::Impl(.., impl_items)), + ) = (&proj.skip_binder().self_ty().kind, item.map(|i| &i.kind)) { + if let Some((impl_item, trait_assoc_item)) = trait_assoc_items .filter(|i| i.def_id == *item_def_id) .next() - .and_then(|trait_assoc_item| impl_items.iter() - .filter(|i| i.ident == trait_assoc_item.ident) - .next() - .map(|impl_item| (impl_item, trait_assoc_item))) + .and_then(|trait_assoc_item| impl_items.iter() + .filter(|i| i.ident == trait_assoc_item.ident) + .next() + .map(|impl_item| (impl_item, trait_assoc_item))) { - cause.span = impl_item.span; - cause.code = traits::AssocTypeBound( - item_span, - trait_assoc_item.ident.span, - ); - } + cause.span = impl_item.span; + cause.code = traits::AssocTypeBound( + item_span, + trait_assoc_item.ident.span, + ); } } - _ => {} } + _ => {} + } + }; + + if let Elaborate::All = elaborate { + let trait_assoc_items = tcx.associated_items(trait_ref.def_id); + + let predicates = obligations.iter() + .map(|obligation| obligation.predicate.clone()) + .collect(); + let implied_obligations = traits::elaborate_predicates(tcx, predicates); + let implied_obligations = implied_obligations.map(|pred| { + let mut cause = cause.clone(); + extend_cause_with_original_assoc_item_obligation( + &mut cause, + &pred, + trait_assoc_items.clone(), + ); traits::Obligation::new(cause, param_env, pred) }); self.out.extend(implied_obligations); diff --git a/src/test/ui/associated-types/point-at-type-on-obligation-failure-2.stderr b/src/test/ui/associated-types/point-at-type-on-obligation-failure-2.stderr index 62bb9388633b08dda76c4ef7157c324ab659c12d..f1a2e343a7ec370e98c374e325a8203cf80879b9 100644 --- a/src/test/ui/associated-types/point-at-type-on-obligation-failure-2.stderr +++ b/src/test/ui/associated-types/point-at-type-on-obligation-failure-2.stderr @@ -1,14 +1,13 @@ error[E0277]: the trait bound `bool: Bar` is not satisfied --> $DIR/point-at-type-on-obligation-failure-2.rs:8:5 | -LL | type Assoc: Bar; - | ----- associated type defined here +LL | type Assoc: Bar; + | ----- associated type defined here ... -LL | / impl Foo for () { -LL | | type Assoc = bool; - | | ^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `bool` -LL | | } - | |_- in this `impl` item +LL | impl Foo for () { + | --------------- in this `impl` item +LL | type Assoc = bool; + | ^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `bool` error: aborting due to previous error diff --git a/src/test/ui/associated-types/point-at-type-on-obligation-failure.stderr b/src/test/ui/associated-types/point-at-type-on-obligation-failure.stderr index 95e8ebdd180b0ac2d657e67f5e97cf27eb942fd4..e4bd39c8ba62c53ab698197bdf509c0fcdc279db 100644 --- a/src/test/ui/associated-types/point-at-type-on-obligation-failure.stderr +++ b/src/test/ui/associated-types/point-at-type-on-obligation-failure.stderr @@ -1,15 +1,13 @@ error[E0271]: type mismatch resolving `::Ok == ()` --> $DIR/point-at-type-on-obligation-failure.rs:13:5 | -LL | type Ok; - | -- associated type defined here +LL | type Ok; + | -- associated type defined here ... -LL | / impl Bar for Foo { -LL | | type Ok = (); - | | ^^^^^^^^^^^^^ expected u32, found () -LL | | type Sibling = Foo2; -LL | | } - | |_- in this `impl` item +LL | impl Bar for Foo { + | ---------------- in this `impl` item +LL | type Ok = (); + | ^^^^^^^^^^^^^ expected u32, found () | = note: expected type `u32` found type `()` diff --git a/src/test/ui/issues/issue-43784-associated-type.stderr b/src/test/ui/issues/issue-43784-associated-type.stderr index cfab66302cdcab71f670ed7c1f9a5dc727fec76e..33692bd254e76a6e372e5466a123fb41d3494146 100644 --- a/src/test/ui/issues/issue-43784-associated-type.stderr +++ b/src/test/ui/issues/issue-43784-associated-type.stderr @@ -1,15 +1,15 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied --> $DIR/issue-43784-associated-type.rs:14:5 | -LL | type Assoc: Partial; - | ----- associated type defined here +LL | type Assoc: Partial; + | ----- associated type defined here ... -LL | / impl Complete for T { - | | - help: consider restricting this bound: `T: std::marker::Copy` -LL | | type Assoc = T; - | | ^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` -LL | | } - | |_- in this `impl` item +LL | impl Complete for T { + | ---------------------- in this `impl` item + | | + | help: consider restricting this bound: `T: std::marker::Copy` +LL | type Assoc = T; + | ^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` | = help: consider adding a `where T: std::marker::Copy` bound diff --git a/src/test/ui/traits/cycle-cache-err-60010.stderr b/src/test/ui/traits/cycle-cache-err-60010.stderr index a7b8dd05527a5a46606a64fd14cb1c6f96896b61..f439de88261179519c417e62ca90f271501cde97 100644 --- a/src/test/ui/traits/cycle-cache-err-60010.stderr +++ b/src/test/ui/traits/cycle-cache-err-60010.stderr @@ -9,14 +9,13 @@ LL | _parse: >::Data, error[E0275]: overflow evaluating the requirement `RootDatabase: SourceDatabase` --> $DIR/cycle-cache-err-60010.rs:31:5 | -LL | type Storage; - | ------- associated type defined here +LL | type Storage; + | ------- associated type defined here ... -LL | / impl Database for RootDatabase { -LL | | type Storage = SalsaStorage; - | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | | } - | |_- in this `impl` item +LL | impl Database for RootDatabase { + | ------------------------------ in this `impl` item +LL | type Storage = SalsaStorage; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: required because of the requirements on the impl of `Query` for `ParseQuery` = note: required because it appears within the type `SalsaStorage`