Skip to content

Commit 755ca4b

Browse files
committed
Reduce the scope of allow(rustc::potential_query_instability) in rustc_trait_selection
Make InferCtxtExt use a FxIndexMap This should be faster, because the map is only being used to iterate, which is supposed to be faster with the IndexMap Make the user_computed_preds use an IndexMap It is being used mostly for iteration, so the change shouldn't result in a perf hit Make the RegionDeps fields use an IndexMap This change could be a perf hit. Both `larger` and `smaller` are used for iteration, but they are also used for insertions. Make types_without_default_bounds use an IndexMap It uses extend, but it also iterates and removes items. Not sure if this will be a perf hit. Make InferTtxt.reported_trait_errors use an IndexMap This change brought a lot of other changes. The map seems to have been mostly used for iteration, so the performance shouldn't suffer. Add FIXME to change ProvisionalEvaluationCache.map to use an IndexMap Right now this results in a perf hit. IndexMap doesn't have the `drain_filter` API, so in `on_completion` we now need to iterate two times over the map.
1 parent ddfe1e8 commit 755ca4b

File tree

10 files changed

+37
-30
lines changed

10 files changed

+37
-30
lines changed

compiler/rustc_hir_analysis/src/check/compare_method.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::potentially_plural_count;
22
use crate::errors::LifetimesOrBoundsMismatchOnTrait;
33
use hir::def_id::{DefId, LocalDefId};
4-
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
4+
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
55
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed};
66
use rustc_hir as hir;
77
use rustc_hir::def::{DefKind, Res};
@@ -256,7 +256,7 @@ fn compare_predicate_entailment<'tcx>(
256256
// Compute placeholder form of impl and trait method tys.
257257
let tcx = infcx.tcx;
258258

259-
let mut wf_tys = FxHashSet::default();
259+
let mut wf_tys = FxIndexSet::default();
260260

261261
let impl_sig = infcx.replace_bound_vars_with_fresh_vars(
262262
impl_m_span,
@@ -479,7 +479,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
479479
let trait_sig = ocx.normalize(norm_cause.clone(), param_env, unnormalized_trait_sig);
480480
let trait_return_ty = trait_sig.output();
481481

482-
let wf_tys = FxHashSet::from_iter(
482+
let wf_tys = FxIndexSet::from_iter(
483483
unnormalized_trait_sig.inputs_and_output.iter().chain(trait_sig.inputs_and_output.iter()),
484484
);
485485

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
22
use hir::def::DefKind;
33
use rustc_ast as ast;
4-
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
4+
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
55
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
66
use rustc_hir as hir;
77
use rustc_hir::def_id::{DefId, LocalDefId};
@@ -412,7 +412,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
412412
.iter()
413413
.copied()
414414
.collect::<Vec<_>>(),
415-
&FxHashSet::default(),
415+
&FxIndexSet::default(),
416416
gat_def_id.def_id,
417417
gat_generics,
418418
)
@@ -462,10 +462,10 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
462462
.into_iter()
463463
.filter(|clause| match clause.kind().skip_binder() {
464464
ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => {
465-
!region_known_to_outlive(tcx, gat_hir, param_env, &FxHashSet::default(), a, b)
465+
!region_known_to_outlive(tcx, gat_hir, param_env, &FxIndexSet::default(), a, b)
466466
}
467467
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(a, b)) => {
468-
!ty_known_to_outlive(tcx, gat_hir, param_env, &FxHashSet::default(), a, b)
468+
!ty_known_to_outlive(tcx, gat_hir, param_env, &FxIndexSet::default(), a, b)
469469
}
470470
_ => bug!("Unexpected PredicateKind"),
471471
})
@@ -547,7 +547,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<'tcx>>(
547547
param_env: ty::ParamEnv<'tcx>,
548548
item_hir: hir::HirId,
549549
to_check: T,
550-
wf_tys: &FxHashSet<Ty<'tcx>>,
550+
wf_tys: &FxIndexSet<Ty<'tcx>>,
551551
gat_def_id: LocalDefId,
552552
gat_generics: &'tcx ty::Generics,
553553
) -> Option<FxHashSet<ty::Predicate<'tcx>>> {
@@ -654,7 +654,7 @@ fn ty_known_to_outlive<'tcx>(
654654
tcx: TyCtxt<'tcx>,
655655
id: hir::HirId,
656656
param_env: ty::ParamEnv<'tcx>,
657-
wf_tys: &FxHashSet<Ty<'tcx>>,
657+
wf_tys: &FxIndexSet<Ty<'tcx>>,
658658
ty: Ty<'tcx>,
659659
region: ty::Region<'tcx>,
660660
) -> bool {
@@ -671,7 +671,7 @@ fn region_known_to_outlive<'tcx>(
671671
tcx: TyCtxt<'tcx>,
672672
id: hir::HirId,
673673
param_env: ty::ParamEnv<'tcx>,
674-
wf_tys: &FxHashSet<Ty<'tcx>>,
674+
wf_tys: &FxIndexSet<Ty<'tcx>>,
675675
region_a: ty::Region<'tcx>,
676676
region_b: ty::Region<'tcx>,
677677
) -> bool {
@@ -695,7 +695,7 @@ fn resolve_regions_with_wf_tys<'tcx>(
695695
tcx: TyCtxt<'tcx>,
696696
id: hir::HirId,
697697
param_env: ty::ParamEnv<'tcx>,
698-
wf_tys: &FxHashSet<Ty<'tcx>>,
698+
wf_tys: &FxIndexSet<Ty<'tcx>>,
699699
add_constraints: impl for<'a> FnOnce(&'a InferCtxt<'tcx>, &'a RegionBoundPairs<'tcx>),
700700
) -> bool {
701701
// Unfortunately, we have to use a new `InferCtxt` each call, because

compiler/rustc_infer/src/infer/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog};
1010

