Skip to content

Commit 4799baa

Browse files
committed
Auto merge of rust-lang#96458 - Aaron1011:no-cycle-caching, r=jackh726,cjgillot
Don't cache results of coinductive cycle
2 parents 77652b9 + 40c6d83 commit 4799baa

File tree

1 file changed

+18
-59
lines changed
  • compiler/rustc_trait_selection/src/traits/select

1 file changed

+18
-59
lines changed

compiler/rustc_trait_selection/src/traits/select/mod.rs

+18-59
Original file line numberDiff line numberDiff line change
@@ -741,39 +741,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
741741
if reached_depth >= stack.depth {
742742
debug!(?result, "CACHE MISS");
743743
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);
777745
} else {
778746
debug!(?result, "PROVISIONAL");
779747
debug!(
@@ -782,13 +750,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
782750
fresh_trait_pred, stack.depth, reached_depth,
783751
);
784752

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);
792754
}
793755

794756
Ok(result)
@@ -2531,11 +2493,6 @@ struct ProvisionalEvaluation {
25312493
from_dfn: usize,
25322494
reached_depth: usize,
25332495
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,
25392496
}
25402497

25412498
impl<'tcx> Default for ProvisionalEvaluationCache<'tcx> {
@@ -2578,7 +2535,6 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> {
25782535
reached_depth: usize,
25792536
fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
25802537
result: EvaluationResult,
2581-
dep_node: DepNodeIndex,
25822538
) {
25832539
debug!(?from_dfn, ?fresh_trait_pred, ?result, "insert_provisional");
25842540

@@ -2604,10 +2560,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> {
26042560
}
26052561
}
26062562

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 });
26112564
}
26122565

26132566
/// Invoked when the node with dfn `dfn` does not get a successful
@@ -2633,8 +2586,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> {
26332586
/// Invoked when the node at depth `depth` completed without
26342587
/// depending on anything higher in the stack (if that completion
26352588
/// 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).
26382590
///
26392591
/// Note that we may still have provisional cache items remaining
26402592
/// in the cache when this is done. For example, if there is a
@@ -2655,19 +2607,26 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> {
26552607
/// would be 2, representing the C node, and hence we would
26562608
/// remove the result for D, which has DFN 3, but not the results for
26572609
/// 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) {
26632624
debug!(?dfn, "on_completion");
26642625

26652626
for (fresh_trait_pred, eval) in
26662627
self.map.borrow_mut().drain_filter(|_k, eval| eval.from_dfn >= dfn)
26672628
{
26682629
debug!(?fresh_trait_pred, ?eval, "on_completion");
2669-
2670-
op(fresh_trait_pred, eval.result, eval.dep_node);
26712630
}
26722631
}
26732632
}

0 commit comments

Comments
 (0)