1
Fork 0

correctly update goals in the cache

This commit is contained in:
lcnr 2023-02-08 13:50:27 +01:00
parent 6eb9f2dd67
commit a5164605bc

View file

@ -7,7 +7,7 @@ use cache::ProvisionalCache;
use overflow::OverflowData; use overflow::OverflowData;
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use std::collections::hash_map::Entry; use std::{collections::hash_map::Entry, mem};
rustc_index::newtype_index! { rustc_index::newtype_index! {
pub struct StackDepth {} pub struct StackDepth {}
@ -134,12 +134,15 @@ impl<'tcx> SearchGraph<'tcx> {
let provisional_entry_index = *cache.lookup_table.get(&goal).unwrap(); let provisional_entry_index = *cache.lookup_table.get(&goal).unwrap();
let provisional_entry = &mut cache.entries[provisional_entry_index]; let provisional_entry = &mut cache.entries[provisional_entry_index];
let depth = provisional_entry.depth; let depth = provisional_entry.depth;
// We eagerly update the response in the cache here. If we have to reevaluate
// this goal we use the new response when hitting a cycle, and we definitely
// want to access the final response whenever we look at the cache.
let prev_response = mem::replace(&mut provisional_entry.response, response);
// Was the current goal the root of a cycle and was the provisional response // Was the current goal the root of a cycle and was the provisional response
// different from the final one. // different from the final one.
if has_been_used && provisional_entry.response != response { if has_been_used && prev_response != response {
// If so, update the provisional reponse for this goal... // If so, remove all entries whose result depends on this goal
provisional_entry.response = response;
// ...remove all entries whose result depends on this goal
// from the provisional cache... // from the provisional cache...
// //
// That's not completely correct, as a nested goal can also // That's not completely correct, as a nested goal can also