1111
use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine, TraitEngineExt};
1212

13+
use rustc_data_structures::fx::FxIndexMap;
1314
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1415
use rustc_data_structures::sync::Lrc;
1516
use rustc_data_structures::undo_log::Rollback;
@@ -294,7 +295,7 @@ pub struct InferCtxt<'tcx> {
294295

295296
/// the set of predicates on which errors have been reported, to
296297
/// avoid reporting the same error twice.
297-
pub reported_trait_errors: RefCell<FxHashMap<Span, Vec<ty::Predicate<'tcx>>>>,
298+
pub reported_trait_errors: RefCell<FxIndexMap<Span, Vec<ty::Predicate<'tcx>>>>,
298299

299300
pub reported_closure_mismatch: RefCell<FxHashSet<(Span, Option<Span>)>>,
300301

compiler/rustc_trait_selection/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
//!
1111
//! This API is completely unstable and subject to change.
1212
13-
#![allow(rustc::potential_query_instability)]
1413
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
1514
#![feature(box_patterns)]
1615
#![feature(control_flow_enum)]

compiler/rustc_trait_selection/src/traits/auto_trait.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
1212
use rustc_middle::ty::visit::TypeVisitable;
1313
use rustc_middle::ty::{PolyTraitRef, Region, RegionVid};
1414

15-
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
15+
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
1616

1717
use std::collections::hash_map::Entry;
1818
use std::collections::VecDeque;
@@ -27,8 +27,8 @@ pub enum RegionTarget<'tcx> {
2727

2828
#[derive(Default, Debug, Clone)]
2929
pub struct RegionDeps<'tcx> {
30-
larger: FxHashSet<RegionTarget<'tcx>>,
31-
smaller: FxHashSet<RegionTarget<'tcx>>,
30+
larger: FxIndexSet<RegionTarget<'tcx>>,
31+
smaller: FxIndexSet<RegionTarget<'tcx>>,
3232
}
3333

3434
pub enum AutoTraitResult<A> {
@@ -266,7 +266,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
266266
}));
267267

268268
let computed_preds = param_env.caller_bounds().iter();
269-
let mut user_computed_preds: FxHashSet<_> = user_env.caller_bounds().iter().collect();
269+
let mut user_computed_preds: FxIndexSet<_> = user_env.caller_bounds().iter().collect();
270270

