@@ -488,6 +488,13 @@ fn opt_normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
488
488
ty. obligations = vec ! [ ] ;
489
489
}
490
490
491
+ push_paranoid_cache_value_obligation ( infcx,
492
+ param_env,
493
+ projection_ty,
494
+ cause,
495
+ depth,
496
+ & mut ty) ;
497
+
491
498
return Some ( ty) ;
492
499
}
493
500
Err ( ProjectionCacheEntry :: Error ) => {
@@ -612,6 +619,33 @@ fn prune_cache_value_obligations<'a, 'gcx, 'tcx>(infcx: &'a InferCtxt<'a, 'gcx,
612
619
NormalizedTy { value : result. value , obligations }
613
620
}
614
621
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
+
615
649
/// If we are projecting `<T as Trait>::Item`, but `T: Trait` does not
616
650
/// hold. In various error cases, we cannot generate a valid
617
651
/// normalized projection. Therefore, we create an inference variable
0 commit comments