Don't memoize seen types.
That cache is unlikely to be particularly useful within a single invocation of structurally_same_type, especially compared to memoizing results across _all_ invocations of that function.
This commit is contained in:
parent
bca48ad7ac
commit
6c57de1166
1 changed files with 9 additions and 51 deletions
|
|
@ -2153,62 +2153,22 @@ impl ClashingExternDeclarations {
|
|||
b: Ty<'tcx>,
|
||||
ckind: CItemKind,
|
||||
) -> bool {
|
||||
// In order to avoid endlessly recursing on recursive types, we maintain a "seen" set.
|
||||
// We'll need to store every combination of types we encounter anyway, so we also memoize
|
||||
// the result.
|
||||
struct SeenSet<'tcx>(FxHashMap<(Ty<'tcx>, Ty<'tcx>), Option<bool>>);
|
||||
|
||||
enum SeenSetResult {
|
||||
/// We've never seen this combination of types.
|
||||
Unseen,
|
||||
/// We've seen this combination of types, but are still computing the result.
|
||||
Computing,
|
||||
/// We've seen this combination of types, and have already computed the result.
|
||||
Computed(bool),
|
||||
}
|
||||
|
||||
impl<'tcx> SeenSet<'tcx> {
|
||||
fn new() -> Self {
|
||||
SeenSet(FxHashMap::default())
|
||||
}
|
||||
/// Mark (a, b) as `Computing`.
|
||||
fn mark_computing(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
|
||||
self.0.insert((a, b), None);
|
||||
}
|
||||
/// Mark (a, b) as `Computed(result)`.
|
||||
fn mark_computed(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, result: bool) {
|
||||
*self.0.get_mut(&(a, b)).expect("Missing prior call to mark_computing") =
|
||||
Some(result);
|
||||
}
|
||||
fn get(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> SeenSetResult {
|
||||
match self.0.get(&(a, b)) {
|
||||
None => SeenSetResult::Unseen,
|
||||
Some(None) => SeenSetResult::Computing,
|
||||
Some(Some(b)) => SeenSetResult::Computed(*b),
|
||||
}
|
||||
}
|
||||
}
|
||||
fn structurally_same_type_impl<'tcx>(
|
||||
seen_types: &mut SeenSet<'tcx>,
|
||||
seen_types: &mut FxHashSet<(Ty<'tcx>, Ty<'tcx>)>,
|
||||
cx: &LateContext<'tcx>,
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
ckind: CItemKind,
|
||||
) -> bool {
|
||||
debug!("structurally_same_type_impl(cx, a = {:?}, b = {:?})", a, b);
|
||||
match seen_types.get(a, b) {
|
||||
// If we've already computed the result, just return the memoized result.
|
||||
SeenSetResult::Computed(result) => return result,
|
||||
// We are already in the process of computing structural sameness for this type,
|
||||
// meaning we've found a cycle. The types are structurally same, then.
|
||||
SeenSetResult::Computing => return true,
|
||||
// We haven't seen this combination of types at all -- continue on to computing
|
||||
// their sameness.
|
||||
SeenSetResult::Unseen => (),
|
||||
if seen_types.contains(&(a, b)) {
|
||||
// We've encountered a cycle. There's no point going any further -- the types are
|
||||
// structurally the same.
|
||||
return true;
|
||||
}
|
||||
seen_types.mark_computing(a, b);
|
||||
seen_types.insert((a, b));
|
||||
let tcx = cx.tcx;
|
||||
let result = if a == b || rustc_middle::ty::TyS::same_type(a, b) {
|
||||
if a == b || rustc_middle::ty::TyS::same_type(a, b) {
|
||||
// All nominally-same types are structurally same, too.
|
||||
true
|
||||
} else {
|
||||
|
|
@ -2333,11 +2293,9 @@ impl ClashingExternDeclarations {
|
|||
// uninitialised memory.
|
||||
_ => compare_layouts(a, b),
|
||||
}
|
||||
};
|
||||
seen_types.mark_computed(a, b, result);
|
||||
result
|
||||
}
|
||||
}
|
||||
let mut seen_types = SeenSet::new();
|
||||
let mut seen_types = FxHashSet::default();
|
||||
structurally_same_type_impl(&mut seen_types, cx, a, b, ckind)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue