@@ -426,11 +426,25 @@ fn opt_normalize_projection_type<'a,'b,'tcx>(
426426 }
427427}
428428
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.
431434///
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.)
434448fn normalize_to_error < ' a , ' tcx > ( selcx : & mut SelectionContext < ' a , ' tcx > ,
435449 projection_ty : ty:: ProjectionTy < ' tcx > ,
436450 cause : ObligationCause < ' tcx > ,
@@ -441,8 +455,9 @@ fn normalize_to_error<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
441455 let trait_obligation = Obligation { cause : cause,
442456 recursion_depth : depth,
443457 predicate : trait_ref. to_predicate ( ) } ;
458+ let new_value = selcx. infcx ( ) . next_ty_var ( ) ;
444459 Normalized {
445- value : selcx . tcx ( ) . types . err ,
460+ value : new_value ,
446461 obligations : vec ! ( trait_obligation)
447462 }
448463}
0 commit comments