1
+ use std:: cell:: RefCell ;
2
+
1
3
use crate :: infer:: outlives:: env:: RegionBoundPairs ;
2
4
use crate :: infer:: { GenericKind , VerifyBound } ;
3
5
use crate :: traits;
@@ -17,6 +19,7 @@ pub struct VerifyBoundCx<'cx, 'tcx> {
17
19
region_bound_pairs : & ' cx RegionBoundPairs < ' tcx > ,
18
20
implicit_region_bound : Option < ty:: Region < ' tcx > > ,
19
21
param_env : ty:: ParamEnv < ' tcx > ,
22
+ elaborator : RefCell < traits:: Elaborator < ' tcx > > ,
20
23
}
21
24
22
25
impl < ' cx , ' tcx > VerifyBoundCx < ' cx , ' tcx > {
@@ -26,7 +29,13 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
26
29
implicit_region_bound : Option < ty:: Region < ' tcx > > ,
27
30
param_env : ty:: ParamEnv < ' tcx > ,
28
31
) -> 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
+ }
30
39
}
31
40
32
41
/// Returns a "verify bound" that encodes what we know about
@@ -113,10 +122,10 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
113
122
self . tcx . mk_projection ( projection_ty. item_def_id , projection_ty. substs ) ;
114
123
115
124
// 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) | {
120
129
let vb = VerifyBound :: OutlivedBy ( r) ;
121
130
if ty == projection_ty_as_ty {
122
131
// Micro-optimize if this is an exact match (this
@@ -126,18 +135,20 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
126
135
} else {
127
136
VerifyBound :: IfEq ( ty, Box :: new ( vb) )
128
137
}
129
- } ) ;
138
+ } ,
139
+ ) ) ;
130
140
131
141
// 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
+ ) ;
135
146
136
147
// see the extensive comment in projection_must_outlive
137
148
let ty = self . tcx . mk_projection ( projection_ty. item_def_id , projection_ty. substs ) ;
138
149
let recursive_bound = self . recursive_type_bound ( ty) ;
139
150
140
- VerifyBound :: AnyBound ( env_bounds . chain ( trait_bounds ) . collect ( ) ) . or ( recursive_bound)
151
+ VerifyBound :: AnyBound ( bounds ) . or ( recursive_bound)
141
152
}
142
153
143
154
fn recursive_type_bound ( & self , ty : Ty < ' tcx > ) -> VerifyBound < ' tcx > {
@@ -154,7 +165,11 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
154
165
. filter ( |b| !b. must_hold ( ) )
155
166
. collect :: < Vec < _ > > ( ) ;
156
167
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
+ }
158
173
}
159
174
160
175
/// Searches the environment for where-clauses like `G: 'a` where
@@ -281,13 +296,16 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
281
296
let tcx = self . tcx ;
282
297
let assoc_item = tcx. associated_item ( assoc_item_def_id) ;
283
298
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) ;
286
303
let identity_substs = InternalSubsts :: identity_for_item ( tcx, assoc_item_def_id) ;
287
304
let identity_proj = tcx. mk_projection ( assoc_item_def_id, identity_substs) ;
305
+
288
306
self . collect_outlives_from_predicate_list (
289
307
move |ty| ty == identity_proj,
290
- traits :: elaborate_predicates ( tcx , trait_predicates ) ,
308
+ std :: iter :: from_fn ( move || elaborator . next ( ) ) ,
291
309
)
292
310
. map ( |b| b. 1 )
293
311
}
0 commit comments