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