@@ -16,10 +16,11 @@ use super::{CombinedSnapshot,
16
16
HigherRankedType ,
17
17
SkolemizationMap } ;
18
18
use super :: combine:: CombineFields ;
19
- use super :: region_inference:: taint:: TaintDirections ;
19
+ use super :: region_inference:: taint:: TaintIterator ;
20
20
21
21
use ty:: { self , TyCtxt , Binder , TypeFoldable } ;
22
22
use ty:: relate:: { Relate , RelateResult , TypeRelation } ;
23
+ use std:: usize;
23
24
use syntax_pos:: Span ;
24
25
use util:: nodemap:: { FxHashMap , FxHashSet } ;
25
26
@@ -108,7 +109,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
108
109
fold_regions_in (
109
110
self . tcx ( ) ,
110
111
& result0,
111
- |r, debruijn| generalize_region ( self . infcx , span, snapshot, debruijn,
112
+ |r, debruijn| generalize_region ( self . infcx , span, snapshot, param_env , debruijn,
112
113
& new_vars, & a_map, r) ) ;
113
114
114
115
debug ! ( "lub({:?},{:?}) = {:?}" ,
@@ -122,6 +123,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
122
123
fn generalize_region < ' a , ' gcx , ' tcx > ( infcx : & InferCtxt < ' a , ' gcx , ' tcx > ,
123
124
span : Span ,
124
125
snapshot : & CombinedSnapshot < ' a , ' tcx > ,
126
+ param_env : ty:: ParamEnv < ' tcx > ,
125
127
debruijn : ty:: DebruijnIndex ,
126
128
new_vars : & [ ty:: RegionVid ] ,
127
129
a_map : & FxHashMap < ty:: BoundRegion , ty:: Region < ' tcx > > ,
@@ -134,33 +136,39 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
134
136
return r0;
135
137
}
136
138
137
- let tainted = infcx . tainted_regions ( snapshot , r0 , TaintDirections :: both ( ) ) ;
139
+ let mut best_index = usize :: MAX ;
138
140
139
- // Variables created during LUB computation which are
140
- // *related* to regions that pre-date the LUB computation
141
- // stay as they are.
142
- if !tainted. iter ( ) . all ( |& r| is_var_in_set ( new_vars, r) ) {
143
- debug ! ( "generalize_region(r0={:?}): \
144
- non-new-variables found in {:?}",
145
- r0, tainted) ;
146
- assert ! ( !r0. is_late_bound( ) ) ;
147
- return r0;
148
- }
149
-
150
- // Otherwise, the variable must be associated with at
151
- // least one of the variables representing bound regions
152
- // in both A and B. Replace the variable with the "first"
153
- // bound region from A that we find it to be associated
154
- // with.
155
- for ( a_br, a_r) in a_map {
156
- if tainted. iter ( ) . any ( |x| x == a_r) {
141
+ for r in infcx. tainted_regions ( snapshot, param_env, r0) {
142
+ // Variables created during LUB computation which are
143
+ // *related* to regions that pre-date the LUB computation
144
+ // stay as they are.
145
+ if !is_var_in_set ( new_vars, r) {
157
146
debug ! ( "generalize_region(r0={:?}): \
158
- replacing with {:?}, tainted={:?}",
159
- r0, * a_br, tainted) ;
160
- return infcx. tcx . mk_region ( ty:: ReLateBound ( debruijn, * a_br) ) ;
147
+ non-new-variable `{:?}` found in taint regions",
148
+ r0, r) ;
149
+ assert ! ( !r0. is_late_bound( ) ) ;
150
+ return r0;
151
+ }
152
+
153
+ // Otherwise, the variable must be associated with at
154
+ // least one of the variables representing bound regions
155
+ // in both A and B. Replace the variable with the "first"
156
+ // bound region from A that we find it to be associated
157
+ // with.
158
+ for ( index, ( _, & a_r) ) in a_map. iter ( ) . enumerate ( ) {
159
+ if r == a_r && index < best_index {
160
+ best_index = index;
161
+ }
161
162
}
162
163
}
163
164
165
+ for ( a_br, a_r) in a_map. iter ( ) . skip ( best_index) {
166
+ debug ! ( "generalize_region(r0={:?}): \
167
+ replacing with {:?}, tainted={:?}",
168
+ r0, * a_br, a_r) ;
169
+ return infcx. tcx . mk_region ( ty:: ReLateBound ( debruijn, * a_br) ) ;
170
+ }
171
+
164
172
span_bug ! (
165
173
span,
166
174
"region {:?} is not associated with any bound region from A!" ,
@@ -206,8 +214,8 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
206
214
fold_regions_in (
207
215
self . tcx ( ) ,
208
216
& result0,
209
- |r, debruijn| generalize_region ( self . infcx , span, snapshot, debruijn ,
210
- & new_vars,
217
+ |r, debruijn| generalize_region ( self . infcx , span, snapshot, param_env ,
218
+ debruijn , & new_vars,
211
219
& a_map, & a_vars, & b_vars,
212
220
r) ) ;
213
221
@@ -222,6 +230,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
222
230
fn generalize_region < ' a , ' gcx , ' tcx > ( infcx : & InferCtxt < ' a , ' gcx , ' tcx > ,
223
231
span : Span ,
224
232
snapshot : & CombinedSnapshot < ' a , ' tcx > ,
233
+ param_env : ty:: ParamEnv < ' tcx > ,
225
234
debruijn : ty:: DebruijnIndex ,
226
235
new_vars : & [ ty:: RegionVid ] ,
227
236
a_map : & FxHashMap < ty:: BoundRegion , ty:: Region < ' tcx > > ,
@@ -234,25 +243,24 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
234
243
return r0;
235
244
}
236
245
237
- let tainted = infcx. tainted_regions ( snapshot, r0, TaintDirections :: both ( ) ) ;
238
-
239
246
let mut a_r = None ;
240
247
let mut b_r = None ;
241
248
let mut only_new_vars = true ;
242
- for r in & tainted {
243
- if is_var_in_set ( a_vars, * r) {
249
+
250
+ for r in infcx. tainted_regions ( snapshot, param_env, r0) {
251
+ if is_var_in_set ( a_vars, r) {
244
252
if a_r. is_some ( ) {
245
253
return fresh_bound_variable ( infcx, debruijn) ;
246
254
} else {
247
- a_r = Some ( * r) ;
255
+ a_r = Some ( r) ;
248
256
}
249
- } else if is_var_in_set ( b_vars, * r) {
257
+ } else if is_var_in_set ( b_vars, r) {
250
258
if b_r. is_some ( ) {
251
259
return fresh_bound_variable ( infcx, debruijn) ;
252
260
} else {
253
- b_r = Some ( * r) ;
261
+ b_r = Some ( r) ;
254
262
}
255
- } else if !is_var_in_set ( new_vars, * r) {
263
+ } else if !is_var_in_set ( new_vars, r) {
256
264
only_new_vars = false ;
257
265
}
258
266
}
@@ -359,12 +367,12 @@ fn fold_regions_in<'a, 'gcx, 'tcx, T, F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
359
367
}
360
368
361
369
impl < ' a , ' gcx , ' tcx > InferCtxt < ' a , ' gcx , ' tcx > {
362
- fn tainted_regions ( & self ,
363
- snapshot : & CombinedSnapshot < ' a , ' tcx > ,
364
- r : ty:: Region < ' tcx > ,
365
- directions : TaintDirections )
366
- -> FxHashSet < ty :: Region < ' tcx > > {
367
- self . region_vars . tainted ( & snapshot. region_vars_snapshot , r , directions )
370
+ fn tainted_regions < ' this > ( & ' this self ,
371
+ snapshot : & CombinedSnapshot < ' a , ' tcx > ,
372
+ param_env : ty:: ParamEnv < ' tcx > ,
373
+ r : ty :: Region < ' tcx > )
374
+ -> TaintIterator < ' this , ' gcx , ' tcx > {
375
+ self . region_vars . tainted ( & snapshot. region_vars_snapshot , param_env , r )
368
376
}
369
377
370
378
fn region_vars_confined_to_snapshot ( & self ,
0 commit comments