1+ use std:: cell:: RefCell ;
2+
13use crate :: hir:: def_id:: DefId ;
24use crate :: infer:: outlives:: env:: RegionBoundPairs ;
35use crate :: infer:: { GenericKind , VerifyBound } ;
@@ -17,6 +19,7 @@ pub struct VerifyBoundCx<'cx, 'tcx> {
1719 region_bound_pairs : & ' cx RegionBoundPairs < ' tcx > ,
1820 implicit_region_bound : Option < ty:: Region < ' tcx > > ,
1921 param_env : ty:: ParamEnv < ' tcx > ,
22+ elaborator : RefCell < traits:: Elaborator < ' tcx > > ,
2023}
2124
2225impl < ' cx , ' tcx > VerifyBoundCx < ' cx , ' tcx > {
@@ -26,7 +29,13 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
2629 implicit_region_bound : Option < ty:: Region < ' tcx > > ,
2730 param_env : ty:: ParamEnv < ' tcx > ,
2831 ) -> Self {
29- Self { tcx, region_bound_pairs, implicit_region_bound, param_env }
32+ Self {
33+ tcx,
34+ region_bound_pairs,
35+ implicit_region_bound,
36+ param_env,
37+ elaborator : RefCell :: new ( traits:: Elaborator :: new ( tcx) ) ,
38+ }
3039 }
3140
3241 /// Returns a "verify bound" that encodes what we know about
@@ -113,10 +122,10 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
113122 self . tcx . mk_projection ( projection_ty. item_def_id , projection_ty. substs ) ;
114123
115124 // Search the env for where clauses like `P: 'a`.
116- let env_bounds = self
117- . projection_approx_declared_bounds_from_env ( projection_ty )
118- . into_iter ( )
119- . map ( |ty:: OutlivesPredicate ( ty, r) | {
125+ let mut bounds = Vec :: new ( ) ;
126+
127+ bounds . extend ( self . projection_approx_declared_bounds_from_env ( projection_ty ) . map (
128+ |ty:: OutlivesPredicate ( ty, r) | {
120129 let vb = VerifyBound :: OutlivedBy ( r) ;
121130 if ty == projection_ty_as_ty {
122131 // Micro-optimize if this is an exact match (this
@@ -126,18 +135,20 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
126135 } else {
127136 VerifyBound :: IfEq ( ty, Box :: new ( vb) )
128137 }
129- } ) ;
138+ } ,
139+ ) ) ;
130140
131141 // Extend with bounds that we can find from the trait.
132- let trait_bounds = self
133- . projection_declared_bounds_from_trait ( projection_ty)
134- . map ( |r| VerifyBound :: OutlivedBy ( r) ) ;
142+ bounds. extend (
143+ self . projection_declared_bounds_from_trait ( projection_ty)
144+ . map ( |r| VerifyBound :: OutlivedBy ( r) ) ,
145+ ) ;
135146
136147 // see the extensive comment in projection_must_outlive
137148 let ty = self . tcx . mk_projection ( projection_ty. item_def_id , projection_ty. substs ) ;
138149 let recursive_bound = self . recursive_type_bound ( ty) ;
139150
140- VerifyBound :: AnyBound ( env_bounds . chain ( trait_bounds ) . collect ( ) ) . or ( recursive_bound)
151+ VerifyBound :: AnyBound ( bounds ) . or ( recursive_bound)
141152 }
142153
143154 fn recursive_type_bound ( & self , ty : Ty < ' tcx > ) -> VerifyBound < ' tcx > {
@@ -281,13 +292,16 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
281292 let tcx = self . tcx ;
282293 let assoc_item = tcx. associated_item ( assoc_item_def_id) ;
283294 let trait_def_id = assoc_item. container . assert_trait ( ) ;
284- let trait_predicates =
285- tcx. predicates_of ( trait_def_id) . predicates . iter ( ) . map ( |( p, _) | * p) . collect ( ) ;
295+ let trait_predicates = tcx. predicates_of ( trait_def_id) . predicates . iter ( ) . map ( |( p, _) | * p) ;
296+ let mut elaborator = self . elaborator . borrow_mut ( ) ;
297+ elaborator. clear ( ) ;
298+ elaborator. extend ( trait_predicates) ;
286299 let identity_substs = InternalSubsts :: identity_for_item ( tcx, assoc_item_def_id) ;
287300 let identity_proj = tcx. mk_projection ( assoc_item_def_id, identity_substs) ;
301+
288302 self . collect_outlives_from_predicate_list (
289303 move |ty| ty == identity_proj,
290- traits :: elaborate_predicates ( tcx , trait_predicates ) ,
304+ std :: iter :: from_fn ( move || elaborator . next ( ) ) ,
291305 )
292306 . map ( |b| b. 1 )
293307 }
0 commit comments