mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
review
This commit is contained in:
parent
a7b114420c
commit
1a04a317c4
@ -14,14 +14,16 @@ use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin};
|
||||
|
||||
/// Enforce that `a` is equal to or a subtype of `b`.
|
||||
pub struct TypeRelating<'combine, 'a, 'tcx> {
|
||||
// Partially mutable.
|
||||
// Immutable except for the `InferCtxt` and the
|
||||
// resulting nested `goals`.
|
||||
fields: &'combine mut CombineFields<'a, 'tcx>,
|
||||
|
||||
// Immutable fields.
|
||||
// Immutable field.
|
||||
structurally_relate_aliases: StructurallyRelateAliases,
|
||||
// Mutable field.
|
||||
ambient_variance: ty::Variance,
|
||||
|
||||
/// The cache has only tracks the `ambient_variance` as its the
|
||||
/// The cache only tracks the `ambient_variance` as it's the
|
||||
/// only field which is mutable and which meaningfully changes
|
||||
/// the result when relating types.
|
||||
///
|
||||
|
@ -210,16 +210,17 @@ where
|
||||
debug_assert!(!ty.has_vars_bound_above(ty::INNERMOST));
|
||||
ty::fold::shift_vars(self.tcx, ty, self.current_index.as_u32())
|
||||
}
|
||||
_ if t.has_vars_bound_at_or_above(self.current_index) => {
|
||||
if let Some(&ty) = self.cache.get(&(self.current_index, t)) {
|
||||
return ty;
|
||||
}
|
||||
|
||||
_ => {
|
||||
if !t.has_vars_bound_at_or_above(self.current_index) {
|
||||
t
|
||||
} else if let Some(&t) = self.cache.get(&(self.current_index, t)) {
|
||||
t
|
||||
} else {
|
||||
let res = t.super_fold_with(self);
|
||||
assert!(self.cache.insert((self.current_index, t), res));
|
||||
res
|
||||
}
|
||||
_ => t,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,17 +42,19 @@ pub enum CanonicalizeMode {
|
||||
|
||||
pub struct Canonicalizer<'a, D: SolverDelegate<Interner = I>, I: Interner> {
|
||||
delegate: &'a D,
|
||||
|
||||
// Immutable field.
|
||||
canonicalize_mode: CanonicalizeMode,
|
||||
|
||||
// Mutable fields.
|
||||
variables: &'a mut Vec<I::GenericArg>,
|
||||
variable_lookup_table: HashMap<I::GenericArg, usize>,
|
||||
|
||||
primitive_var_infos: Vec<CanonicalVarInfo<I>>,
|
||||
variable_lookup_table: HashMap<I::GenericArg, usize>,
|
||||
binder_index: ty::DebruijnIndex,
|
||||
|
||||
/// We only use the debruijn index during lookup as all other fields
|
||||
/// should not be impacted by whether a type is folded once or multiple
|
||||
/// times.
|
||||
/// 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>,
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,8 @@ where
|
||||
I: Interner,
|
||||
{
|
||||
delegate: &'a D,
|
||||
/// We're able to use a cache here as the folder does not have any
|
||||
/// mutable state.
|
||||
cache: DelayedMap<I::Ty, I::Ty>,
|
||||
}
|
||||
|
||||
|
@ -1057,16 +1057,17 @@ where
|
||||
);
|
||||
infer_ty
|
||||
}
|
||||
_ if ty.has_aliases() => {
|
||||
if let Some(&entry) = self.cache.get(&ty) {
|
||||
_ => {
|
||||
if !ty.has_aliases() {
|
||||
ty
|
||||
} else if let Some(&entry) = self.cache.get(&ty) {
|
||||
return entry;
|
||||
}
|
||||
|
||||
} else {
|
||||
let res = ty.super_fold_with(self);
|
||||
assert!(self.cache.insert(ty, res).is_none());
|
||||
res
|
||||
}
|
||||
_ => ty,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user