@@ -488,6 +488,13 @@ fn opt_normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
488488 ty. obligations = vec ! [ ] ;
489489 }
490490
491+ push_paranoid_cache_value_obligation ( infcx,
492+ param_env,
493+ projection_ty,
494+ cause,
495+ depth,
496+ & mut ty) ;
497+
491498 return Some ( ty) ;
492499 }
493500 Err ( ProjectionCacheEntry :: Error ) => {
@@ -612,6 +619,33 @@ fn prune_cache_value_obligations<'a, 'gcx, 'tcx>(infcx: &'a InferCtxt<'a, 'gcx,
612619 NormalizedTy { value : result. value , obligations }
613620}
614621
622+ /// Whenever we give back a cache result for a projection like `<T as
623+ /// Trait>::Item ==> X`, we *always* include the obligation to prove
624+ /// that `T: Trait` (we may also include some other obligations). This
625+ /// may or may not be necessary -- in principle, all the obligations
626+ /// that must be proven to show that `T: Trait` were also returned
627+ /// when the cache was first populated. But there is a vague concern
628+ /// that perhaps someone would not have proven those, but also not
629+ /// have used a snapshot, in which case the cache could remain
630+ /// populated even though `T: Trait` has not been shown. Returning
631+ /// this "paranoid" obligation ensures that, no matter what has come
632+ /// before, if you prove the subobligations, we at least know that `T:
633+ /// Trait` is implemented.
634+ fn push_paranoid_cache_value_obligation < ' a , ' gcx , ' tcx > ( infcx : & ' a InferCtxt < ' a , ' gcx , ' tcx > ,
635+ param_env : ty:: ParamEnv < ' tcx > ,
636+ projection_ty : ty:: ProjectionTy < ' tcx > ,
637+ cause : ObligationCause < ' tcx > ,
638+ depth : usize ,
639+ result : & mut NormalizedTy < ' tcx > )
640+ {
641+ let trait_ref = projection_ty. trait_ref ( infcx. tcx ) . to_poly_trait_ref ( ) ;
642+ let trait_obligation = Obligation { cause,
643+ recursion_depth : depth,
644+ param_env,
645+ predicate : trait_ref. to_predicate ( ) } ;
646+ result. obligations . push ( trait_obligation) ;
647+ }
648+
615649/// If we are projecting `<T as Trait>::Item`, but `T: Trait` does not
616650/// hold. In various error cases, we cannot generate a valid
617651/// normalized projection. Therefore, we create an inference variable
0 commit comments