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-
115use self :: EvaluationResult :: * ;
126use self :: SelectionCandidate :: * ;
137
@@ -32,8 +26,7 @@ use crate::traits::project::ProjectAndUnifyResult;
3226use crate :: traits:: project:: ProjectionCacheKeyExt ;
3327use crate :: traits:: ProjectionCacheKey ;
3428use 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 } ;
3730use rustc_data_structures:: stack:: ensure_sufficient_stack;
3831use rustc_errors:: Diagnostic ;
3932use 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