Layout-cache variable invalidation must compare by root keys

After unification, variable roots can change. So, when we invalidate
entries in the layout cache, we must compare for variable equivalence
relative to the current state of subs.
This commit is contained in:
Ayaz Hafiz 2023-01-30 13:06:44 -06:00
parent 8afdc820a6
commit 1e22a2bbcd
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
2 changed files with 10 additions and 4 deletions

View file

@ -1479,7 +1479,7 @@ impl<'a, 'i> Env<'a, 'i> {
right,
)?;
layout_cache.invalidate(changed_variables.iter().copied());
layout_cache.invalidate(self.subs, changed_variables.iter().copied());
external_specializations
.into_iter()
.for_each(|e| e.invalidate_cache(&changed_variables));

View file

@ -300,14 +300,20 @@ impl<'a> LayoutCache<'a> {
/// Invalidates the list of given root variables.
/// Usually called after unification, when merged variables with changed contents need to be
/// invalidated.
pub fn invalidate(&mut self, vars: impl IntoIterator<Item = Variable>) {
pub fn invalidate(&mut self, subs: &Subs, vars: impl IntoIterator<Item = Variable>) {
// TODO(layout-cache): optimize me somehow
for var in vars.into_iter() {
let var = subs.get_root_key_without_compacting(var);
for layer in self.cache.iter_mut().rev() {
layer.0.remove(&var);
layer
.0
.retain(|k, _| !subs.equivalent_without_compacting(var, *k));
roc_tracing::debug!(?var, "invalidating cached layout");
}
for layer in self.raw_function_cache.iter_mut().rev() {
layer.0.remove(&var);
layer
.0
.retain(|k, _| !subs.equivalent_without_compacting(var, *k));
roc_tracing::debug!(?var, "invalidating cached layout");
}
}