@@ -21,7 +21,7 @@ use std::marker::PhantomData;
21
21
use derive_where:: derive_where;
22
22
#[ cfg( feature = "nightly" ) ]
23
23
use rustc_macros:: { Decodable_NoContext , Encodable_NoContext , HashStable_NoContext } ;
24
- use rustc_type_ir:: data_structures:: HashMap ;
24
+ use rustc_type_ir:: data_structures:: { HashMap , HashSet } ;
25
25
use tracing:: { debug, instrument} ;
26
26
27
27
mod stack;
@@ -1113,7 +1113,6 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1113
1113
1114
1114
/// Whether we've reached a fixpoint when evaluating a cycle head.
1115
1115
fn reached_fixpoint (
1116
- & mut self ,
1117
1116
cx : X ,
1118
1117
stack_entry : & StackEntry < X > ,
1119
1118
usage_kind : UsageKind ,
@@ -1161,7 +1160,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1161
1160
// is equal to the provisional result of the previous iteration, or because
1162
1161
// this was only the root of either coinductive or inductive cycles, and the
1163
1162
// final result is equal to the initial response for that case.
1164
- if self . reached_fixpoint ( cx, & stack_entry, usage_kind, result) {
1163
+ if Self :: reached_fixpoint ( cx, & stack_entry, usage_kind, result) {
1165
1164
Self :: rebase_provisional_cache_entries (
1166
1165
& self . stack ,
1167
1166
& mut self . provisional_cache ,
@@ -1270,7 +1269,9 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1270
1269
let truncate_stack = |stack : & mut Stack < X > , provisional_cache : & mut _ , depth| {
1271
1270
while stack. next_index ( ) > depth {
1272
1271
let reeval_entry = stack. pop ( ) ;
1273
- // TODO
1272
+ // TODO: How can we tell whether this entry was the final revision.
1273
+ //
1274
+ // We should be able to rebase provisional entries in most cases.
1274
1275
Self :: clear_dependent_provisional_results ( stack, provisional_cache) ;
1275
1276
Self :: update_parent_goal (
1276
1277
stack,
@@ -1286,6 +1287,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1286
1287
let cycles = self . tree . rerun_get_and_reset_cycles ( prev_stack_entry. node_id ) ;
1287
1288
let current_stack_len = self . stack . len ( ) ;
1288
1289
let mut first_cycle = true ;
1290
+ let mut has_changed = HashSet :: default ( ) ;
1289
1291
' outer: for cycle in cycles {
1290
1292
let & tree:: Cycle { node_id : cycle_node_id, ref provisional_results } =
1291
1293
self . tree . get_cycle ( cycle) ;
@@ -1310,6 +1312,13 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1310
1312
if !self . tree . get_heads ( entry_node_id) . contains_stack_entry ( current_depth) {
1311
1313
continue ;
1312
1314
}
1315
+
1316
+ // We've evaluated the `entry_node_id` before evaluating this goal. In case
1317
+ // that node and its parents has not changed, we can reinsert the cache entry
1318
+ // before starting to reevaluate it.
1319
+ if !self . tree . goal_or_parent_has_changed ( node_id, & has_changed, entry_node_id) {
1320
+ continue ;
1321
+ }
1313
1322
}
1314
1323
} ;
1315
1324
@@ -1345,8 +1354,6 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1345
1354
while let Some ( & ( stack_depth, node_id, info) ) = added_goals. peek ( ) {
1346
1355
if let Some ( existing_entry) = self . stack . get ( stack_depth) {
1347
1356
let provisional_result = provisional_results. get ( & stack_depth) . copied ( ) ;
1348
- // Issue: changing the provisional result means we must not rebase, but instead
1349
- // invalidate.
1350
1357
if existing_entry. node_id == node_id
1351
1358
&& provisional_result == existing_entry. provisional_result
1352
1359
{
@@ -1410,10 +1417,10 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1410
1417
debug ! ( input = ?current_goal. 1 . input, ?result, "goal did not change" ) ;
1411
1418
continue ' outer;
1412
1419
} else {
1420
+ has_changed. insert ( current_goal. 0 ) ;
1413
1421
debug ! ( input = ?current_goal. 1 . input, ?result, "goal did change" ) ;
1414
1422
if self . stack . len ( ) > current_stack_len {
1415
1423
let parent = self . stack . pop ( ) ;
1416
- // TODO
1417
1424
Self :: clear_dependent_provisional_results (
1418
1425
& self . stack ,
1419
1426
& mut self . provisional_cache ,
0 commit comments