271271
let mut new_env = param_env;
272272
let dummy_cause = ObligationCause::dummy();
@@ -389,7 +389,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
389389
/// not just one specific lifetime (e.g., `'static`).
390390
fn add_user_pred(
391391
&self,
392-
user_computed_preds: &mut FxHashSet<ty::Predicate<'tcx>>,
392+
user_computed_preds: &mut FxIndexSet<ty::Predicate<'tcx>>,
393393
new_pred: ty::Predicate<'tcx>,
394394
) {
395395
let mut should_add_new = true;
@@ -585,7 +585,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
585585
&self,
586586
ty: Ty<'_>,
587587
nested: impl Iterator<Item = Obligation<'tcx, ty::Predicate<'tcx>>>,
588-
computed_preds: &mut FxHashSet<ty::Predicate<'tcx>>,
588+
computed_preds: &mut FxIndexSet<ty::Predicate<'tcx>>,
589589
fresh_preds: &mut FxHashSet<ty::Predicate<'tcx>>,
590590
predicates: &mut VecDeque<ty::PolyTraitPredicate<'tcx>>,
591591
select: &mut SelectionContext<'_, 'tcx>,

compiler/rustc_trait_selection/src/traits/engine.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::fmt::Debug;
44
use super::TraitEngine;
55
use super::{ChalkFulfillmentContext, FulfillmentContext};
66
use crate::infer::InferCtxtExt;
7-
use rustc_data_structures::fx::FxHashSet;
7+
use rustc_data_structures::fx::FxIndexSet;
88
use rustc_hir::def_id::{DefId, LocalDefId};
99
use rustc_infer::infer::at::ToTrace;
1010
use rustc_infer::infer::canonical::{
@@ -153,10 +153,10 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
153153
param_env: ty::ParamEnv<'tcx>,
154154
span: Span,
155155
def_id: LocalDefId,
156-
) -> FxHashSet<Ty<'tcx>> {
156+
) -> FxIndexSet<Ty<'tcx>> {
157157
let tcx = self.infcx.tcx;
158158
let assumed_wf_types = tcx.assumed_wf_types(def_id);
159-
let mut implied_bounds = FxHashSet::default();
159+
let mut implied_bounds = FxIndexSet::default();
160160
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
161161
let cause = ObligationCause::misc(span, hir_id);
162162
for ty in assumed_wf_types {

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::traits::query::normalize::AtExt as _;
1414
use crate::traits::specialize::to_pretty_impl_header;
1515
use on_unimplemented::OnUnimplementedNote;
1616
use on_unimplemented::TypeErrCtxtExt as _;
17-
use rustc_data_structures::fx::FxHashMap;
17+
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
1818
use rustc_errors::{
1919
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
2020
MultiSpan, Style,
@@ -378,7 +378,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
378378
index: Option<usize>, // None if this is an old error
379379
}
380380

381-
let mut error_map: FxHashMap<_, Vec<_>> = self
381+
let mut error_map: FxIndexMap<_, Vec<_>> = self
382382
.reported_trait_errors
383383
.borrow()
384384
.iter()

compiler/rustc_trait_selection/src/traits/outlives_bounds.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::infer::InferCtxt;
22
use crate::traits::query::type_op::{self, TypeOp, TypeOpOutput};
33
use crate::traits::query::NoSolution;
44
use crate::traits::ObligationCause;
5-
use rustc_data_structures::fx::FxHashSet;
5+
use rustc_data_structures::fx::FxIndexSet;
66
use rustc_hir as hir;
77
use rustc_hir::HirId;
88
use rustc_middle::ty::{self, ParamEnv, Ty};
@@ -22,7 +22,7 @@ pub trait InferCtxtExt<'a, 'tcx> {
2222
&'a self,
2323
param_env: ty::ParamEnv<'tcx>,
2424
body_id: hir::HirId,
25-
tys: FxHashSet<Ty<'tcx>>,
25+
tys: FxIndexSet<Ty<'tcx>>,
2626
) -> Bounds<'a, 'tcx>;
2727
}
2828

@@ -103,7 +103,7 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
103103
&'a self,
104104
param_env: ParamEnv<'tcx>,
105105
body_id: HirId,
106-
tys: FxHashSet<Ty<'tcx>>,
106+
tys: FxIndexSet<Ty<'tcx>>,
107107
) -> Bounds<'a, 'tcx> {
108108
tys.into_iter()
109109
.map(move |ty| {

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

+8-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
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+
511
use self::EvaluationResult::*;
612
use self::SelectionCandidate::*;
713

@@ -24,7 +30,8 @@ use crate::traits::error_reporting::TypeErrCtxtExt;
2430
use crate::traits::project::ProjectAndUnifyResult;
2531
use crate::traits::project::ProjectionCacheKeyExt;
2632
use crate::traits::ProjectionCacheKey;
27-
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
33+
use rustc_data_structures::fx::FxHashMap;
34+
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
2835
use rustc_data_structures::stack::ensure_sufficient_stack;
2936
use rustc_errors::{Diagnostic, ErrorGuaranteed};
3037
use rustc_hir as hir;

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::errors::NegativePositiveConflict;
1616
use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
1717
use crate::traits::select::IntercrateAmbiguityCause;
1818
use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause};
19-
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
19+
use rustc_data_structures::fx::FxIndexSet;
2020
use rustc_errors::{struct_span_err, DiagnosticBuilder, EmissionGuarantee};
2121
use rustc_hir::def_id::{DefId, LocalDefId};
2222
use rustc_middle::ty::{self, ImplSubject, TyCtxt};
@@ -435,7 +435,7 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti
435435

436436
// FIXME: Currently only handles ?Sized.
437437
// Needs to support ?Move and ?DynSized when they are implemented.
438-
let mut types_without_default_bounds = FxHashSet::default();
438+
let mut types_without_default_bounds = FxIndexSet::default();
439439
let sized_trait = tcx.lang_items().sized_trait();
440440

441441
if !substs.is_empty() {

0 commit comments

Comments
 (0)