Skip to content

Commit 582a369

Browse files
committed
encapsulate infcx too into the delegate
1 parent c6f4513 commit 582a369

File tree

1 file changed

+84
-34
lines changed

1 file changed

+84
-34
lines changed

src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs

Lines changed: 84 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ pub(super) fn sub_types<'tcx>(
3131
) -> Fallible<()> {
3232
debug!("sub_types(a={:?}, b={:?}, locations={:?})", a, b, locations);
3333
TypeRelating::new(
34-
infcx,
35-
NllTypeRelatingDelegate::new(borrowck_context, locations, category),
34+
infcx.tcx,
35+
NllTypeRelatingDelegate::new(infcx, borrowck_context, locations, category),
3636
ty::Variance::Covariant,
3737
ty::List::empty(),
3838
).relate(&a, &b)?;
@@ -50,8 +50,8 @@ pub(super) fn eq_types<'tcx>(
5050
) -> Fallible<()> {
5151
debug!("eq_types(a={:?}, b={:?}, locations={:?})", a, b, locations);
5252
TypeRelating::new(
53-
infcx,
54-
NllTypeRelatingDelegate::new(borrowck_context, locations, category),
53+
infcx.tcx,
54+
NllTypeRelatingDelegate::new(infcx, borrowck_context, locations, category),
5555
ty::Variance::Invariant,
5656
ty::List::empty(),
5757
).relate(&a, &b)?;
@@ -85,8 +85,8 @@ pub(super) fn relate_type_and_user_type<'tcx>(
8585
let v1 = ty::Contravariant.xform(v);
8686

8787
TypeRelating::new(
88-
infcx,
89-
NllTypeRelatingDelegate::new(borrowck_context, locations, category),
88+
infcx.tcx,
89+
NllTypeRelatingDelegate::new(infcx, borrowck_context, locations, category),
9090
v1,
9191
b_variables,
9292
).relate(&b_value, &a)?;
@@ -97,7 +97,7 @@ struct TypeRelating<'me, 'gcx: 'tcx, 'tcx: 'me, D>
9797
where
9898
D: TypeRelatingDelegate<'tcx>,
9999
{
100-
infcx: &'me InferCtxt<'me, 'gcx, 'tcx>,
100+
tcx: TyCtxt<'me, 'gcx, 'tcx>,
101101

102102
/// Callback to use when we deduce an outlives relationship
103103
delegate: D,
@@ -140,10 +140,37 @@ where
140140
}
141141

142142
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.
143147
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>;
144170
}
145171

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>,
147174
borrowck_context: Option<&'me mut BorrowCheckContext<'bccx, 'tcx>>,
148175

149176
/// Where (and why) is this relation taking place?
@@ -153,21 +180,40 @@ struct NllTypeRelatingDelegate<'me, 'bccx: 'me, 'tcx: 'bccx> {
153180
category: ConstraintCategory,
154181
}
155182

