1+ use std:: cell:: RefCell ;
2+
13use crate :: infer:: outlives:: env:: RegionBoundPairs ;
24use crate :: infer:: { GenericKind , VerifyBound } ;
35use crate :: traits;
@@ -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 > {
@@ -154,7 +165,11 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
154165 . filter ( |b| !b. must_hold ( ) )
155166 . collect :: < Vec < _ > > ( ) ;
156167
157- if bounds. len ( ) == 1 { bounds. pop ( ) . unwrap ( ) } else { VerifyBound :: AllBounds ( bounds) }
168+ if bounds. len ( ) == 1 {
169+ bounds. pop ( ) . unwrap ( )
170+ } else {
171+ VerifyBound :: AllBounds ( bounds)
172+ }
158173 }
159174
160175 /// Searches the environment for where-clauses like `G: 'a` where
@@ -281,13 +296,16 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
281296 let tcx = self . tcx ;
282297 let assoc_item = tcx. associated_item ( assoc_item_def_id) ;
283298 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 ( ) ;
299+ let trait_predicates = tcx. predicates_of ( trait_def_id) . predicates . iter ( ) . map ( |( p, _) | * p) ;
300+ let mut elaborator = self . elaborator . borrow_mut ( ) ;
301+ elaborator. clear ( ) ;
302+ elaborator. extend ( trait_predicates) ;
286303 let identity_substs = InternalSubsts :: identity_for_item ( tcx, assoc_item_def_id) ;
287304 let identity_proj = tcx. mk_projection ( assoc_item_def_id, identity_substs) ;
305+
288306 self . collect_outlives_from_predicate_list (
289307 move |ty| ty == identity_proj,
290- traits :: elaborate_predicates ( tcx , trait_predicates ) ,
308+ std :: iter :: from_fn ( move || elaborator . next ( ) ) ,
291309 )
292310 . map ( |b| b. 1 )
293311 }
0 commit comments