mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +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`.
|
/// Enforce that `a` is equal to or a subtype of `b`.
|
||||||
pub struct TypeRelating<'combine, 'a, 'tcx> {
|
pub struct TypeRelating<'combine, 'a, 'tcx> {
|
||||||
// Partially mutable.
|
// Immutable except for the `InferCtxt` and the
|
||||||
|
// resulting nested `goals`.
|
||||||
fields: &'combine mut CombineFields<'a, 'tcx>,
|
fields: &'combine mut CombineFields<'a, 'tcx>,
|
||||||
|
|
||||||
// Immutable fields.
|
// Immutable field.
|
||||||
structurally_relate_aliases: StructurallyRelateAliases,
|
structurally_relate_aliases: StructurallyRelateAliases,
|
||||||
|
// Mutable field.
|
||||||
ambient_variance: ty::Variance,
|
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
|
/// only field which is mutable and which meaningfully changes
|
||||||
/// the result when relating types.
|
/// the result when relating types.
|
||||||
///
|
///
|
||||||
|
@ -210,16 +210,17 @@ where
|
|||||||
debug_assert!(!ty.has_vars_bound_above(ty::INNERMOST));
|
debug_assert!(!ty.has_vars_bound_above(ty::INNERMOST));
|
||||||
ty::fold::shift_vars(self.tcx, ty, self.current_index.as_u32())
|
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)) {
|
if !t.has_vars_bound_at_or_above(self.current_index) {
|
||||||
return ty;
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
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> {
|
pub struct Canonicalizer<'a, D: SolverDelegate<Interner = I>, I: Interner> {
|
||||||
delegate: &'a D,
|
delegate: &'a D,
|
||||||
|
|
||||||
|
// Immutable field.
|
||||||
canonicalize_mode: CanonicalizeMode,
|
canonicalize_mode: CanonicalizeMode,
|
||||||
|
|
||||||
|
// Mutable fields.
|
||||||
variables: &'a mut Vec<I::GenericArg>,
|
variables: &'a mut Vec<I::GenericArg>,
|
||||||
variable_lookup_table: HashMap<I::GenericArg, usize>,
|
|
||||||
|
|
||||||
primitive_var_infos: Vec<CanonicalVarInfo<I>>,
|
primitive_var_infos: Vec<CanonicalVarInfo<I>>,
|
||||||
|
variable_lookup_table: HashMap<I::GenericArg, usize>,
|
||||||
binder_index: ty::DebruijnIndex,
|
binder_index: ty::DebruijnIndex,
|
||||||
|
|
||||||
/// We only use the debruijn index during lookup as all other fields
|
/// We only use the debruijn index during lookup. We don't need to
|
||||||
/// should not be impacted by whether a type is folded once or multiple
|
/// track the `variables` as each generic arg only results in a single
|
||||||
/// times.
|
/// bound variable regardless of how many times it is encountered.
|
||||||
cache: HashMap<(ty::DebruijnIndex, I::Ty), I::Ty>,
|
cache: HashMap<(ty::DebruijnIndex, I::Ty), I::Ty>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@ where
|
|||||||
I: Interner,
|
I: Interner,
|
||||||
{
|
{
|
||||||
delegate: &'a D,
|
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>,
|
cache: DelayedMap<I::Ty, I::Ty>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1057,16 +1057,17 @@ where
|
|||||||
);
|
);
|
||||||
infer_ty
|
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;
|
return entry;
|
||||||
|
} else {
|
||||||
|
let res = ty.super_fold_with(self);
|
||||||
|
assert!(self.cache.insert(ty, res).is_none());
|
||||||
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
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