@@ -31,8 +31,8 @@ pub(super) fn sub_types<'tcx>(
31
31
) -> Fallible < ( ) > {
32
32
debug ! ( "sub_types(a={:?}, b={:?}, locations={:?})" , a, b, locations) ;
33
33
TypeRelating :: new (
34
- infcx,
35
- NllTypeRelatingDelegate :: new ( borrowck_context, locations, category) ,
34
+ infcx. tcx ,
35
+ NllTypeRelatingDelegate :: new ( infcx , borrowck_context, locations, category) ,
36
36
ty:: Variance :: Covariant ,
37
37
ty:: List :: empty ( ) ,
38
38
) . relate ( & a, & b) ?;
@@ -50,8 +50,8 @@ pub(super) fn eq_types<'tcx>(
50
50
) -> Fallible < ( ) > {
51
51
debug ! ( "eq_types(a={:?}, b={:?}, locations={:?})" , a, b, locations) ;
52
52
TypeRelating :: new (
53
- infcx,
54
- NllTypeRelatingDelegate :: new ( borrowck_context, locations, category) ,
53
+ infcx. tcx ,
54
+ NllTypeRelatingDelegate :: new ( infcx , borrowck_context, locations, category) ,
55
55
ty:: Variance :: Invariant ,
56
56
ty:: List :: empty ( ) ,
57
57
) . relate ( & a, & b) ?;
@@ -85,8 +85,8 @@ pub(super) fn relate_type_and_user_type<'tcx>(
85
85
let v1 = ty:: Contravariant . xform ( v) ;
86
86
87
87
TypeRelating :: new (
88
- infcx,
89
- NllTypeRelatingDelegate :: new ( borrowck_context, locations, category) ,
88
+ infcx. tcx ,
89
+ NllTypeRelatingDelegate :: new ( infcx , borrowck_context, locations, category) ,
90
90
v1,
91
91
b_variables,
92
92
) . relate ( & b_value, & a) ?;
@@ -97,7 +97,7 @@ struct TypeRelating<'me, 'gcx: 'tcx, 'tcx: 'me, D>
97
97
where
98
98
D : TypeRelatingDelegate < ' tcx > ,
99
99
{
100
- infcx : & ' me InferCtxt < ' me , ' gcx , ' tcx > ,
100
+ tcx : TyCtxt < ' me , ' gcx , ' tcx > ,
101
101
102
102
/// Callback to use when we deduce an outlives relationship
103
103
delegate : D ,
@@ -140,10 +140,37 @@ where
140
140
}
141
141
142
142
trait TypeRelatingDelegate < ' tcx > {
143
+ /// Push a constraint `sup: sub` -- this constraint must be
144
+ /// satisfied for the two types to be related. `sub` and `sup` may
145
+ /// be regions from the type or new variables created through the
146
+ /// delegate.
143
147
fn push_outlives ( & mut self , sup : ty:: Region < ' tcx > , sub : ty:: Region < ' tcx > ) ;
148
+
149
+ /// Creates a new region variable representing an instantiated
150
+ /// higher-ranked region; this will be either existential or
151
+ /// universal depending on the context. So e.g. if you have
152
+ /// `for<'a> fn(..) <: for<'b> fn(..)`, then we will first
153
+ /// instantiate `'b` with a universally quantitifed region and
154
+ /// then `'a` with an existentially quantified region (the order
155
+ /// is important so that the existential region `'a` can see the
156
+ /// universal one).
157
+ fn next_region_var (
158
+ & mut self ,
159
+ universally_quantified : UniversallyQuantified ,
160
+ ) -> ty:: Region < ' tcx > ;
161
+
162
+ /// Creates a new existential region in the given universe. This
163
+ /// is used when handling subtyping and type variables -- if we
164
+ /// have that `?X <: Foo<'a>`, for example, we would instantiate
165
+ /// `?X` with a type like `Foo<'?0>` where `'?0` is a fresh
166
+ /// existential variable created by this function. We would then
167
+ /// relate `Foo<'?0>` with `Foo<'a>` (and probably add an outlives
168
+ /// relation stating that `'?0: 'a`).
169
+ fn generalize_existential ( & mut self , universe : ty:: UniverseIndex ) -> ty:: Region < ' tcx > ;
144
170
}
145
171
146
- struct NllTypeRelatingDelegate < ' me , ' bccx : ' me , ' tcx : ' bccx > {
172
+ struct NllTypeRelatingDelegate < ' me , ' bccx : ' me , ' gcx : ' tcx , ' tcx : ' bccx > {
173
+ infcx : & ' me InferCtxt < ' me , ' gcx , ' tcx > ,
147
174
borrowck_context : Option < & ' me mut BorrowCheckContext < ' bccx , ' tcx > > ,
148
175
149
176
/// Where (and why) is this relation taking place?
@@ -153,21 +180,40 @@ struct NllTypeRelatingDelegate<'me, 'bccx: 'me, 'tcx: 'bccx> {
153
180
category : ConstraintCategory ,
154
181
}
155
182
156
- impl NllTypeRelatingDelegate < ' me , ' bccx , ' tcx > {
183
+ impl NllTypeRelatingDelegate < ' me , ' bccx , ' gcx , ' tcx > {
157
184
fn new (
185
+ infcx : & ' me InferCtxt < ' me , ' gcx , ' tcx > ,
158
186
borrowck_context : Option < & ' me mut BorrowCheckContext < ' bccx , ' tcx > > ,
159
187
locations : Locations ,
160
188
category : ConstraintCategory ,
161
189
) -> Self {
162
190
Self {
191
+ infcx,
163
192
borrowck_context,
164
193
locations,
165
194
category,
166
195
}
167
196
}
168
197
}
169
198
170
- impl TypeRelatingDelegate < ' tcx > for NllTypeRelatingDelegate < ' _ , ' _ , ' tcx > {
199
+ impl TypeRelatingDelegate < ' tcx > for NllTypeRelatingDelegate < ' _ , ' _ , ' _ , ' tcx > {
200
+ fn next_region_var (
201
+ & mut self ,
202
+ universally_quantified : UniversallyQuantified ,
203
+ ) -> ty:: Region < ' tcx > {
204
+ let origin = if universally_quantified. 0 {
205
+ NLLRegionVariableOrigin :: BoundRegion ( self . infcx . create_subuniverse ( ) )
206
+ } else {
207
+ NLLRegionVariableOrigin :: Existential
208
+ } ;
209
+ self . infcx . next_nll_region_var ( origin)
210
+ }
211
+
212
+ fn generalize_existential ( & mut self , universe : ty:: UniverseIndex ) -> ty:: Region < ' tcx > {
213
+ self . infcx
214
+ . next_nll_region_var_in_universe ( NLLRegionVariableOrigin :: Existential , universe)
215
+ }
216
+
171
217
fn push_outlives ( & mut self , sup : ty:: Region < ' tcx > , sub : ty:: Region < ' tcx > ) {
172
218
if let Some ( borrowck_context) = & mut self . borrowck_context {
173
219
let sub = borrowck_context. universal_regions . to_region_vid ( sub) ;
@@ -206,14 +252,14 @@ where
206
252
D : TypeRelatingDelegate < ' tcx > ,
207
253
{
208
254
fn new (
209
- infcx : & ' me InferCtxt < ' me , ' gcx , ' tcx > ,
255
+ tcx : TyCtxt < ' me , ' gcx , ' tcx > ,
210
256
delegate : D ,
211
257
ambient_variance : ty:: Variance ,
212
258
canonical_var_infos : CanonicalVarInfos < ' tcx > ,
213
259
) -> Self {
214
260
let canonical_var_values = IndexVec :: from_elem_n ( None , canonical_var_infos. len ( ) ) ;
215
261
Self {
216
- infcx ,
262
+ tcx ,
217
263
delegate,
218
264
ambient_variance,
219
265
canonical_var_values,
@@ -243,7 +289,7 @@ where
243
289
) -> BoundRegionScope < ' tcx > {
244
290
let mut scope = BoundRegionScope :: default ( ) ;
245
291
value. skip_binder ( ) . visit_with ( & mut ScopeInstantiator {
246
- infcx : self . infcx ,
292
+ delegate : & mut self . delegate ,
247
293
target_index : ty:: INNERMOST ,
248
294
universally_quantified,
249
295
bound_region_scope : & mut scope,
@@ -335,9 +381,10 @@ where
335
381
return result;
336
382
}
337
383
338
- fn generalize_value ( & self , kind : Kind < ' tcx > ) -> Kind < ' tcx > {
384
+ fn generalize_value ( & mut self , kind : Kind < ' tcx > ) -> Kind < ' tcx > {
339
385
TypeGeneralizer {
340
- type_rel : self ,
386
+ tcx : self . tcx ,
387
+ delegate : & mut self . delegate ,
341
388
first_free_index : ty:: INNERMOST ,
342
389
ambient_variance : self . ambient_variance ,
343
390
@@ -354,7 +401,7 @@ where
354
401
D : TypeRelatingDelegate < ' tcx > ,
355
402
{
356
403
fn tcx ( & self ) -> TyCtxt < ' me , ' gcx , ' tcx > {
357
- self . infcx . tcx
404
+ self . tcx
358
405
}
359
406
360
407
fn tag ( & self ) -> & ' static str {
@@ -559,15 +606,21 @@ where
559
606
/// binder depth, and finds late-bound regions targeting the
560
607
/// `for<..`>. For each of those, it creates an entry in
561
608
/// `bound_region_scope`.
562
- struct ScopeInstantiator < ' me , ' gcx : ' tcx , ' tcx : ' me > {
563
- infcx : & ' me InferCtxt < ' me , ' gcx , ' tcx > ,
609
+ struct ScopeInstantiator < ' me , ' tcx : ' me , D >
610
+ where
611
+ D : TypeRelatingDelegate < ' tcx > + ' me ,
612
+ {
613
+ delegate : & ' me mut D ,
564
614
// The debruijn index of the scope we are instantiating.
565
615
target_index : ty:: DebruijnIndex ,
566
616
universally_quantified : UniversallyQuantified ,
567
617
bound_region_scope : & ' me mut BoundRegionScope < ' tcx > ,
568
618
}
569
619
570
- impl < ' me , ' gcx , ' tcx > TypeVisitor < ' tcx > for ScopeInstantiator < ' me , ' gcx , ' tcx > {
620
+ impl < ' me , ' tcx , D > TypeVisitor < ' tcx > for ScopeInstantiator < ' me , ' tcx , D >
621
+ where
622
+ D : TypeRelatingDelegate < ' tcx > ,
623
+ {
571
624
fn visit_binder < T : TypeFoldable < ' tcx > > ( & mut self , t : & ty:: Binder < T > ) -> bool {
572
625
self . target_index . shift_in ( 1 ) ;
573
626
t. super_visit_with ( self ) ;
@@ -578,21 +631,18 @@ impl<'me, 'gcx, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'gcx, 'tcx> {
578
631
579
632
fn visit_region ( & mut self , r : ty:: Region < ' tcx > ) -> bool {
580
633
let ScopeInstantiator {
581
- infcx,
582
634
universally_quantified,
635
+ bound_region_scope,
636
+ delegate,
583
637
..
584
- } = * self ;
638
+ } = self ;
585
639
586
640
match r {
587
641
ty:: ReLateBound ( debruijn, br) if * debruijn == self . target_index => {
588
- self . bound_region_scope . map . entry ( * br) . or_insert_with ( || {
589
- let origin = if universally_quantified. 0 {
590
- NLLRegionVariableOrigin :: BoundRegion ( infcx. create_subuniverse ( ) )
591
- } else {
592
- NLLRegionVariableOrigin :: Existential
593
- } ;
594
- infcx. next_nll_region_var ( origin)
595
- } ) ;
642
+ bound_region_scope
643
+ . map
644
+ . entry ( * br)
645
+ . or_insert_with ( || delegate. next_region_var ( * universally_quantified) ) ;
596
646
}
597
647
598
648
_ => { }
@@ -625,7 +675,9 @@ struct TypeGeneralizer<'me, 'gcx: 'tcx, 'tcx: 'me, D>
625
675
where
626
676
D : TypeRelatingDelegate < ' tcx > + ' me ,
627
677
{
628
- type_rel : & ' me TypeRelating < ' me , ' gcx , ' tcx , D > ,
678
+ tcx : TyCtxt < ' me , ' gcx , ' tcx > ,
679
+
680
+ delegate : & ' me mut D ,
629
681
630
682
/// After we generalize this type, we are going to relative it to
631
683
/// some other type. What will be the variance at this point?
@@ -641,7 +693,7 @@ where
641
693
D : TypeRelatingDelegate < ' tcx > ,
642
694
{
643
695
fn tcx ( & self ) -> TyCtxt < ' me , ' gcx , ' tcx > {
644
- self . type_rel . infcx . tcx
696
+ self . tcx
645
697
}
646
698
647
699
fn tag ( & self ) -> & ' static str {
@@ -724,9 +776,7 @@ where
724
776
// though, we may however need to check well-formedness or
725
777
// risk a problem like #41677 again.
726
778
727
- let replacement_region_vid = self . type_rel
728
- . infcx
729
- . next_nll_region_var_in_universe ( NLLRegionVariableOrigin :: Existential , self . universe ) ;
779
+ let replacement_region_vid = self . delegate . generalize_existential ( self . universe ) ;
730
780
731
781
Ok ( replacement_region_vid)
732
782
}
0 commit comments