@@ -426,11 +426,25 @@ fn opt_normalize_projection_type<'a,'b,'tcx>(
426
426
}
427
427
}
428
428
429
- /// in various error cases, we just set TyError and return an obligation
430
- /// that, when fulfilled, will lead to an error.
429
+ /// If we are projecting `<T as Trait>::Item`, but `T: Trait` does not
430
+ /// hold. In various error cases, we cannot generate a valid
431
+ /// normalized projection. Therefore, we create an inference variable
432
+ /// return an associated obligation that, when fulfilled, will lead to
433
+ /// an error.
431
434
///
432
- /// FIXME: the TyError created here can enter the obligation we create,
433
- /// leading to error messages involving TyError.
435
+ /// Note that we used to return `TyError` here, but that was quite
436
+ /// dubious -- the premise was that an error would *eventually* be
437
+ /// reported, when the obligation was processed. But in general once
438
+ /// you see a `TyError` you are supposed to be able to assume that an
439
+ /// error *has been* reported, so that you can take whatever heuristic
440
+ /// paths you want to take. To make things worse, it was possible for
441
+ /// cycles to arise, where you basically had a setup like `<MyType<$0>
442
+ /// as Trait>::Foo == $0`. Here, normalizing `<MyType<$0> as
443
+ /// Trait>::Foo> to `[type error]` would lead to an obligation of
444
+ /// `<MyType<[type error]> as Trait>::Foo`. We are supposed to report
445
+ /// an error for this obligation, but we legitimately should not,
446
+ /// because it contains `[type error]`. Yuck! (See issue #29857 for
447
+ /// one case where this arose.)
434
448
fn normalize_to_error < ' a , ' tcx > ( selcx : & mut SelectionContext < ' a , ' tcx > ,
435
449
projection_ty : ty:: ProjectionTy < ' tcx > ,
436
450
cause : ObligationCause < ' tcx > ,
@@ -441,8 +455,9 @@ fn normalize_to_error<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
441
455
let trait_obligation = Obligation { cause : cause,
442
456
recursion_depth : depth,
443
457
predicate : trait_ref. to_predicate ( ) } ;
458
+ let new_value = selcx. infcx ( ) . next_ty_var ( ) ;
444
459
Normalized {
445
- value : selcx . tcx ( ) . types . err ,
460
+ value : new_value ,
446
461
obligations : vec ! ( trait_obligation)
447
462
}
448
463
}
0 commit comments