@@ -741,39 +741,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
741
741
if reached_depth >= stack. depth {
742
742
debug ! ( ?result, "CACHE MISS" ) ;
743
743
self . insert_evaluation_cache ( param_env, fresh_trait_pred, dep_node, result) ;
744
-
745
- stack. cache ( ) . on_completion (
746
- stack. dfn ,
747
- |fresh_trait_pred, provisional_result, provisional_dep_node| {
748
- // Create a new `DepNode` that has dependencies on:
749
- // * The `DepNode` for the original evaluation that resulted in a provisional cache
750
- // entry being crated
751
- // * The `DepNode` for the *current* evaluation, which resulted in us completing
752
- // provisional caches entries and inserting them into the evaluation cache
753
- //
754
- // This ensures that when a query reads this entry from the evaluation cache,
755
- // it will end up (transitively) depending on all of the incr-comp dependencies
756
- // created during the evaluation of this trait. For example, evaluating a trait
757
- // will usually require us to invoke `type_of(field_def_id)` to determine the
758
- // constituent types, and we want any queries reading from this evaluation
759
- // cache entry to end up with a transitive `type_of(field_def_id`)` dependency.
760
- //
761
- // By using `in_task`, we're also creating an edge from the *current* query
762
- // to the newly-created `combined_dep_node`. This is probably redundant,
763
- // but it's better to add too many dep graph edges than to add too few
764
- // dep graph edges.
765
- let ( ( ) , combined_dep_node) = self . in_task ( |this| {
766
- this. tcx ( ) . dep_graph . read_index ( provisional_dep_node) ;
767
- this. tcx ( ) . dep_graph . read_index ( dep_node) ;
768
- } ) ;
769
- self . insert_evaluation_cache (
770
- param_env,
771
- fresh_trait_pred,
772
- combined_dep_node,
773
- provisional_result. max ( result) ,
774
- ) ;
775
- } ,
776
- ) ;
744
+ stack. cache ( ) . on_completion ( stack. dfn ) ;
777
745
} else {
778
746
debug ! ( ?result, "PROVISIONAL" ) ;
779
747
debug ! (
@@ -782,13 +750,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
782
750
fresh_trait_pred, stack. depth, reached_depth,
783
751
) ;
784
752
785
- stack. cache ( ) . insert_provisional (
786
- stack. dfn ,
787
- reached_depth,
788
- fresh_trait_pred,
789
- result,
790
- dep_node,
791
- ) ;
753
+ stack. cache ( ) . insert_provisional ( stack. dfn , reached_depth, fresh_trait_pred, result) ;
792
754
}
793
755
794
756
Ok ( result)
@@ -2531,11 +2493,6 @@ struct ProvisionalEvaluation {
2531
2493
from_dfn : usize ,
2532
2494
reached_depth : usize ,
2533
2495
result : EvaluationResult ,
2534
- /// The `DepNodeIndex` created for the `evaluate_stack` call for this provisional
2535
- /// evaluation. When we create an entry in the evaluation cache using this provisional
2536
- /// cache entry (see `on_completion`), we use this `dep_node` to ensure that future reads from
2537
- /// the cache will have all of the necessary incr comp dependencies tracked.
2538
- dep_node : DepNodeIndex ,
2539
2496
}
2540
2497
2541
2498
impl < ' tcx > Default for ProvisionalEvaluationCache < ' tcx > {
@@ -2578,7 +2535,6 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> {
2578
2535
reached_depth : usize ,
2579
2536
fresh_trait_pred : ty:: PolyTraitPredicate < ' tcx > ,
2580
2537
result : EvaluationResult ,
2581
- dep_node : DepNodeIndex ,
2582
2538
) {
2583
2539
debug ! ( ?from_dfn, ?fresh_trait_pred, ?result, "insert_provisional" ) ;
2584
2540
@@ -2604,10 +2560,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> {
2604
2560
}
2605
2561
}
2606
2562
2607
- map. insert (
2608
- fresh_trait_pred,
2609
- ProvisionalEvaluation { from_dfn, reached_depth, result, dep_node } ,
2610
- ) ;
2563
+ map. insert ( fresh_trait_pred, ProvisionalEvaluation { from_dfn, reached_depth, result } ) ;
2611
2564
}
2612
2565
2613
2566
/// Invoked when the node with dfn `dfn` does not get a successful
@@ -2633,8 +2586,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> {
2633
2586
/// Invoked when the node at depth `depth` completed without
2634
2587
/// depending on anything higher in the stack (if that completion
2635
2588
/// was a failure, then `on_failure` should have been invoked
2636
- /// already). The callback `op` will be invoked for each
2637
- /// provisional entry that we can now confirm.
2589
+ /// already).
2638
2590
///
2639
2591
/// Note that we may still have provisional cache items remaining
2640
2592
/// in the cache when this is done. For example, if there is a
@@ -2655,19 +2607,26 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> {
2655
2607
/// would be 2, representing the C node, and hence we would
2656
2608
/// remove the result for D, which has DFN 3, but not the results for
2657
2609
/// A and B, which have DFNs 0 and 1 respectively).
2658
- fn on_completion (
2659
- & self ,
2660
- dfn : usize ,
2661
- mut op : impl FnMut ( ty:: PolyTraitPredicate < ' tcx > , EvaluationResult , DepNodeIndex ) ,
2662
- ) {
2610
+ ///
2611
+ /// Note that we *do not* attempt to cache these cycle participants
2612
+ /// in the evaluation cache. Doing so would require carefully computing
2613
+ /// the correct `DepNode` to store in the cache entry:
2614
+ /// cycle participants may implicitly depend on query results
2615
+ /// related to other participants in the cycle, due to our logic
2616
+ /// which examines the evaluation stack.
2617
+ ///
2618
+ /// We used to try to perform this caching,
2619
+ /// but it lead to multiple incremental compilation ICEs
2620
+ /// (see #92987 and #96319), and was very hard to understand.
2621
+ /// Fortunately, removing the caching didn't seem to
2622
+ /// have a performance impact in practice.
2623
+ fn on_completion ( & self , dfn : usize ) {
2663
2624
debug ! ( ?dfn, "on_completion" ) ;
2664
2625
2665
2626
for ( fresh_trait_pred, eval) in
2666
2627
self . map . borrow_mut ( ) . drain_filter ( |_k, eval| eval. from_dfn >= dfn)
2667
2628
{
2668
2629
debug ! ( ?fresh_trait_pred, ?eval, "on_completion" ) ;
2669
-
2670
- op ( fresh_trait_pred, eval. result , eval. dep_node ) ;
2671
2630
}
2672
2631
}
2673
2632
}
0 commit comments