]> git.lizzy.rs Git - rust.git/commitdiff
correctly update goals in the cache
authorlcnr <rust@lcnr.de>
Wed, 8 Feb 2023 12:50:27 +0000 (13:50 +0100)
committerlcnr <rust@lcnr.de>
Wed, 8 Feb 2023 18:11:14 +0000 (19:11 +0100)
compiler/rustc_trait_selection/src/solve/search_graph/mod.rs

index 7514c7ee55170482df63a66136f376b39492629f..a2ca4bc189c87faae28f66fa694633ab1ade0125 100644 (file)
@@ -7,7 +7,7 @@
 use overflow::OverflowData;
 use rustc_index::vec::IndexVec;
 use rustc_middle::ty::TyCtxt;
-use std::collections::hash_map::Entry;
+use std::{collections::hash_map::Entry, mem};
 
 rustc_index::newtype_index! {
     pub struct StackDepth {}
@@ -134,12 +134,15 @@ pub(super) fn try_finalize_goal(
         let provisional_entry_index = *cache.lookup_table.get(&goal).unwrap();
         let provisional_entry = &mut cache.entries[provisional_entry_index];
         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
         // different from the final one.
-        if has_been_used && provisional_entry.response != response {
-            // If so, update the provisional reponse for this goal...
-            provisional_entry.response = response;
-            // ...remove all entries whose result depends on this goal
+        if has_been_used && prev_response != response {
+            // If so, remove all entries whose result depends on this goal
             // from the provisional cache...
             //
             // That's not completely correct, as a nested goal can also