Skip to content

Commit f867742

Browse files
committed
reviews + rebase
1 parent b181a12 commit f867742

File tree

11 files changed

+101
-114
lines changed

11 files changed

+101
-114
lines changed

compiler/rustc_infer/src/infer/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1032,7 +1032,6 @@ impl<'tcx> InferCtxt<'tcx> {
10321032
_ => {}
10331033
}
10341034

1035-
// FIXME(tree_universes): leaking placeholders
10361035
self.enter_forall(predicate, |ty::SubtypePredicate { a_is_expected, a, b }| {
10371036
Ok(self.at(cause, param_env).sub_exp(DefineOpaqueTypes::No, a_is_expected, a, b))
10381037
})
@@ -1043,7 +1042,6 @@ impl<'tcx> InferCtxt<'tcx> {
10431042
cause: &traits::ObligationCause<'tcx>,
10441043
predicate: ty::PolyRegionOutlivesPredicate<'tcx>,
10451044
) {
1046-
// FIXME(tree_universes): leaking placeholders
10471045
self.enter_forall(predicate, |ty::OutlivesPredicate(r_a, r_b)| {
10481046
let origin = SubregionOrigin::from_obligation_cause(cause, || {
10491047
RelateRegionParamBound(cause.span)

compiler/rustc_infer/src/infer/relate/higher_ranked.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
4949
debug!("b_prime={:?}", sup_prime);
5050

5151
// Compare types now that bound regions have been replaced.
52-
// FIXME(tree_universes): leaked universes
5352
let result = self.sub(sub_is_expected).relate(sub_prime, sup_prime);
5453
if result.is_ok() {
5554
debug!("OK result={result:?}");
@@ -70,7 +69,7 @@ impl<'tcx> InferCtxt<'tcx> {
7069
/// This is the first step of checking subtyping when higher-ranked things are involved.
7170
/// For more details visit the relevant sections of the [rustc dev guide].
7271
///
73-
/// `enter_forall` should be preferred over this method.
72+
/// `fn enter_forall` should be preferred over this method.
7473
///
7574
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
7675
#[instrument(level = "debug", skip(self), ret)]
@@ -111,21 +110,25 @@ impl<'tcx> InferCtxt<'tcx> {
111110
}
112111

113112
/// Replaces all bound variables (lifetimes, types, and constants) bound by
114-
/// `binder` with placeholder variables in a new universe. This means that the
115-
/// new placeholders can only be named by inference variables created after
116-
/// this method has been called.
113+
/// `binder` with placeholder variables in a new universe and then calls the
114+
/// closure `f` with the instantiated value. The new placeholders can only be
115+
/// named by inference variables created inside of the closure `f` or afterwards.
117116
///
118117
/// This is the first step of checking subtyping when higher-ranked things are involved.
119118
/// For more details visit the relevant sections of the [rustc dev guide].
120119
///
121-
/// This method should be preferred over `enter_forall_and_leak_universe`.
120+
/// This method should be preferred over `fn enter_forall_and_leak_universe`.
122121
///
123122
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
124123
#[instrument(level = "debug", skip(self, f))]
125124
pub fn enter_forall<T, U>(&self, forall: ty::Binder<'tcx, T>, f: impl FnOnce(T) -> U) -> U
126125
where
127126
T: TypeFoldable<TyCtxt<'tcx>> + Copy,
128127
{
128+
// FIXME: currently we do nothing to prevent placeholders with the new universe being
129+
// used after exiting `f`. For example region subtyping can result in outlives constraints
130+
// that name placeholders created in this function. Nested goals from type relations can
131+
// also contain placeholders created by this function.
129132
let value = self.enter_forall_and_leak_universe(forall);
130133
debug!("?value");
131134
f(value)

compiler/rustc_infer/src/infer/relate/nll.rs

+40-49
Original file line numberDiff line numberDiff line change
@@ -261,54 +261,6 @@ where
261261
Ok(a)
262262
}
263263

264-
#[instrument(skip(self), level = "debug")]
265-
fn enter_forall_and_leak_universe<T>(&mut self, binder: ty::Binder<'tcx, T>) -> T
266-
where
267-
T: ty::TypeFoldable<TyCtxt<'tcx>> + Copy,
268-
{
269-
if let Some(inner) = binder.no_bound_vars() {
270-
return inner;
271-
}
272-
273-
let mut next_region = {
274-
let nll_delegate = &mut self.delegate;
275-
let mut lazy_universe = None;
276-
277-
move |br: ty::BoundRegion| {
278-
// The first time this closure is called, create a
279-
// new universe for the placeholders we will make
280-
// from here out.
281-
let universe = lazy_universe.unwrap_or_else(|| {
282-
let universe = nll_delegate.create_next_universe();
283-
lazy_universe = Some(universe);
284-
universe
285-
});
286-
287-
let placeholder = ty::PlaceholderRegion { universe, bound: br };
288-
debug!(?placeholder);
289-
let placeholder_reg = nll_delegate.next_placeholder_region(placeholder);
290-
debug!(?placeholder_reg);
291-
292-
placeholder_reg
293-
}
294-
};
295-
296-
let delegate = FnMutDelegate {
297-
regions: &mut next_region,
298-
types: &mut |_bound_ty: ty::BoundTy| {
299-
unreachable!("we only replace regions in nll_relate, not types")
300-
},
301-
consts: &mut |_bound_var: ty::BoundVar, _ty| {
302-
unreachable!("we only replace regions in nll_relate, not consts")
303-
},
304-
};
305-
306-
let replaced = self.infcx.tcx.replace_bound_vars_uncached(binder, delegate);
307-
debug!(?replaced);
308-
309-
replaced
310-
}
311-
312264
fn enter_forall<T, U>(
313265
&mut self,
314266
binder: ty::Binder<'tcx, T>,
@@ -317,7 +269,46 @@ where
317269
where
318270
T: ty::TypeFoldable<TyCtxt<'tcx>> + Copy,
319271
{
320-
let value = self.enter_forall_and_leak_universe(binder);
272+
let value = if let Some(inner) = binder.no_bound_vars() {
273+
inner
274+
} else {
275+
let mut next_region = {
276+
let nll_delegate = &mut self.delegate;
277+
let mut lazy_universe = None;
278+
279+
move |br: ty::BoundRegion| {
280+
// The first time this closure is called, create a
281+
// new universe for the placeholders we will make
282+
// from here out.
283+
let universe = lazy_universe.unwrap_or_else(|| {
284+
let universe = nll_delegate.create_next_universe();
285+
lazy_universe = Some(universe);
286+
universe
287+
});
288+
289+
let placeholder = ty::PlaceholderRegion { universe, bound: br };
290+
debug!(?placeholder);
291+
let placeholder_reg = nll_delegate.next_placeholder_region(placeholder);
292+
debug!(?placeholder_reg);
293+
294+
placeholder_reg
295+
}
296+
};
297+
298+
let delegate = FnMutDelegate {
299+
regions: &mut next_region,
300+
types: &mut |_bound_ty: ty::BoundTy| {
301+
unreachable!("we only replace regions in nll_relate, not types")
302+
},
303+
consts: &mut |_bound_var: ty::BoundVar, _ty| {
304+
unreachable!("we only replace regions in nll_relate, not consts")
305+
},
306+
};
307+
308+
self.infcx.tcx.replace_bound_vars_uncached(binder, delegate)
309+
};
310+
311+
debug!(?value);
321312
f(self, value)
322313
}
323314

compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
5959

6060
ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]),
6161

62-
ty::CoroutineClosure(_, args) => Ok(vec![args.as_coroutine_closure().tupled_upvars_ty()]),
62+
ty::CoroutineClosure(_, args) => {
63+
Ok(vec![ty::Binder::dummy(args.as_coroutine_closure().tupled_upvars_ty())])
64+
}
6365

6466
ty::Coroutine(_, args) => {
6567
let coroutine_args = args.as_coroutine();

compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
480480
self.infcx.enter_forall(kind, |kind| {
481481
let goal = goal.with(self.tcx(), ty::Binder::dummy(kind));
482482
self.add_goal(GoalSource::Misc, goal);
483-
// FIXME(tree_universes): leaking universes
484483
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
485484
})
486485
}

compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs

-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ impl<'tcx> InferCtxtSelectExt<'tcx> for InferCtxt<'tcx> {
3131
) -> SelectionResult<'tcx, Selection<'tcx>> {
3232
assert!(self.next_trait_solver());
3333

34-
// FIXME(tree_universes): leaking universes?
3534
self.enter_forall(obligation.predicate, |pred| {
3635
let trait_goal = Goal::new(self.tcx, obligation.param_env, pred);
3736

compiler/rustc_trait_selection/src/solve/trait_goals.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1060,7 +1060,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
10601060
constituent_tys(ecx, goal.predicate.self_ty())?
10611061
.into_iter()
10621062
.map(|ty| {
1063-
// FIXME(tree_universes): leaking universes
10641063
ecx.enter_forall(ty, |ty| {
10651064
goal.with(ecx.tcx(), goal.predicate.with_self_ty(ecx.tcx(), ty))
10661065
})

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4621,7 +4621,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
46214621
let ocx = ObligationCtxt::new(self);
46224622
self.enter_forall(pred, |pred| {
46234623
let pred = ocx.normalize(&ObligationCause::dummy(), param_env, pred);
4624-
// FIXME(tree_universes): universe leakage
46254624
ocx.register_obligation(Obligation::new(
46264625
self.tcx,
46274626
ObligationCause::dummy(),

compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

-1
Original file line numberDiff line numberDiff line change
@@ -2049,7 +2049,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
20492049
for (obligation_arg, impl_arg) in
20502050
std::iter::zip(obligation_trait_ref.args, impl_trait_ref.args)
20512051
{
2052-
// FIXME(tree_universes): universe leakage
20532052
if let Err(terr) =
20542053
ocx.eq(&ObligationCause::dummy(), param_env, impl_arg, obligation_arg)
20552054
{

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

+48-49
Original file line numberDiff line numberDiff line change
@@ -728,64 +728,63 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
728728

729729
self.infcx.probe(|_snapshot| {
730730
let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
731-
let placeholder_trait_predicate =
732-
self.infcx.enter_forall_and_leak_universe(poly_trait_predicate);
733-
734-
let self_ty = placeholder_trait_predicate.self_ty();
735-
let principal_trait_ref = match self_ty.kind() {
736-
ty::Dynamic(data, ..) => {
737-
if data.auto_traits().any(|did| did == obligation.predicate.def_id()) {
738-
debug!(
739-
"assemble_candidates_from_object_ty: matched builtin bound, \
731+
self.infcx.enter_forall(poly_trait_predicate, |placeholder_trait_predicate| {
732+
let self_ty = placeholder_trait_predicate.self_ty();
733+
let principal_trait_ref = match self_ty.kind() {
734+
ty::Dynamic(data, ..) => {
735+
if data.auto_traits().any(|did| did == obligation.predicate.def_id()) {
736+
debug!(
737+
"assemble_candidates_from_object_ty: matched builtin bound, \
740738
pushing candidate"
741-
);
742-
candidates.vec.push(BuiltinObjectCandidate);
743-
return;
744-
}
739+
);
740+
candidates.vec.push(BuiltinObjectCandidate);
741+
return;
742+
}
745743

746-
if let Some(principal) = data.principal() {
747-
if !self.infcx.tcx.features().object_safe_for_dispatch {
748-
principal.with_self_ty(self.tcx(), self_ty)
749-
} else if self.tcx().check_is_object_safe(principal.def_id()) {
750-
principal.with_self_ty(self.tcx(), self_ty)
744+
if let Some(principal) = data.principal() {
745+
if !self.infcx.tcx.features().object_safe_for_dispatch {
746+
principal.with_self_ty(self.tcx(), self_ty)
747+
} else if self.tcx().check_is_object_safe(principal.def_id()) {
748+
principal.with_self_ty(self.tcx(), self_ty)
749+
} else {
750+
return;
751+
}
751752
} else {
753+
// Only auto trait bounds exist.
752754
return;
753755
}
754-
} else {
755-
// Only auto trait bounds exist.
756+
}
757+
ty::Infer(ty::TyVar(_)) => {
758+
debug!("assemble_candidates_from_object_ty: ambiguous");
759+
candidates.ambiguous = true; // could wind up being an object type
756760
return;
757761
}
758-
}
759-
ty::Infer(ty::TyVar(_)) => {
760-
debug!("assemble_candidates_from_object_ty: ambiguous");
761-
candidates.ambiguous = true; // could wind up being an object type
762-
return;
763-
}
764-
_ => return,
765-
};
766-
767-
debug!(?principal_trait_ref, "assemble_candidates_from_object_ty");
768-
769-
// Count only those upcast versions that match the trait-ref
770-
// we are looking for. Specifically, do not only check for the
771-
// correct trait, but also the correct type parameters.
772-
// For example, we may be trying to upcast `Foo` to `Bar<i32>`,
773-
// but `Foo` is declared as `trait Foo: Bar<u32>`.
774-
let candidate_supertraits = util::supertraits(self.tcx(), principal_trait_ref)
775-
.enumerate()
776-
.filter(|&(_, upcast_trait_ref)| {
777-
self.infcx.probe(|_| {
778-
self.match_normalize_trait_ref(
779-
obligation,
780-
upcast_trait_ref,
781-
placeholder_trait_predicate.trait_ref,
782-
)
783-
.is_ok()
762+
_ => return,
763+
};
764+
765+
debug!(?principal_trait_ref, "assemble_candidates_from_object_ty");
766+
767+
// Count only those upcast versions that match the trait-ref
768+
// we are looking for. Specifically, do not only check for the
769+
// correct trait, but also the correct type parameters.
770+
// For example, we may be trying to upcast `Foo` to `Bar<i32>`,
771+
// but `Foo` is declared as `trait Foo: Bar<u32>`.
772+
let candidate_supertraits = util::supertraits(self.tcx(), principal_trait_ref)
773+
.enumerate()
774+
.filter(|&(_, upcast_trait_ref)| {
775+
self.infcx.probe(|_| {
776+
self.match_normalize_trait_ref(
777+
obligation,
778+
upcast_trait_ref,
779+
placeholder_trait_predicate.trait_ref,
780+
)
781+
.is_ok()
782+
})
784783
})
785-
})
786-
.map(|(idx, _)| ObjectCandidate(idx));
784+
.map(|(idx, _)| ObjectCandidate(idx));
787785

788-
candidates.vec.extend(candidate_supertraits);
786+
candidates.vec.extend(candidate_supertraits);
787+
})
789788
})
790789
}
791790

compiler/rustc_type_ir/src/region_kind.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,7 @@ pub enum RegionKind<I: Interner> {
163163
/// A placeholder region -- the higher-ranked version of `ReLateParam`.
164164
/// Should not exist outside of type inference.
165165
///
166-
/// Used when instantiating a `forall` binder via
167-
/// `infcx.enter_forall` and `infcx.enter_forall_and_leak_universe`.
166+
/// Used when instantiating a `forall` binder via `infcx.enter_forall`.
168167
RePlaceholder(I::PlaceholderRegion),
169168

170169
/// Erased region, used by trait selection, in MIR and during codegen.

0 commit comments

Comments
 (0)