@@ -179,6 +179,47 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
179
179
let item_span = item. map( |i| tcx. sess. source_map( ) . def_span( i. span) ) ;
180
180
match pred {
181
181
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 `()`
182
223
if let Some ( hir:: ItemKind :: Impl ( .., impl_items) ) = item. map ( |i| & i. kind ) {
183
224
let trait_assoc_item = tcx. associated_item ( proj. projection_def_id ( ) ) ;
184
225
if let Some ( impl_item) = impl_items. iter ( ) . filter ( |item| {
@@ -193,6 +234,38 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
193
234
}
194
235
}
195
236
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`
196
269
if let (
197
270
ty:: Projection ( ty:: ProjectionTy { item_def_id, .. } ) ,
198
271
Some ( hir:: ItemKind :: Impl ( .., impl_items) ) ,
0 commit comments