@@ -179,6 +179,47 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
179179 let item_span = item. map( |i| tcx. sess. source_map( ) . def_span( i. span) ) ;
180180 match pred {
181181 ty : : Predicate :: Projection ( proj) => {
182+ // The obligation comes not from the current `impl` nor the `trait` being
183+ // implemented, but rather from a "second order" obligation, like in
184+ // `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs`:
185+ //
186+ // error[E0271]: type mismatch resolving `<Foo2 as Bar2>::Ok == ()`
187+ // --> $DIR/point-at-type-on-obligation-failure.rs:13:5
188+ // |
189+ // LL | type Ok;
190+ // | -- associated type defined here
191+ // ...
192+ // LL | impl Bar for Foo {
193+ // | ---------------- in this `impl` item
194+ // LL | type Ok = ();
195+ // | ^^^^^^^^^^^^^ expected u32, found ()
196+ // |
197+ // = note: expected type `u32`
198+ // found type `()`
199+ //
200+ // FIXME: we would want to point a span to all places that contributed to this
201+ // obligation. In the case above, it should be closer to:
202+ //
203+ // error[E0271]: type mismatch resolving `<Foo2 as Bar2>::Ok == ()`
204+ // --> $DIR/point-at-type-on-obligation-failure.rs:13:5
205+ // |
206+ // LL | type Ok;
207+ // | -- associated type defined here
208+ // LL | type Sibling: Bar2<Ok=Self::Ok>;
209+ // | -------------------------------- obligation set here
210+ // ...
211+ // LL | impl Bar for Foo {
212+ // | ---------------- in this `impl` item
213+ // LL | type Ok = ();
214+ // | ^^^^^^^^^^^^^ expected u32, found ()
215+ // ...
216+ // LL | impl Bar2 for Foo2 {
217+ // | ---------------- in this `impl` item
218+ // LL | type Ok = u32;
219+ // | -------------- obligation set here
220+ // |
221+ // = note: expected type `u32`
222+ // found type `()`
182223 if let Some ( hir:: ItemKind :: Impl ( .., impl_items) ) = item. map ( |i| & i. kind ) {
183224 let trait_assoc_item = tcx. associated_item ( proj. projection_def_id ( ) ) ;
184225 if let Some ( impl_item) = impl_items. iter ( ) . filter ( |item| {
@@ -193,6 +234,38 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
193234 }
194235 }
195236 ty:: Predicate :: Trait ( proj) => {
237+ // An associated item obligation born out of the `trait` failed to be met.
238+ // Point at the `impl` that failed the obligation, the associated item that
239+ // needed to meet the obligation, and the definition of that associated item,
240+ // which should hold the obligation in most cases. An example can be seen in
241+ // `src/test/ui/associated-types/point-at-type-on-obligation-failure-2.rs`:
242+ //
243+ // error[E0277]: the trait bound `bool: Bar` is not satisfied
244+ // --> $DIR/point-at-type-on-obligation-failure-2.rs:8:5
245+ // |
246+ // LL | type Assoc: Bar;
247+ // | ----- associated type defined here
248+ // ...
249+ // LL | impl Foo for () {
250+ // | --------------- in this `impl` item
251+ // LL | type Assoc = bool;
252+ // | ^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `bool`
253+ //
254+ // FIXME: if the obligation comes from the where clause in the `trait`, we
255+ // should point at it:
256+ //
257+ // error[E0277]: the trait bound `bool: Bar` is not satisfied
258+ // --> $DIR/point-at-type-on-obligation-failure-2.rs:8:5
259+ // |
260+ // | trait Foo where <Self as Foo>>::Assoc: Bar {
261+ // | -------------------------- obligation set here
262+ // LL | type Assoc;
263+ // | ----- associated type defined here
264+ // ...
265+ // LL | impl Foo for () {
266+ // | --------------- in this `impl` item
267+ // LL | type Assoc = bool;
268+ // | ^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `bool`
196269 if let (
197270 ty:: Projection ( ty:: ProjectionTy { item_def_id, .. } ) ,
198271 Some ( hir:: ItemKind :: Impl ( .., impl_items) ) ,
0 commit comments