Skip to content

Commit 3d26f5a

Browse files
committed
eagerly check whether we replace any bound vars
1 parent e61807c commit 3d26f5a

File tree

3 files changed

+16
-25
lines changed

3 files changed

+16
-25
lines changed

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

+10-23
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use super::{HigherRankedType, InferCtxt};
66
use crate::infer::CombinedSnapshot;
77
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
88
use rustc_middle::ty::{self, Binder, TypeFoldable};
9-
use std::cell::Cell;
109

1110
impl<'a, 'tcx> CombineFields<'a, 'tcx> {
1211
/// Checks whether `for<..> sub <: for<..> sup` holds.
@@ -57,15 +56,17 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
5756

5857
debug!("higher_ranked_sub: OK result={result:?}");
5958
// NOTE: returning the result here would be dangerous as it contains
60-
// placeholders which **must not** be named after wards.
59+
// placeholders which **must not** be named afterwards.
6160
Ok(())
6261
})
6362
}
6463
}
6564

6665
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
6766
/// Replaces all bound variables (lifetimes, types, and constants) bound by
68-
/// `binder` with placeholder variables.
67+
/// `binder` with placeholder variables in a new universe. This means that the
68+
/// new placeholders can only be named by inference variables created after
69+
/// this method has been called.
6970
///
7071
/// This is the first step of checking subtyping when higher-ranked things are involved.
7172
/// For more details visit the relevant sections of the [rustc dev guide].
@@ -74,34 +75,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
7475
#[instrument(level = "debug", skip(self))]
7576
pub fn replace_bound_vars_with_placeholders<T>(&self, binder: ty::Binder<'tcx, T>) -> T
7677
where
77-
T: TypeFoldable<'tcx>,
78+
T: TypeFoldable<'tcx> + Copy,
7879
{
79-
// Figure out what the next universe will be, but don't actually create
80-
// it until after we've done the substitution (in particular there may
81-
// be no bound variables). This is a performance optimization, since the
82-
// leak check for example can be skipped if no new universes are created
83-
// (i.e., if there are no placeholders).
84-
let next_universe = self.universe().next_universe();
80+
if let Some(inner) = binder.no_bound_vars() {
81+
return inner;
82+
}
83+
84+
let next_universe = self.create_next_universe();
8585

86-
let replaced_bound_var = Cell::new(false);
8786
let fld_r = |br: ty::BoundRegion| {
88-
replaced_bound_var.set(true);
8987
self.tcx.mk_region(ty::RePlaceholder(ty::PlaceholderRegion {
9088
universe: next_universe,
9189
name: br.kind,
9290
}))
9391
};
9492

9593
let fld_t = |bound_ty: ty::BoundTy| {
96-
replaced_bound_var.set(true);
9794
self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
9895
universe: next_universe,
9996
name: bound_ty.var,
10097
}))
10198
};
10299

103100
let fld_c = |bound_var: ty::BoundVar, ty| {
104-
replaced_bound_var.set(true);
105101
self.tcx.mk_const(ty::ConstS {
106102
val: ty::ConstKind::Placeholder(ty::PlaceholderConst {
107103
universe: next_universe,
@@ -112,16 +108,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
112108
};
113109

114110
let result = self.tcx.replace_bound_vars_uncached(binder, fld_r, fld_t, fld_c);
115-
116-
// If there were higher-ranked regions to replace, then actually create
117-
// the next universe (this avoids needlessly creating universes).
118-
if replaced_bound_var.get() {
119-
let n_u = self.create_next_universe();
120-
assert_eq!(n_u, next_universe);
121-
}
122-
123111
debug!(?next_universe, ?result);
124-
125112
result
126113
}
127114

compiler/rustc_infer/src/infer/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1526,8 +1526,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
15261526
value: ty::Binder<'tcx, T>,
15271527
) -> T
15281528
where
1529-
T: TypeFoldable<'tcx>,
1529+
T: TypeFoldable<'tcx> + Copy,
15301530
{
1531+
if let Some(inner) = value.no_bound_vars() {
1532+
return inner;
1533+
}
1534+
15311535
let mut region_map = BTreeMap::new();
15321536
let fld_r = |br: ty::BoundRegion| {
15331537
*region_map

compiler/rustc_typeck/src/check/method/confirm.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
572572

573573
fn replace_bound_vars_with_fresh_vars<T>(&self, value: ty::Binder<'tcx, T>) -> T
574574
where
575-
T: TypeFoldable<'tcx>,
575+
T: TypeFoldable<'tcx> + Copy,
576576
{
577577
self.fcx.replace_bound_vars_with_fresh_vars(self.span, infer::FnCall, value)
578578
}

0 commit comments

Comments
 (0)