introduce enter_forall
This commit is contained in:
parent
af88f7db51
commit
ac559af98f
15 changed files with 524 additions and 446 deletions
|
@ -1032,10 +1032,10 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
_ => {}
|
||||
}
|
||||
|
||||
let ty::SubtypePredicate { a_is_expected, a, b } =
|
||||
self.instantiate_binder_with_placeholders(predicate);
|
||||
|
||||
Ok(self.at(cause, param_env).sub_exp(DefineOpaqueTypes::No, a_is_expected, a, b))
|
||||
// FIXME(tree_universes): leaking universes
|
||||
self.enter_forall(predicate, |ty::SubtypePredicate { a_is_expected, a, b }| {
|
||||
Ok(self.at(cause, param_env).sub_exp(DefineOpaqueTypes::No, a_is_expected, a, b))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn region_outlives_predicate(
|
||||
|
@ -1043,10 +1043,13 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
cause: &traits::ObligationCause<'tcx>,
|
||||
predicate: ty::PolyRegionOutlivesPredicate<'tcx>,
|
||||
) {
|
||||
let ty::OutlivesPredicate(r_a, r_b) = self.instantiate_binder_with_placeholders(predicate);
|
||||
let origin =
|
||||
SubregionOrigin::from_obligation_cause(cause, || RelateRegionParamBound(cause.span));
|
||||
self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b`
|
||||
// FIXME(tree_universes): leaking universes
|
||||
self.enter_forall(predicate, |ty::OutlivesPredicate(r_a, r_b)| {
|
||||
let origin = SubregionOrigin::from_obligation_cause(cause, || {
|
||||
RelateRegionParamBound(cause.span)
|
||||
});
|
||||
self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b`
|
||||
})
|
||||
}
|
||||
|
||||
/// Number of type variables created so far.
|
||||
|
@ -1455,7 +1458,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
// Use this method if you'd like to find some substitution of the binder's
|
||||
// variables (e.g. during a method call). If there isn't a [`BoundRegionConversionTime`]
|
||||
// that corresponds to your use case, consider whether or not you should
|
||||
// use [`InferCtxt::instantiate_binder_with_placeholders`] instead.
|
||||
// use [`InferCtxt::enter_forall`] instead.
|
||||
pub fn instantiate_binder_with_fresh_vars<T>(
|
||||
&self,
|
||||
span: Span,
|
||||
|
|
|
@ -38,24 +38,24 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
|
|||
// First, we instantiate each bound region in the supertype with a
|
||||
// fresh placeholder region. Note that this automatically creates
|
||||
// a new universe if needed.
|
||||
let sup_prime = self.infcx.instantiate_binder_with_placeholders(sup);
|
||||
self.infcx.enter_forall(sup, |sup_prime| {
|
||||
// Next, we instantiate each bound region in the subtype
|
||||
// with a fresh region variable. These region variables --
|
||||
// but no other preexisting region variables -- can name
|
||||
// the placeholders.
|
||||
let sub_prime =
|
||||
self.infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, sub);
|
||||
debug!("a_prime={:?}", sub_prime);
|
||||
debug!("b_prime={:?}", sup_prime);
|
||||
|
||||
// Next, we instantiate each bound region in the subtype
|
||||
// with a fresh region variable. These region variables --
|
||||
// but no other preexisting region variables -- can name
|
||||
// the placeholders.
|
||||
let sub_prime = self.infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, sub);
|
||||
|
||||
debug!("a_prime={:?}", sub_prime);
|
||||
debug!("b_prime={:?}", sup_prime);
|
||||
|
||||
// Compare types now that bound regions have been replaced.
|
||||
let result = self.sub(sub_is_expected).relate(sub_prime, sup_prime)?;
|
||||
|
||||
debug!("OK result={result:?}");
|
||||
// NOTE: returning the result here would be dangerous as it contains
|
||||
// placeholders which **must not** be named afterwards.
|
||||
Ok(())
|
||||
// Compare types now that bound regions have been replaced.
|
||||
// FIXME(tree_universes): leaked dead universes
|
||||
let result = self.sub(sub_is_expected).relate(sub_prime, sup_prime);
|
||||
if result.is_ok() {
|
||||
debug!("OK result={result:?}");
|
||||
}
|
||||
result.map(|_| ())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,6 +106,14 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
self.tcx.replace_bound_vars_uncached(binder, delegate)
|
||||
}
|
||||
|
||||
pub fn enter_forall<T, U>(&self, forall: ty::Binder<'tcx, T>, f: impl FnOnce(T) -> U) -> U
|
||||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>> + Copy,
|
||||
{
|
||||
let value = self.instantiate_binder_with_placeholders(forall);
|
||||
f(value)
|
||||
}
|
||||
|
||||
/// See [RegionConstraintCollector::leak_check][1]. We only check placeholder
|
||||
/// leaking into `outer_universe`, i.e. placeholders which cannot be named by that
|
||||
/// universe.
|
||||
|
|
|
@ -309,6 +309,18 @@ where
|
|||
replaced
|
||||
}
|
||||
|
||||
fn enter_forall<T, U>(
|
||||
&mut self,
|
||||
binder: ty::Binder<'tcx, T>,
|
||||
f: impl FnOnce(&mut Self, T) -> U,
|
||||
) -> U
|
||||
where
|
||||
T: ty::TypeFoldable<TyCtxt<'tcx>> + Copy,
|
||||
{
|
||||
let value = self.instantiate_binder_with_placeholders(binder);
|
||||
f(self, value)
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn instantiate_binder_with_existentials<T>(&mut self, binder: ty::Binder<'tcx, T>) -> T
|
||||
where
|
||||
|
@ -630,10 +642,10 @@ where
|
|||
|
||||
// Note: the order here is important. Create the placeholders first, otherwise
|
||||
// we assign the wrong universe to the existential!
|
||||
let b_replaced = self.instantiate_binder_with_placeholders(b);
|
||||
let a_replaced = self.instantiate_binder_with_existentials(a);
|
||||
|
||||
self.relate(a_replaced, b_replaced)?;
|
||||
self.enter_forall(b, |this, b| {
|
||||
let a = this.instantiate_binder_with_existentials(a);
|
||||
this.relate(a, b)
|
||||
})?;
|
||||
|
||||
self.ambient_variance = variance;
|
||||
}
|
||||
|
@ -650,10 +662,10 @@ where
|
|||
let variance =
|
||||
std::mem::replace(&mut self.ambient_variance, ty::Variance::Contravariant);
|
||||
|
||||
let a_replaced = self.instantiate_binder_with_placeholders(a);
|
||||
let b_replaced = self.instantiate_binder_with_existentials(b);
|
||||
|
||||
self.relate(a_replaced, b_replaced)?;
|
||||
self.enter_forall(a, |this, a| {
|
||||
let b = this.instantiate_binder_with_existentials(b);
|
||||
this.relate(a, b)
|
||||
})?;
|
||||
|
||||
self.ambient_variance = variance;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue