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