1
Fork 0

rename instantiate_binder_with_placeholders

This commit is contained in:
Boxy 2024-01-30 02:15:21 +00:00
parent ac559af98f
commit b181a12623
10 changed files with 38 additions and 23 deletions

View file

@ -1032,7 +1032,7 @@ impl<'tcx> InferCtxt<'tcx> {
_ => {} _ => {}
} }
// FIXME(tree_universes): leaking universes // FIXME(tree_universes): leaking placeholders
self.enter_forall(predicate, |ty::SubtypePredicate { a_is_expected, a, b }| { 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)) Ok(self.at(cause, param_env).sub_exp(DefineOpaqueTypes::No, a_is_expected, a, b))
}) })
@ -1043,7 +1043,7 @@ impl<'tcx> InferCtxt<'tcx> {
cause: &traits::ObligationCause<'tcx>, cause: &traits::ObligationCause<'tcx>,
predicate: ty::PolyRegionOutlivesPredicate<'tcx>, predicate: ty::PolyRegionOutlivesPredicate<'tcx>,
) { ) {
// FIXME(tree_universes): leaking universes // FIXME(tree_universes): leaking placeholders
self.enter_forall(predicate, |ty::OutlivesPredicate(r_a, r_b)| { self.enter_forall(predicate, |ty::OutlivesPredicate(r_a, r_b)| {
let origin = SubregionOrigin::from_obligation_cause(cause, || { let origin = SubregionOrigin::from_obligation_cause(cause, || {
RelateRegionParamBound(cause.span) RelateRegionParamBound(cause.span)

View file

@ -49,11 +49,13 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
debug!("b_prime={:?}", sup_prime); debug!("b_prime={:?}", sup_prime);
// Compare types now that bound regions have been replaced. // Compare types now that bound regions have been replaced.
// FIXME(tree_universes): leaked dead universes // FIXME(tree_universes): leaked universes
let result = self.sub(sub_is_expected).relate(sub_prime, sup_prime); let result = self.sub(sub_is_expected).relate(sub_prime, sup_prime);
if result.is_ok() { if result.is_ok() {
debug!("OK result={result:?}"); debug!("OK result={result:?}");
} }
// NOTE: returning the result here would be dangerous as it contains
// placeholders which **must not** be named afterwards.
result.map(|_| ()) result.map(|_| ())
}) })
} }
@ -68,9 +70,11 @@ impl<'tcx> InferCtxt<'tcx> {
/// This is the first step of checking subtyping when higher-ranked things are involved. /// This is the first step of checking subtyping when higher-ranked things are involved.
/// For more details visit the relevant sections of the [rustc dev guide]. /// For more details visit the relevant sections of the [rustc dev guide].
/// ///
/// `enter_forall` should be preferred over this method.
///
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
#[instrument(level = "debug", skip(self), ret)] #[instrument(level = "debug", skip(self), ret)]
pub fn instantiate_binder_with_placeholders<T>(&self, binder: ty::Binder<'tcx, T>) -> T pub fn enter_forall_and_leak_universe<T>(&self, binder: ty::Binder<'tcx, T>) -> T
where where
T: TypeFoldable<TyCtxt<'tcx>> + Copy, T: TypeFoldable<TyCtxt<'tcx>> + Copy,
{ {
@ -106,11 +110,24 @@ impl<'tcx> InferCtxt<'tcx> {
self.tcx.replace_bound_vars_uncached(binder, delegate) self.tcx.replace_bound_vars_uncached(binder, delegate)
} }
/// Replaces all bound variables (lifetimes, types, and constants) bound by
/// `binder` with placeholder variables in a new universe. This means that the
/// new placeholders can only be named by inference variables created after
/// this method has been called.
///
/// This is the first step of checking subtyping when higher-ranked things are involved.
/// For more details visit the relevant sections of the [rustc dev guide].
///
/// This method should be preferred over `enter_forall_and_leak_universe`.
///
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
#[instrument(level = "debug", skip(self, f))]
pub fn enter_forall<T, U>(&self, forall: ty::Binder<'tcx, T>, f: impl FnOnce(T) -> U) -> U pub fn enter_forall<T, U>(&self, forall: ty::Binder<'tcx, T>, f: impl FnOnce(T) -> U) -> U
where where
T: TypeFoldable<TyCtxt<'tcx>> + Copy, T: TypeFoldable<TyCtxt<'tcx>> + Copy,
{ {
let value = self.instantiate_binder_with_placeholders(forall); let value = self.enter_forall_and_leak_universe(forall);
debug!("?value");
f(value) f(value)
} }

View file

@ -262,7 +262,7 @@ where
} }
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]
fn instantiate_binder_with_placeholders<T>(&mut self, binder: ty::Binder<'tcx, T>) -> T fn enter_forall_and_leak_universe<T>(&mut self, binder: ty::Binder<'tcx, T>) -> T
where where
T: ty::TypeFoldable<TyCtxt<'tcx>> + Copy, T: ty::TypeFoldable<TyCtxt<'tcx>> + Copy,
{ {
@ -317,7 +317,7 @@ where
where where
T: ty::TypeFoldable<TyCtxt<'tcx>> + Copy, T: ty::TypeFoldable<TyCtxt<'tcx>> + Copy,
{ {
let value = self.instantiate_binder_with_placeholders(binder); let value = self.enter_forall_and_leak_universe(binder);
f(self, value) f(self, value)
} }

View file

@ -140,7 +140,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
) )
} }
ty::PredicateKind::Subtype(pred) => { ty::PredicateKind::Subtype(pred) => {
let (a, b) = infcx.instantiate_binder_with_placeholders( let (a, b) = infcx.enter_forall_and_leak_universe(
goal.predicate.kind().rebind((pred.a, pred.b)), goal.predicate.kind().rebind((pred.a, pred.b)),
); );
let expected_found = ExpectedFound::new(true, a, b); let expected_found = ExpectedFound::new(true, a, b);
@ -150,7 +150,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
) )
} }
ty::PredicateKind::Coerce(pred) => { ty::PredicateKind::Coerce(pred) => {
let (a, b) = infcx.instantiate_binder_with_placeholders( let (a, b) = infcx.enter_forall_and_leak_universe(
goal.predicate.kind().rebind((pred.a, pred.b)), goal.predicate.kind().rebind((pred.a, pred.b)),
); );
let expected_found = ExpectedFound::new(false, a, b); let expected_found = ExpectedFound::new(false, a, b);

View file

@ -358,8 +358,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
| ty::PredicateKind::Coerce(_) | ty::PredicateKind::Coerce(_)
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
| ty::PredicateKind::ConstEquate(..) => { | ty::PredicateKind::ConstEquate(..) => {
let pred = let pred = ty::Binder::dummy(infcx.enter_forall_and_leak_universe(binder));
ty::Binder::dummy(infcx.instantiate_binder_with_placeholders(binder));
ProcessResult::Changed(mk_pending(vec![obligation.with(infcx.tcx, pred)])) ProcessResult::Changed(mk_pending(vec![obligation.with(infcx.tcx, pred)]))
} }
ty::PredicateKind::Ambiguous => ProcessResult::Unchanged, ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,

View file

@ -250,8 +250,7 @@ pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
let infcx = selcx.infcx; let infcx = selcx.infcx;
let r = infcx.commit_if_ok(|_snapshot| { let r = infcx.commit_if_ok(|_snapshot| {
let old_universe = infcx.universe(); let old_universe = infcx.universe();
let placeholder_predicate = let placeholder_predicate = infcx.enter_forall_and_leak_universe(obligation.predicate);
infcx.instantiate_binder_with_placeholders(obligation.predicate);
let new_universe = infcx.universe(); let new_universe = infcx.universe();
let placeholder_obligation = obligation.with(infcx.tcx, placeholder_predicate); let placeholder_obligation = obligation.with(infcx.tcx, placeholder_predicate);

View file

@ -729,7 +729,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
self.infcx.probe(|_snapshot| { self.infcx.probe(|_snapshot| {
let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate); let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
let placeholder_trait_predicate = let placeholder_trait_predicate =
self.infcx.instantiate_binder_with_placeholders(poly_trait_predicate); self.infcx.enter_forall_and_leak_universe(poly_trait_predicate);
let self_ty = placeholder_trait_predicate.self_ty(); let self_ty = placeholder_trait_predicate.self_ty();
let principal_trait_ref = match self_ty.kind() { let principal_trait_ref = match self_ty.kind() {

View file

@ -159,7 +159,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let trait_predicate = self.infcx.shallow_resolve(obligation.predicate); let trait_predicate = self.infcx.shallow_resolve(obligation.predicate);
let placeholder_trait_predicate = let placeholder_trait_predicate =
self.infcx.instantiate_binder_with_placeholders(trait_predicate).trait_ref; self.infcx.enter_forall_and_leak_universe(trait_predicate).trait_ref;
let placeholder_self_ty = placeholder_trait_predicate.self_ty(); let placeholder_self_ty = placeholder_trait_predicate.self_ty();
let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate); let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate);
let (def_id, args) = match *placeholder_self_ty.kind() { let (def_id, args) = match *placeholder_self_ty.kind() {
@ -402,7 +402,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let cause = obligation.derived_cause(BuiltinDerivedObligation); let cause = obligation.derived_cause(BuiltinDerivedObligation);
let poly_trait_ref = obligation.predicate.to_poly_trait_ref(); let poly_trait_ref = obligation.predicate.to_poly_trait_ref();
let trait_ref = self.infcx.instantiate_binder_with_placeholders(poly_trait_ref); let trait_ref = self.infcx.enter_forall_and_leak_universe(poly_trait_ref);
let trait_obligations: Vec<PredicateObligation<'_>> = self.impl_or_trait_obligations( let trait_obligations: Vec<PredicateObligation<'_>> = self.impl_or_trait_obligations(
&cause, &cause,
obligation.recursion_depth + 1, obligation.recursion_depth + 1,
@ -493,7 +493,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let tcx = self.tcx(); let tcx = self.tcx();
debug!(?obligation, ?index, "confirm_object_candidate"); debug!(?obligation, ?index, "confirm_object_candidate");
let trait_predicate = self.infcx.instantiate_binder_with_placeholders(obligation.predicate); let trait_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
let self_ty = self.infcx.shallow_resolve(trait_predicate.self_ty()); let self_ty = self.infcx.shallow_resolve(trait_predicate.self_ty());
let obligation_trait_ref = ty::Binder::dummy(trait_predicate.trait_ref); let obligation_trait_ref = ty::Binder::dummy(trait_predicate.trait_ref);
let ty::Dynamic(data, ..) = *self_ty.kind() else { let ty::Dynamic(data, ..) = *self_ty.kind() else {
@ -691,7 +691,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let cause = obligation.derived_cause(BuiltinDerivedObligation); let cause = obligation.derived_cause(BuiltinDerivedObligation);
// Confirm the `type Output: Sized;` bound that is present on `FnOnce` // Confirm the `type Output: Sized;` bound that is present on `FnOnce`
let output_ty = self.infcx.instantiate_binder_with_placeholders(sig.output()); let output_ty = self.infcx.enter_forall_and_leak_universe(sig.output());
let output_ty = normalize_with_depth_to( let output_ty = normalize_with_depth_to(
self, self,
obligation.param_env, obligation.param_env,
@ -712,7 +712,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
) -> Vec<PredicateObligation<'tcx>> { ) -> Vec<PredicateObligation<'tcx>> {
debug!(?obligation, "confirm_trait_alias_candidate"); debug!(?obligation, "confirm_trait_alias_candidate");
let predicate = self.infcx.instantiate_binder_with_placeholders(obligation.predicate); let predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
let trait_ref = predicate.trait_ref; let trait_ref = predicate.trait_ref;
let trait_def_id = trait_ref.def_id; let trait_def_id = trait_ref.def_id;
let args = trait_ref.args; let args = trait_ref.args;

View file

@ -1606,7 +1606,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
) -> smallvec::SmallVec<[usize; 2]> { ) -> smallvec::SmallVec<[usize; 2]> {
let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate); let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
let placeholder_trait_predicate = let placeholder_trait_predicate =
self.infcx.instantiate_binder_with_placeholders(poly_trait_predicate); self.infcx.enter_forall_and_leak_universe(poly_trait_predicate);
debug!(?placeholder_trait_predicate); debug!(?placeholder_trait_predicate);
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
@ -2386,7 +2386,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
.flat_map(|ty| { .flat_map(|ty| {
let ty: ty::Binder<'tcx, Ty<'tcx>> = types.rebind(*ty); // <----/ let ty: ty::Binder<'tcx, Ty<'tcx>> = types.rebind(*ty); // <----/
let placeholder_ty = self.infcx.instantiate_binder_with_placeholders(ty); let placeholder_ty = self.infcx.enter_forall_and_leak_universe(ty);
let Normalized { value: normalized_ty, mut obligations } = let Normalized { value: normalized_ty, mut obligations } =
ensure_sufficient_stack(|| { ensure_sufficient_stack(|| {
project::normalize_with_depth( project::normalize_with_depth(
@ -2472,7 +2472,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
obligation: &PolyTraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> Result<Normalized<'tcx, GenericArgsRef<'tcx>>, ()> { ) -> Result<Normalized<'tcx, GenericArgsRef<'tcx>>, ()> {
let placeholder_obligation = let placeholder_obligation =
self.infcx.instantiate_binder_with_placeholders(obligation.predicate); self.infcx.enter_forall_and_leak_universe(obligation.predicate);
let placeholder_obligation_trait_ref = placeholder_obligation.trait_ref; let placeholder_obligation_trait_ref = placeholder_obligation.trait_ref;
let impl_args = self.infcx.fresh_args_for_item(obligation.cause.span, impl_def_id); let impl_args = self.infcx.fresh_args_for_item(obligation.cause.span, impl_def_id);

View file

@ -164,7 +164,7 @@ pub enum RegionKind<I: Interner> {
/// Should not exist outside of type inference. /// Should not exist outside of type inference.
/// ///
/// Used when instantiating a `forall` binder via /// Used when instantiating a `forall` binder via
/// `infcx.enter_forall` and `infcx.instantiate_binder_with_placeholders`. /// `infcx.enter_forall` and `infcx.enter_forall_and_leak_universe`.
RePlaceholder(I::PlaceholderRegion), RePlaceholder(I::PlaceholderRegion),
/// Erased region, used by trait selection, in MIR and during codegen. /// Erased region, used by trait selection, in MIR and during codegen.