Split Bound into Canonical and Bound
This commit is contained in:
@@ -74,12 +74,10 @@ pub(super) struct Canonicalizer<'a, D: SolverDelegate<Interner = I>, I: Interner
|
||||
/// we set the `sub_root` of the second variable to the position of the first.
|
||||
/// Otherwise the `sub_root` of each type variable is just its own position.
|
||||
sub_root_lookup_table: HashMap<ty::TyVid, usize>,
|
||||
binder_index: ty::DebruijnIndex,
|
||||
|
||||
/// We only use the debruijn index during lookup. We don't need to
|
||||
/// track the `variables` as each generic arg only results in a single
|
||||
/// bound variable regardless of how many times it is encountered.
|
||||
cache: HashMap<(ty::DebruijnIndex, I::Ty), I::Ty>,
|
||||
/// We can simply cache based on the ty itself, because we use
|
||||
/// `ty::BoundVarIndexKind::Canonical`.
|
||||
cache: HashMap<I::Ty, I::Ty>,
|
||||
}
|
||||
|
||||
impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
||||
@@ -97,7 +95,6 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
||||
variable_lookup_table: Default::default(),
|
||||
sub_root_lookup_table: Default::default(),
|
||||
var_kinds: Vec::new(),
|
||||
binder_index: ty::INNERMOST,
|
||||
|
||||
cache: Default::default(),
|
||||
};
|
||||
@@ -141,12 +138,10 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
||||
variable_lookup_table: Default::default(),
|
||||
sub_root_lookup_table: Default::default(),
|
||||
var_kinds: Vec::new(),
|
||||
binder_index: ty::INNERMOST,
|
||||
|
||||
cache: Default::default(),
|
||||
};
|
||||
let param_env = param_env.fold_with(&mut env_canonicalizer);
|
||||
debug_assert_eq!(env_canonicalizer.binder_index, ty::INNERMOST);
|
||||
debug_assert!(env_canonicalizer.sub_root_lookup_table.is_empty());
|
||||
CanonicalParamEnvCacheEntry {
|
||||
param_env,
|
||||
@@ -175,12 +170,10 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
||||
variable_lookup_table: Default::default(),
|
||||
sub_root_lookup_table: Default::default(),
|
||||
var_kinds: Vec::new(),
|
||||
binder_index: ty::INNERMOST,
|
||||
|
||||
cache: Default::default(),
|
||||
};
|
||||
let param_env = param_env.fold_with(&mut env_canonicalizer);
|
||||
debug_assert_eq!(env_canonicalizer.binder_index, ty::INNERMOST);
|
||||
debug_assert!(env_canonicalizer.sub_root_lookup_table.is_empty());
|
||||
(param_env, env_canonicalizer.variable_lookup_table, env_canonicalizer.var_kinds)
|
||||
}
|
||||
@@ -212,7 +205,6 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
||||
variable_lookup_table,
|
||||
sub_root_lookup_table: Default::default(),
|
||||
var_kinds,
|
||||
binder_index: ty::INNERMOST,
|
||||
|
||||
// We do not reuse the cache as it may contain entries whose canonicalized
|
||||
// value contains `'static`. While we could alternatively handle this by
|
||||
@@ -409,7 +401,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
||||
|
||||
let var = self.get_or_insert_bound_var(t, kind);
|
||||
|
||||
Ty::new_anon_bound(self.cx(), self.binder_index, var)
|
||||
Ty::new_canonical_bound(self.cx(), var)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,16 +410,6 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
|
||||
self.delegate.cx()
|
||||
}
|
||||
|
||||
fn fold_binder<T>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T>
|
||||
where
|
||||
T: TypeFoldable<I>,
|
||||
{
|
||||
self.binder_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
self.binder_index.shift_out(1);
|
||||
t
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: I::Region) -> I::Region {
|
||||
let kind = match r.kind() {
|
||||
ty::ReBound(..) => return r,
|
||||
@@ -491,15 +473,15 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
|
||||
|
||||
let var = self.get_or_insert_bound_var(r, kind);
|
||||
|
||||
Region::new_anon_bound(self.cx(), self.binder_index, var)
|
||||
Region::new_canonical_bound(self.cx(), var)
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
|
||||
if let Some(&ty) = self.cache.get(&(self.binder_index, t)) {
|
||||
if let Some(&ty) = self.cache.get(&t) {
|
||||
ty
|
||||
} else {
|
||||
let res = self.inner_fold_ty(t);
|
||||
let old = self.cache.insert((self.binder_index, t), res);
|
||||
let old = self.cache.insert(t, res);
|
||||
assert_eq!(old, None);
|
||||
res
|
||||
}
|
||||
@@ -552,7 +534,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
|
||||
|
||||
let var = self.get_or_insert_bound_var(c, kind);
|
||||
|
||||
Const::new_anon_bound(self.cx(), self.binder_index, var)
|
||||
Const::new_canonical_bound(self.cx(), var)
|
||||
}
|
||||
|
||||
fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
|
||||
|
||||
@@ -167,25 +167,25 @@ where
|
||||
// and only use it for placeholders. We need to handle the
|
||||
// `sub_root` of type inference variables which would make this
|
||||
// more involved. They are also a lot rarer than region variables.
|
||||
if let ty::Bound(debruijn, b) = t.kind()
|
||||
if let ty::Bound(index_kind, b) = t.kind()
|
||||
&& !matches!(
|
||||
response.variables.get(b.var().as_usize()).unwrap(),
|
||||
CanonicalVarKind::Ty { .. }
|
||||
)
|
||||
{
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
assert!(matches!(index_kind, ty::BoundVarIndexKind::Canonical));
|
||||
opt_values[b.var()] = Some(*original_value);
|
||||
}
|
||||
}
|
||||
ty::GenericArgKind::Lifetime(r) => {
|
||||
if let ty::ReBound(debruijn, br) = r.kind() {
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
if let ty::ReBound(index_kind, br) = r.kind() {
|
||||
assert!(matches!(index_kind, ty::BoundVarIndexKind::Canonical));
|
||||
opt_values[br.var()] = Some(*original_value);
|
||||
}
|
||||
}
|
||||
ty::GenericArgKind::Const(c) => {
|
||||
if let ty::ConstKind::Bound(debruijn, bv) = c.kind() {
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
if let ty::ConstKind::Bound(index_kind, bv) = c.kind() {
|
||||
assert!(matches!(index_kind, ty::BoundVarIndexKind::Canonical));
|
||||
opt_values[bv.var()] = Some(*original_value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ where
|
||||
|
||||
fn fold_region(&mut self, r: I::Region) -> I::Region {
|
||||
match r.kind() {
|
||||
ty::ReBound(debruijn, _)
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _)
|
||||
if debruijn.as_usize()
|
||||
>= self.current_index.as_usize() + self.universe_indices.len() =>
|
||||
{
|
||||
@@ -99,7 +99,9 @@ where
|
||||
self.universe_indices
|
||||
);
|
||||
}
|
||||
ty::ReBound(debruijn, br) if debruijn >= self.current_index => {
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), br)
|
||||
if debruijn >= self.current_index =>
|
||||
{
|
||||
let universe = self.universe_for(debruijn);
|
||||
let p = PlaceholderLike::new(universe, br);
|
||||
self.mapped_regions.insert(p, br);
|
||||
@@ -111,7 +113,7 @@ where
|
||||
|
||||
fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
|
||||
match t.kind() {
|
||||
ty::Bound(debruijn, _)
|
||||
ty::Bound(ty::BoundVarIndexKind::Bound(debruijn), _)
|
||||
if debruijn.as_usize() + 1
|
||||
> self.current_index.as_usize() + self.universe_indices.len() =>
|
||||
{
|
||||
@@ -120,7 +122,9 @@ where
|
||||
self.universe_indices
|
||||
);
|
||||
}
|
||||
ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => {
|
||||
ty::Bound(ty::BoundVarIndexKind::Bound(debruijn), bound_ty)
|
||||
if debruijn >= self.current_index =>
|
||||
{
|
||||
let universe = self.universe_for(debruijn);
|
||||
let p = PlaceholderLike::new(universe, bound_ty);
|
||||
self.mapped_types.insert(p, bound_ty);
|
||||
@@ -133,7 +137,7 @@ where
|
||||
|
||||
fn fold_const(&mut self, ct: I::Const) -> I::Const {
|
||||
match ct.kind() {
|
||||
ty::ConstKind::Bound(debruijn, _)
|
||||
ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(debruijn), _)
|
||||
if debruijn.as_usize() + 1
|
||||
> self.current_index.as_usize() + self.universe_indices.len() =>
|
||||
{
|
||||
@@ -142,7 +146,9 @@ where
|
||||
self.universe_indices
|
||||
);
|
||||
}
|
||||
ty::ConstKind::Bound(debruijn, bound_const) if debruijn >= self.current_index => {
|
||||
ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(debruijn), bound_const)
|
||||
if debruijn >= self.current_index =>
|
||||
{
|
||||
let universe = self.universe_for(debruijn);
|
||||
let p = PlaceholderLike::new(universe, bound_const);
|
||||
self.mapped_consts.insert(p, bound_const);
|
||||
|
||||
Reference in New Issue
Block a user