@@ -28,6 +28,7 @@ use crate::traits::{Obligation, PredicateObligations};
28
28
use rustc_data_structures:: fx:: FxHashMap ;
29
29
use rustc_middle:: traits:: ObligationCause ;
30
30
use rustc_middle:: ty:: error:: TypeError ;
31
+ use rustc_middle:: ty:: fold:: FnMutDelegate ;
31
32
use rustc_middle:: ty:: relate:: { self , Relate , RelateResult , TypeRelation } ;
32
33
use rustc_middle:: ty:: visit:: { TypeSuperVisitable , TypeVisitable , TypeVisitableExt , TypeVisitor } ;
33
34
use rustc_middle:: ty:: { self , InferConst , Ty , TyCtxt } ;
55
56
ambient_variance : ty:: Variance ,
56
57
57
58
ambient_variance_info : ty:: VarianceDiagInfo < ' tcx > ,
58
-
59
- /// When we pass through a set of binders (e.g., when looking into
60
- /// a `fn` type), we push a new bound region scope onto here. This
61
- /// will contain the instantiated region for each region in those
62
- /// binders. When we then encounter a `ReLateBound(d, br)`, we can
63
- /// use the De Bruijn index `d` to find the right scope, and then
64
- /// bound region name `br` to find the specific instantiation from
65
- /// within that scope. See `replace_bound_region`.
66
- ///
67
- /// This field stores the instantiations for late-bound regions in
68
- /// the `a` type.
69
- a_scopes : Vec < BoundRegionScope < ' tcx > > ,
70
-
71
- /// Same as `a_scopes`, but for the `b` type.
72
- b_scopes : Vec < BoundRegionScope < ' tcx > > ,
73
59
}
74
60
75
61
pub trait TypeRelatingDelegate < ' tcx > {
@@ -147,8 +133,6 @@ where
147
133
delegate,
148
134
ambient_variance,
149
135
ambient_variance_info : ty:: VarianceDiagInfo :: default ( ) ,
150
- a_scopes : vec ! [ ] ,
151
- b_scopes : vec ! [ ] ,
152
136
}
153
137
}
154
138
@@ -166,88 +150,6 @@ where
166
150
}
167
151
}
168
152
169
- fn create_scope (
170
- & mut self ,
171
- value : ty:: Binder < ' tcx , impl Relate < ' tcx > > ,
172
- universally_quantified : UniversallyQuantified ,
173
- ) -> BoundRegionScope < ' tcx > {
174
- let mut scope = BoundRegionScope :: default ( ) ;
175
-
176
- // Create a callback that creates (via the delegate) either an
177
- // existential or placeholder region as needed.
178
- let mut next_region = {
179
- let delegate = & mut self . delegate ;
180
- let mut lazy_universe = None ;
181
- move |br : ty:: BoundRegion | {
182
- if universally_quantified. 0 {
183
- // The first time this closure is called, create a
184
- // new universe for the placeholders we will make
185
- // from here out.
186
- let universe = lazy_universe. unwrap_or_else ( || {
187
- let universe = delegate. create_next_universe ( ) ;
188
- lazy_universe = Some ( universe) ;
189
- universe
190
- } ) ;
191
-
192
- let placeholder = ty:: PlaceholderRegion { universe, name : br. kind } ;
193
- delegate. next_placeholder_region ( placeholder)
194
- } else {
195
- delegate. next_existential_region_var ( true , br. kind . get_name ( ) )
196
- }
197
- }
198
- } ;
199
-
200
- value. skip_binder ( ) . visit_with ( & mut ScopeInstantiator {
201
- next_region : & mut next_region,
202
- target_index : ty:: INNERMOST ,
203
- bound_region_scope : & mut scope,
204
- } ) ;
205
-
206
- scope
207
- }
208
-
209
- /// When we encounter binders during the type traversal, we record
210
- /// the value to substitute for each of the things contained in
211
- /// that binder. (This will be either a universal placeholder or
212
- /// an existential inference variable.) Given the De Bruijn index
213
- /// `debruijn` (and name `br`) of some binder we have now
214
- /// encountered, this routine finds the value that we instantiated
215
- /// the region with; to do so, it indexes backwards into the list
216
- /// of ambient scopes `scopes`.
217
- fn lookup_bound_region (
218
- debruijn : ty:: DebruijnIndex ,
219
- br : & ty:: BoundRegion ,
220
- first_free_index : ty:: DebruijnIndex ,
221
- scopes : & [ BoundRegionScope < ' tcx > ] ,
222
- ) -> ty:: Region < ' tcx > {
223
- // The debruijn index is a "reverse index" into the
224
- // scopes listing. So when we have INNERMOST (0), we
225
- // want the *last* scope pushed, and so forth.
226
- let debruijn_index = debruijn. index ( ) - first_free_index. index ( ) ;
227
- let scope = & scopes[ scopes. len ( ) - debruijn_index - 1 ] ;
228
-
229
- // Find this bound region in that scope to map to a
230
- // particular region.
231
- scope. map [ br]
232
- }
233
-
234
- /// If `r` is a bound region, find the scope in which it is bound
235
- /// (from `scopes`) and return the value that we instantiated it
236
- /// with. Otherwise just return `r`.
237
- fn replace_bound_region (
238
- & self ,
239
- r : ty:: Region < ' tcx > ,
240
- first_free_index : ty:: DebruijnIndex ,
241
- scopes : & [ BoundRegionScope < ' tcx > ] ,
242
- ) -> ty:: Region < ' tcx > {
243
- debug ! ( "replace_bound_regions(scopes={:?})" , scopes) ;
244
- if let ty:: ReLateBound ( debruijn, br) = * r {
245
- Self :: lookup_bound_region ( debruijn, & br, first_free_index, scopes)
246
- } else {
247
- r
248
- }
249
- }
250
-
251
153
/// Push a new outlives requirement into our output set of
252
154
/// constraints.
253
155
fn push_outlives (
@@ -314,18 +216,9 @@ where
314
216
315
217
self . infcx . inner . borrow_mut ( ) . type_variables ( ) . instantiate ( vid, generalized_ty) ;
316
218
317
- // The generalized values we extract from `canonical_var_values` have
318
- // been fully instantiated and hence the set of scopes we have
319
- // doesn't matter -- just to be sure, put an empty vector
320
- // in there.
321
- let old_a_scopes = std:: mem:: take ( pair. vid_scopes ( self ) ) ;
322
-
323
219
// Relate the generalized kind to the original one.
324
220
let result = pair. relate_generalized_ty ( self , generalized_ty) ;
325
221
326
- // Restore the old scopes now.
327
- * pair. vid_scopes ( self ) = old_a_scopes;
328
-
329
222
debug ! ( "relate_ty_var: complete, result = {:?}" , result) ;
330
223
result
331
224
}
@@ -379,6 +272,97 @@ where
379
272
trace ! ( a = ?a. kind( ) , b = ?b. kind( ) , "opaque type instantiated" ) ;
380
273
Ok ( a)
381
274
}
275
+
276
+ #[ instrument( skip( self ) , level = "debug" ) ]
277
+ fn instantiate_binder_with_placeholders < T > ( & mut self , binder : ty:: Binder < ' tcx , T > ) -> T
278
+ where
279
+ T : ty:: TypeFoldable < TyCtxt < ' tcx > > + Copy ,
280
+ {
281
+ if let Some ( inner) = binder. no_bound_vars ( ) {
282
+ return inner;
283
+ }
284
+
285
+ let mut next_region = {
286
+ let nll_delegate = & mut self . delegate ;
287
+ let mut lazy_universe = None ;
288
+
289
+ move |br : ty:: BoundRegion | {
290
+ // The first time this closure is called, create a
291
+ // new universe for the placeholders we will make
292
+ // from here out.
293
+ let universe = lazy_universe. unwrap_or_else ( || {
294
+ let universe = nll_delegate. create_next_universe ( ) ;
295
+ lazy_universe = Some ( universe) ;
296
+ universe
297
+ } ) ;
298
+
299
+ let placeholder = ty:: PlaceholderRegion { universe, name : br. kind } ;
300
+ debug ! ( ?placeholder) ;
301
+ let placeholder_reg = nll_delegate. next_placeholder_region ( placeholder) ;
302
+ debug ! ( ?placeholder_reg) ;
303
+
304
+ placeholder_reg
305
+ }
306
+ } ;
307
+
308
+ let delegate = FnMutDelegate {
309
+ regions : & mut next_region,
310
+ types : & mut |_bound_ty : ty:: BoundTy | {
311
+ unreachable ! ( "we only replace regions in nll_relate, not types" )
312
+ } ,
313
+ consts : & mut |_bound_var : ty:: BoundVar , _ty| {
314
+ unreachable ! ( "we only replace regions in nll_relate, not consts" )
315
+ } ,
316
+ } ;
317
+
318
+ let replaced = self . infcx . tcx . replace_bound_vars_uncached ( binder, delegate) ;
319
+ debug ! ( ?replaced) ;
320
+
321
+ replaced
322
+ }
323
+
324
+ #[ instrument( skip( self ) , level = "debug" ) ]
325
+ fn instantiate_binder_with_existentials < T > ( & mut self , binder : ty:: Binder < ' tcx , T > ) -> T
326
+ where
327
+ T : ty:: TypeFoldable < TyCtxt < ' tcx > > + Copy ,
328
+ {
329
+ if let Some ( inner) = binder. no_bound_vars ( ) {
330
+ return inner;
331
+ }
332
+
333
+ let mut next_region = {
334
+ let nll_delegate = & mut self . delegate ;
335
+ let mut reg_map = FxHashMap :: default ( ) ;
336
+
337
+ move |br : ty:: BoundRegion | {
338
+ if let Some ( ex_reg_var) = reg_map. get ( & br) {
339
+ return * ex_reg_var;
340
+ } else {
341
+ let ex_reg_var =
342
+ nll_delegate. next_existential_region_var ( true , br. kind . get_name ( ) ) ;
343
+ debug ! ( ?ex_reg_var) ;
344
+ reg_map. insert ( br, ex_reg_var) ;
345
+
346
+ ex_reg_var
347
+ }
348
+ }
349
+ } ;
350
+
351
+ let delegate = FnMutDelegate {
352
+ regions : & mut next_region,
353
+ types : & mut |_bound_ty : ty:: BoundTy | {
354
+ unreachable ! ( "we only replace regions in nll_relate, not types" )
355
+ } ,
356
+ consts : & mut |_bound_var : ty:: BoundVar , _ty| {
357
+ unreachable ! ( "we only replace regions in nll_relate, not consts" )
358
+ } ,
359
+ } ;
360
+
361
+ let replaced = self . infcx . tcx . replace_bound_vars_uncached ( binder, delegate) ;
362
+ debug ! ( ?replaced) ;
363
+
364
+ replaced
365
+ }
382
366
}
383
367
384
368
/// When we instantiate an inference variable with a value in
@@ -396,14 +380,6 @@ trait VidValuePair<'tcx>: Debug {
396
380
/// opposite part of the tuple from the vid).
397
381
fn value_ty ( & self ) -> Ty < ' tcx > ;
398
382
399
- /// Extract the scopes that apply to whichever side of the tuple
400
- /// the vid was found on. See the comment where this is called
401
- /// for more details on why we want them.
402
- fn vid_scopes < ' r , D : TypeRelatingDelegate < ' tcx > > (
403
- & self ,
404
- relate : & ' r mut TypeRelating < ' _ , ' tcx , D > ,
405
- ) -> & ' r mut Vec < BoundRegionScope < ' tcx > > ;
406
-
407
383
/// Given a generalized type G that should replace the vid, relate
408
384
/// G to the value, putting G on whichever side the vid would have
409
385
/// appeared.
@@ -425,16 +401,6 @@ impl<'tcx> VidValuePair<'tcx> for (ty::TyVid, Ty<'tcx>) {
425
401
self . 1
426
402
}
427
403
428
- fn vid_scopes < ' r , D > (
429
- & self ,
430
- relate : & ' r mut TypeRelating < ' _ , ' tcx , D > ,
431
- ) -> & ' r mut Vec < BoundRegionScope < ' tcx > >
432
- where
433
- D : TypeRelatingDelegate < ' tcx > ,
434
- {
435
- & mut relate. a_scopes
436
- }
437
-
438
404
fn relate_generalized_ty < D > (
439
405
& self ,
440
406
relate : & mut TypeRelating < ' _ , ' tcx , D > ,
@@ -457,16 +423,6 @@ impl<'tcx> VidValuePair<'tcx> for (Ty<'tcx>, ty::TyVid) {
457
423
self . 0
458
424
}
459
425
460
- fn vid_scopes < ' r , D > (
461
- & self ,
462
- relate : & ' r mut TypeRelating < ' _ , ' tcx , D > ,
463
- ) -> & ' r mut Vec < BoundRegionScope < ' tcx > >
464
- where
465
- D : TypeRelatingDelegate < ' tcx > ,
466
- {
467
- & mut relate. b_scopes
468
- }
469
-
470
426
fn relate_generalized_ty < D > (
471
427
& self ,
472
428
relate : & mut TypeRelating < ' _ , ' tcx , D > ,
@@ -602,20 +558,14 @@ where
602
558
) -> RelateResult < ' tcx , ty:: Region < ' tcx > > {
603
559
debug ! ( ?self . ambient_variance) ;
604
560
605
- let v_a = self . replace_bound_region ( a, ty:: INNERMOST , & self . a_scopes ) ;
606
- let v_b = self . replace_bound_region ( b, ty:: INNERMOST , & self . b_scopes ) ;
607
-
608
- debug ! ( ?v_a) ;
609
- debug ! ( ?v_b) ;
610
-
611
561
if self . ambient_covariance ( ) {
612
562
// Covariant: &'a u8 <: &'b u8. Hence, `'a: 'b`.
613
- self . push_outlives ( v_a , v_b , self . ambient_variance_info ) ;
563
+ self . push_outlives ( a , b , self . ambient_variance_info ) ;
614
564
}
615
565
616
566
if self . ambient_contravariance ( ) {
617
567
// Contravariant: &'b u8 <: &'a u8. Hence, `'b: 'a`.
618
- self . push_outlives ( v_b , v_a , self . ambient_variance_info ) ;
568
+ self . push_outlives ( b , a , self . ambient_variance_info ) ;
619
569
}
620
570
621
571
Ok ( a)
@@ -689,15 +639,6 @@ where
689
639
// instantiation of B (i.e., B instantiated with
690
640
// universals).
691
641
692
- let b_scope = self . create_scope ( b, UniversallyQuantified ( true ) ) ;
693
- let a_scope = self . create_scope ( a, UniversallyQuantified ( false ) ) ;
694
-
695
- debug ! ( ?a_scope, "(existential)" ) ;
696
- debug ! ( ?b_scope, "(universal)" ) ;
697
-
698
- self . b_scopes . push ( b_scope) ;
699
- self . a_scopes . push ( a_scope) ;
700
-
701
642
// Reset the ambient variance to covariant. This is needed
702
643
// to correctly handle cases like
703
644
//
@@ -718,12 +659,14 @@ where
718
659
// subtyping (i.e., `&'b u32 <: &{P} u32`).
719
660
let variance = std:: mem:: replace ( & mut self . ambient_variance , ty:: Variance :: Covariant ) ;
720
661
721
- self . relate ( a. skip_binder ( ) , b. skip_binder ( ) ) ?;
662
+ // Note: the order here is important. Create the placeholders first, otherwise
663
+ // we assign the wrong universe to the existential!
664
+ let b_replaced = self . instantiate_binder_with_placeholders ( b) ;
665
+ let a_replaced = self . instantiate_binder_with_existentials ( a) ;
722
666
723
- self . ambient_variance = variance ;
667
+ self . relate ( a_replaced , b_replaced ) ? ;
724
668
725
- self . b_scopes . pop ( ) . unwrap ( ) ;
726
- self . a_scopes . pop ( ) . unwrap ( ) ;
669
+ self . ambient_variance = variance;
727
670
}
728
671
729
672
if self . ambient_contravariance ( ) {
@@ -733,26 +676,17 @@ where
733
676
// instantiation of B (i.e., B instantiated with
734
677
// existentials). Opposite of above.
735
678
736
- let a_scope = self . create_scope ( a, UniversallyQuantified ( true ) ) ;
737
- let b_scope = self . create_scope ( b, UniversallyQuantified ( false ) ) ;
738
-
739
- debug ! ( ?a_scope, "(universal)" ) ;
740
- debug ! ( ?b_scope, "(existential)" ) ;
741
-
742
- self . a_scopes . push ( a_scope) ;
743
- self . b_scopes . push ( b_scope) ;
744
-
745
679
// Reset ambient variance to contravariance. See the
746
680
// covariant case above for an explanation.
747
681
let variance =
748
682
std:: mem:: replace ( & mut self . ambient_variance , ty:: Variance :: Contravariant ) ;
749
683
750
- self . relate ( a. skip_binder ( ) , b. skip_binder ( ) ) ?;
684
+ let a_replaced = self . instantiate_binder_with_placeholders ( a) ;
685
+ let b_replaced = self . instantiate_binder_with_existentials ( b) ;
751
686
752
- self . ambient_variance = variance ;
687
+ self . relate ( a_replaced , b_replaced ) ? ;
753
688
754
- self . b_scopes . pop ( ) . unwrap ( ) ;
755
- self . a_scopes . pop ( ) . unwrap ( ) ;
689
+ self . ambient_variance = variance;
756
690
}
757
691
758
692
Ok ( a)
0 commit comments