156-
impl NllTypeRelatingDelegate<'me, 'bccx, 'tcx> {
183+
impl NllTypeRelatingDelegate<'me, 'bccx, 'gcx, 'tcx> {
157184
fn new(
185+
infcx: &'me InferCtxt<'me, 'gcx, 'tcx>,
158186
borrowck_context: Option<&'me mut BorrowCheckContext<'bccx, 'tcx>>,
159187
locations: Locations,
160188
category: ConstraintCategory,
161189
) -> Self {
162190
Self {
191+
infcx,
163192
borrowck_context,
164193
locations,
165194
category,
166195
}
167196
}
168197
}
169198

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+
171217
fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>) {
172218
if let Some(borrowck_context) = &mut self.borrowck_context {
173219
let sub = borrowck_context.universal_regions.to_region_vid(sub);
@@ -206,14 +252,14 @@ where
206252
D: TypeRelatingDelegate<'tcx>,
207253
{
208254
fn new(
209-
infcx: &'me InferCtxt<'me, 'gcx, 'tcx>,
255+
tcx: TyCtxt<'me, 'gcx, 'tcx>,
210256
delegate: D,
211257
ambient_variance: ty::Variance,
212258
canonical_var_infos: CanonicalVarInfos<'tcx>,
213259
) -> Self {
214260
let canonical_var_values = IndexVec::from_elem_n(None, canonical_var_infos.len());
215261
Self {
216-
infcx,
262+
tcx,
217263
delegate,
218264
ambient_variance,
219265
canonical_var_values,
@@ -243,7 +289,7 @@ where
243289
) -> BoundRegionScope<'tcx> {
244290
let mut scope = BoundRegionScope::default();
245291
value.skip_binder().visit_with(&mut ScopeInstantiator {
246-
infcx: self.infcx,
292+
delegate: &mut self.delegate,
247293
target_index: ty::INNERMOST,
248294
universally_quantified,
249295
bound_region_scope: &mut scope,
@@ -335,9 +381,10 @@ where
335381
return result;
336382
}
337383

338-
fn generalize_value(&self, kind: Kind<'tcx>) -> Kind<'tcx> {
384+
fn generalize_value(&mut self, kind: Kind<'tcx>) -> Kind<'tcx> {
339385
TypeGeneralizer {
340-
type_rel: self,
386+
tcx: self.tcx,
387+
delegate: &mut self.delegate,
341388
first_free_index: ty::INNERMOST,
342389
ambient_variance: self.ambient_variance,
343390

@@ -354,7 +401,7 @@ where
354401
D: TypeRelatingDelegate<'tcx>,
355402
{
356403
fn tcx(&self) -> TyCtxt<'me, 'gcx, 'tcx> {
357-
self.infcx.tcx
404+
self.tcx
358405
}
359406

360407
fn tag(&self) -> &'static str {
@@ -559,15 +606,21 @@ where
559606
/// binder depth, and finds late-bound regions targeting the
560607
/// `for<..`>. For each of those, it creates an entry in
561608
/// `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,
564614
// The debruijn index of the scope we are instantiating.
565615
target_index: ty::DebruijnIndex,
566616
universally_quantified: UniversallyQuantified,
567617
bound_region_scope: &'me mut BoundRegionScope<'tcx>,
568618
}
569619

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+
{
571624
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> bool {
572625
self.target_index.shift_in(1);
573626
t.super_visit_with(self);
@@ -578,21 +631,18 @@ impl<'me, 'gcx, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'gcx, 'tcx> {
578631

579632
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
580633
let ScopeInstantiator {
581-
infcx,
582634
universally_quantified,
635+
bound_region_scope,
636+
delegate,
583637
..
584-
} = *self;
638+
} = self;
585639

586640
match r {
587641
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));
596646
}
597647

598648
_ => {}
@@ -625,7 +675,9 @@ struct TypeGeneralizer<'me, 'gcx: 'tcx, 'tcx: 'me, D>
625675
where
626676
D: TypeRelatingDelegate<'tcx> + 'me,
627677
{
628-
type_rel: &'me TypeRelating<'me, 'gcx, 'tcx, D>,
678+
tcx: TyCtxt<'me, 'gcx, 'tcx>,
679+
680+
delegate: &'me mut D,
629681

630682
/// After we generalize this type, we are going to relative it to
631683
/// some other type. What will be the variance at this point?
@@ -641,7 +693,7 @@ where
641693
D: TypeRelatingDelegate<'tcx>,
642694
{
643695
fn tcx(&self) -> TyCtxt<'me, 'gcx, 'tcx> {
644-
self.type_rel.infcx.tcx
696+
self.tcx
645697
}
646698

647699
fn tag(&self) -> &'static str {
@@ -724,9 +776,7 @@ where
724776
// though, we may however need to check well-formedness or
725777
// risk a problem like #41677 again.
726778

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);
730780

731781
Ok(replacement_region_vid)
732782
}

0 commit comments

Comments
 (0)