Skip to content

Commit 66f8dd1

Browse files
committedApr 8, 2023
Auto merge of rust-lang#110069 - ndrewxie:issue-104212-fix, r=cjgillot
Switched provisional evaluation cache map to FxIndexMap, and replaced map.drain_filter with map.retain Switching ProvisionalEvaluationCache's map field from FxHashMap to FxIndexMap was previously blocked because doing so caused performance regressions that could be mitigated by the stabilization of drain_filter for FxIndexMap (rust-lang#104212). However, the only use of drain_filter can be replaced with a retain, so I made the modification and put in a PR to see if this causes a performance regression as well. This PR is part of a broader effort (rust-lang#84447) of removing iteration through FxHashMaps, as the iteration order is unstable and can cause issues in incremental compilation.
2 parents 9e124c4 + 9920bab commit 66f8dd1

File tree

1 file changed

+9
-15
lines changed
  • compiler/rustc_trait_selection/src/traits/select

1 file changed

+9
-15
lines changed
 

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

+9-15
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@
22
//!
33
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html#selection
44
5-
// FIXME: The `map` field in ProvisionalEvaluationCache should be changed to
6-
// a `FxIndexMap` to avoid query instability, but right now it causes a perf regression. This would be
7-
// fixed or at least lightened by the addition of the `drain_filter` method to `FxIndexMap`
8-
// Relevant: https://github.com/rust-lang/rust/pull/103723 and https://github.com/bluss/indexmap/issues/242
9-
#![allow(rustc::potential_query_instability)]
10-
115
use self::EvaluationResult::*;
126
use self::SelectionCandidate::*;
137

@@ -32,8 +26,7 @@ use crate::traits::project::ProjectAndUnifyResult;
3226
use crate::traits::project::ProjectionCacheKeyExt;
3327
use crate::traits::ProjectionCacheKey;
3428
use crate::traits::Unimplemented;
35-
use rustc_data_structures::fx::FxHashMap;
36-
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
29+
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
3730
use rustc_data_structures::stack::ensure_sufficient_stack;
3831
use rustc_errors::Diagnostic;
3932
use rustc_hir as hir;
@@ -2782,7 +2775,7 @@ struct ProvisionalEvaluationCache<'tcx> {
27822775
/// - then we determine that `E` is in error -- we will then clear
27832776
/// all cache values whose DFN is >= 4 -- in this case, that
27842777
/// means the cached value for `F`.
2785-
map: RefCell<FxHashMap<ty::PolyTraitPredicate<'tcx>, ProvisionalEvaluation>>,
2778+
map: RefCell<FxIndexMap<ty::PolyTraitPredicate<'tcx>, ProvisionalEvaluation>>,
27862779

27872780
/// The stack of args that we assume to be true because a `WF(arg)` predicate
27882781
/// is on the stack above (and because of wellformedness is coinductive).
@@ -2930,12 +2923,13 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> {
29302923
/// have a performance impact in practice.
29312924
fn on_completion(&self, dfn: usize) {
29322925
debug!(?dfn, "on_completion");
2933-
2934-
for (fresh_trait_pred, eval) in
2935-
self.map.borrow_mut().drain_filter(|_k, eval| eval.from_dfn >= dfn)
2936-
{
2937-
debug!(?fresh_trait_pred, ?eval, "on_completion");
2938-
}
2926+
self.map.borrow_mut().retain(|fresh_trait_pred, eval| {
2927+
if eval.from_dfn >= dfn {
2928+
debug!(?fresh_trait_pred, ?eval, "on_completion");
2929+
return false;
2930+
}
2931+
true
2932+
});
29392933
}
29402934
}
29412935

0 commit comments

Comments
 (0)
Please sign in to comment.