@@ -785,14 +785,11 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
785
785
fn clear_dependent_provisional_results (
786
786
stack : & Stack < X > ,
787
787
provisional_cache : & mut HashMap < X :: Input , Vec < ProvisionalCacheEntry < X > > > ,
788
- mut handle_removed_entry : impl FnMut ( X :: Input , ProvisionalCacheEntry < X > ) ,
789
788
) {
790
789
let head = stack. next_index ( ) ;
791
790
#[ allow( rustc:: potential_query_instability) ]
792
- provisional_cache. retain ( |& input, entries| {
793
- for e in entries. extract_if ( .., |entry| entry. heads . highest_cycle_head ( ) == head) {
794
- handle_removed_entry ( input, e)
795
- }
791
+ provisional_cache. retain ( |_, entries| {
792
+ entries. retain ( |entry| entry. heads . highest_cycle_head ( ) != head) ;
796
793
!entries. is_empty ( )
797
794
} ) ;
798
795
}
@@ -1171,6 +1168,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1171
1168
& stack_entry,
1172
1169
|_, result| result,
1173
1170
) ;
1171
+ self . tree . set_rebase_kind ( stack_entry. node_id , tree:: RebaseEntriesKind :: Normal ) ;
1174
1172
return EvaluationResult :: finalize ( stack_entry, encountered_overflow, result) ;
1175
1173
}
1176
1174
@@ -1195,6 +1193,8 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1195
1193
& stack_entry,
1196
1194
|input, _| D :: propagate_ambiguity ( cx, input, result) ,
1197
1195
) ;
1196
+
1197
+ self . tree . set_rebase_kind ( stack_entry. node_id , tree:: RebaseEntriesKind :: Ambiguity ) ;
1198
1198
return EvaluationResult :: finalize ( stack_entry, encountered_overflow, result) ;
1199
1199
} ;
1200
1200
@@ -1210,6 +1210,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1210
1210
& stack_entry,
1211
1211
|input, _| D :: on_fixpoint_overflow ( cx, input) ,
1212
1212
) ;
1213
+ self . tree . set_rebase_kind ( stack_entry. node_id , tree:: RebaseEntriesKind :: Overflow ) ;
1213
1214
return EvaluationResult :: finalize ( stack_entry, encountered_overflow, result) ;
1214
1215
}
1215
1216
@@ -1223,6 +1224,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1223
1224
& new_stack_entry,
1224
1225
|_, result| result,
1225
1226
) ;
1227
+ self . tree . set_rebase_kind ( new_stack_entry. node_id , tree:: RebaseEntriesKind :: Normal ) ;
1226
1228
return EvaluationResult :: finalize (
1227
1229
new_stack_entry,
1228
1230
encountered_overflow,
@@ -1247,20 +1249,9 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1247
1249
) -> ( StackEntry < X > , X :: Result ) {
1248
1250
let node_id = prev_stack_entry. node_id ;
1249
1251
let current_depth = self . stack . next_index ( ) ;
1250
-
1251
- let mut removed_entries = BTreeMap :: new ( ) ;
1252
1252
// Clear all provisional cache entries which depend on a previous provisional
1253
1253
// result of this goal and rerun.
1254
- Self :: clear_dependent_provisional_results (
1255
- & self . stack ,
1256
- & mut self . provisional_cache ,
1257
- |input, entry| {
1258
- let prev = removed_entries. insert ( entry. entry_node_id , ( input, entry) ) ;
1259
- if let Some ( prev) = prev {
1260
- unreachable ! ( "duplicate entries for the same `NodeId`: {prev:?}" ) ;
1261
- }
1262
- } ,
1263
- ) ;
1254
+ Self :: clear_dependent_provisional_results ( & self . stack , & mut self . provisional_cache ) ;
1264
1255
self . stack . push ( StackEntry {
1265
1256
node_id,
1266
1257
input : prev_stack_entry. input ,
@@ -1280,13 +1271,58 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1280
1271
return ( reeval_entry, result) ;
1281
1272
}
1282
1273
1283
- let truncate_stack = |stack : & mut Stack < X > , provisional_cache : & mut _ , depth| {
1274
+ let truncate_unchanged_stack = |stack : & mut Stack < X > ,
1275
+ provisional_cache : & mut _ ,
1276
+ tree : & SearchTree < X > ,
1277
+ depth| {
1284
1278
while stack. next_index ( ) > depth {
1285
- let reeval_entry = stack. pop ( ) ;
1286
- // TODO: How can we tell whether this entry was the final revision.
1287
- //
1288
- // We should be able to rebase provisional entries in most cases.
1289
- Self :: clear_dependent_provisional_results ( stack, provisional_cache, |_, _| ( ) ) ;
1279
+ let mut reeval_entry = stack. pop ( ) ;
1280
+ let & tree:: NodeKind :: Finished {
1281
+ encountered_overflow,
1282
+ ref heads,
1283
+ last_iteration_provisional_result,
1284
+ rebase_entries_kind,
1285
+ result,
1286
+ } = tree. node_kind_raw ( reeval_entry. node_id )
1287
+ else {
1288
+ unreachable ! ( ) ;
1289
+ } ;
1290
+ if last_iteration_provisional_result == reeval_entry. provisional_result {
1291
+ reeval_entry. heads = heads. clone ( ) ;
1292
+ match rebase_entries_kind {
1293
+ Some ( tree:: RebaseEntriesKind :: Normal ) => {
1294
+ debug ! ( ?reeval_entry. input, "rebase entries while truncating stack" ) ;
1295
+ Self :: rebase_provisional_cache_entries (
1296
+ stack,
1297
+ provisional_cache,
1298
+ & reeval_entry,
1299
+ |_, result| result,
1300
+ )
1301
+ }
1302
+ Some ( tree:: RebaseEntriesKind :: Ambiguity ) => {
1303
+ Self :: rebase_provisional_cache_entries (
1304
+ stack,
1305
+ provisional_cache,
1306
+ & reeval_entry,
1307
+ |input, result| D :: propagate_ambiguity ( cx, input, result) ,
1308
+ )
1309
+ }
1310
+ Some ( tree:: RebaseEntriesKind :: Overflow ) => {
1311
+ Self :: rebase_provisional_cache_entries (
1312
+ stack,
1313
+ provisional_cache,
1314
+ & reeval_entry,
1315
+ |input, _| D :: on_fixpoint_overflow ( cx, input) ,
1316
+ )
1317
+ }
1318
+ None | _ => {
1319
+ Self :: clear_dependent_provisional_results ( stack, provisional_cache)
1320
+ }
1321
+ }
1322
+ } else {
1323
+ Self :: clear_dependent_provisional_results ( stack, provisional_cache) ;
1324
+ }
1325
+
1290
1326
Self :: update_parent_goal (
1291
1327
stack,
1292
1328
reeval_entry. step_kind_from_parent ,
@@ -1295,10 +1331,39 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1295
1331
reeval_entry. encountered_overflow ,
1296
1332
UpdateParentGoalCtxt :: Ordinary ( & reeval_entry. nested_goals ) ,
1297
1333
) ;
1334
+ let entry = provisional_cache. entry ( reeval_entry. input ) . or_default ( ) ;
1335
+
1336
+ for ( head, path_to_nested) in heads. iter ( ) {
1337
+ let path_from_head =
1338
+ Self :: cycle_path_kind ( & stack, reeval_entry. step_kind_from_parent , head) ;
1339
+ for path_kind in path_to_nested. extend_with ( path_from_head) . iter_paths ( ) {
1340
+ let usage_kind = UsageKind :: Single ( path_kind) ;
1341
+ stack[ head] . has_been_used = Some (
1342
+ stack[ head]
1343
+ . has_been_used
1344
+ . map_or ( usage_kind, |prev| prev. merge ( usage_kind) ) ,
1345
+ ) ;
1346
+ }
1347
+ }
1348
+ let path_from_head = Self :: cycle_path_kind (
1349
+ & stack,
1350
+ reeval_entry. step_kind_from_parent ,
1351
+ heads. highest_cycle_head ( ) ,
1352
+ ) ;
1353
+ let provisional_cache_entry = ProvisionalCacheEntry {
1354
+ entry_node_id : reeval_entry. node_id ,
1355
+ encountered_overflow,
1356
+ heads : heads. clone ( ) ,
1357
+ path_from_head,
1358
+ result,
1359
+ } ;
1360
+ debug ! ( ?provisional_cache_entry) ;
1361
+ entry. push ( provisional_cache_entry) ;
1298
1362
}
1299
1363
} ;
1300
1364
1301
- let cycles = self . tree . rerun_get_and_reset_cycles ( prev_stack_entry. node_id ) ;
1365
+ let cycles =
1366
+ self . tree . rerun_get_and_reset_cycles ( prev_stack_entry. node_id , provisional_result) ;
1302
1367
let current_stack_len = self . stack . len ( ) ;
1303
1368
let mut was_reevaluated = HashSet :: default ( ) ;
1304
1369
' outer: for cycle in cycles {
@@ -1364,9 +1429,10 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1364
1429
) ;
1365
1430
let _ = added_goals. next ( ) . unwrap ( ) ;
1366
1431
} else {
1367
- truncate_stack (
1432
+ truncate_unchanged_stack (
1368
1433
& mut self . stack ,
1369
1434
& mut self . provisional_cache ,
1435
+ & self . tree ,
1370
1436
stack_depth,
1371
1437
) ;
1372
1438
break ;
@@ -1381,7 +1447,12 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1381
1447
}
1382
1448
}
1383
1449
( None , Some ( _) ) => {
1384
- truncate_stack ( & mut self . stack , & mut self . provisional_cache , stack_depth) ;
1450
+ truncate_unchanged_stack (
1451
+ & mut self . stack ,
1452
+ & mut self . provisional_cache ,
1453
+ & self . tree ,
1454
+ stack_depth,
1455
+ ) ;
1385
1456
break ;
1386
1457
}
1387
1458
( None , None ) => break ,
@@ -1406,18 +1477,6 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1406
1477
} ) ;
1407
1478
}
1408
1479
1409
- /*
1410
- while let Some((&entry_node_id, _)) = removed_entries.first_key_value() {
1411
- if entry_node_id < current_goal.0
1412
- && self.stack.iter().all(|e| e.node_id != entry_node_id)
1413
- {
1414
- let (entry_node_id, (input, entry)) = removed_entries.pop_first().unwrap();
1415
- if !self.tree.goal_or_parent_has_changed(node_id, &has_changed, entry_node_id) {
1416
- self.provisional_cache.entry(input).or_default().push(entry);
1417
- }
1418
- }
1419
- }*/
1420
-
1421
1480
loop {
1422
1481
let span = tracing:: debug_span!(
1423
1482
"reevaluate_canonical_goal" ,
@@ -1443,7 +1502,6 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1443
1502
Self :: clear_dependent_provisional_results (
1444
1503
& self . stack ,
1445
1504
& mut self . provisional_cache ,
1446
- |_, _| ( ) ,
1447
1505
) ;
1448
1506
Self :: update_parent_goal (
1449
1507
& mut self . stack ,
@@ -1475,18 +1533,13 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
1475
1533
return ( reeval_entry, result) ;
1476
1534
}
1477
1535
1478
- truncate_stack (
1536
+ truncate_unchanged_stack (
1479
1537
& mut self . stack ,
1480
1538
& mut self . provisional_cache ,
1539
+ & self . tree ,
1481
1540
StackDepth :: from_usize ( current_stack_len) ,
1482
1541
) ;
1483
1542
1484
- for ( entry_node_id, ( input, entry) ) in removed_entries {
1485
- if !self . tree . goal_or_parent_was_reevaluated ( node_id, & was_reevaluated, entry_node_id) {
1486
- self . provisional_cache . entry ( input) . or_default ( ) . push ( entry) ;
1487
- }
1488
- }
1489
-
1490
1543
debug_assert_eq ! ( self . stack. len( ) , current_stack_len) ;
1491
1544
let reeval_entry = self . stack . pop ( ) ;
1492
1545
( reeval_entry, provisional_result)
0 commit comments