From 755ca4b9aa064b77fa8a0f6cdaf050b768d844bc Mon Sep 17 00:00:00 2001 From: CastilloDel Date: Fri, 28 Oct 2022 23:32:41 +0200 Subject: [PATCH] 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. --- .../src/check/compare_method.rs | 6 +++--- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 16 ++++++++-------- compiler/rustc_infer/src/infer/mod.rs | 3 ++- compiler/rustc_trait_selection/src/lib.rs | 1 - .../src/traits/auto_trait.rs | 12 ++++++------ .../rustc_trait_selection/src/traits/engine.rs | 6 +++--- .../src/traits/error_reporting/mod.rs | 4 ++-- .../src/traits/outlives_bounds.rs | 6 +++--- .../src/traits/select/mod.rs | 9 ++++++++- .../src/traits/specialize/mod.rs | 4 ++-- 10 files changed, 37 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs index 0e8ac17fb71b1..818db4186d60a 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_method.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs @@ -1,7 +1,7 @@ use super::potentially_plural_count; use crate::errors::LifetimesOrBoundsMismatchOnTrait; use hir::def_id::{DefId, LocalDefId}; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -256,7 +256,7 @@ fn compare_predicate_entailment<'tcx>( // Compute placeholder form of impl and trait method tys. let tcx = infcx.tcx; - let mut wf_tys = FxHashSet::default(); + let mut wf_tys = FxIndexSet::default(); let impl_sig = infcx.replace_bound_vars_with_fresh_vars( impl_m_span, @@ -479,7 +479,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>( let trait_sig = ocx.normalize(norm_cause.clone(), param_env, unnormalized_trait_sig); let trait_return_ty = trait_sig.output(); - let wf_tys = FxHashSet::from_iter( + let wf_tys = FxIndexSet::from_iter( unnormalized_trait_sig.inputs_and_output.iter().chain(trait_sig.inputs_and_output.iter()), ); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index e2c967d0b0836..6a12db9d36ade 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1,7 +1,7 @@ use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter}; use hir::def::DefKind; use rustc_ast as ast; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -412,7 +412,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe .iter() .copied() .collect::>(), - &FxHashSet::default(), + &FxIndexSet::default(), gat_def_id.def_id, gat_generics, ) @@ -462,10 +462,10 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe .into_iter() .filter(|clause| match clause.kind().skip_binder() { ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => { - !region_known_to_outlive(tcx, gat_hir, param_env, &FxHashSet::default(), a, b) + !region_known_to_outlive(tcx, gat_hir, param_env, &FxIndexSet::default(), a, b) } ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(a, b)) => { - !ty_known_to_outlive(tcx, gat_hir, param_env, &FxHashSet::default(), a, b) + !ty_known_to_outlive(tcx, gat_hir, param_env, &FxIndexSet::default(), a, b) } _ => bug!("Unexpected PredicateKind"), }) @@ -547,7 +547,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<'tcx>>( param_env: ty::ParamEnv<'tcx>, item_hir: hir::HirId, to_check: T, - wf_tys: &FxHashSet>, + wf_tys: &FxIndexSet>, gat_def_id: LocalDefId, gat_generics: &'tcx ty::Generics, ) -> Option>> { @@ -654,7 +654,7 @@ fn ty_known_to_outlive<'tcx>( tcx: TyCtxt<'tcx>, id: hir::HirId, param_env: ty::ParamEnv<'tcx>, - wf_tys: &FxHashSet>, + wf_tys: &FxIndexSet>, ty: Ty<'tcx>, region: ty::Region<'tcx>, ) -> bool { @@ -671,7 +671,7 @@ fn region_known_to_outlive<'tcx>( tcx: TyCtxt<'tcx>, id: hir::HirId, param_env: ty::ParamEnv<'tcx>, - wf_tys: &FxHashSet>, + wf_tys: &FxIndexSet>, region_a: ty::Region<'tcx>, region_b: ty::Region<'tcx>, ) -> bool { @@ -695,7 +695,7 @@ fn resolve_regions_with_wf_tys<'tcx>( tcx: TyCtxt<'tcx>, id: hir::HirId, param_env: ty::ParamEnv<'tcx>, - wf_tys: &FxHashSet>, + wf_tys: &FxIndexSet>, add_constraints: impl for<'a> FnOnce(&'a InferCtxt<'tcx>, &'a RegionBoundPairs<'tcx>), ) -> bool { // Unfortunately, we have to use a new `InferCtxt` each call, because diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index d5be9983ea7c6..ccba197dc80b7 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -10,6 +10,7 @@ pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog}; use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine, TraitEngineExt}; +use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::undo_log::Rollback; @@ -294,7 +295,7 @@ pub struct InferCtxt<'tcx> { /// the set of predicates on which errors have been reported, to /// avoid reporting the same error twice. - pub reported_trait_errors: RefCell>>>, + pub reported_trait_errors: RefCell>>>, pub reported_closure_mismatch: RefCell)>>, diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 5d52aa0752301..2dce18e2d3cad 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -10,7 +10,6 @@ //! //! This API is completely unstable and subject to change. -#![allow(rustc::potential_query_instability)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(box_patterns)] #![feature(control_flow_enum)] diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index ed34ab95ad6c0..188f8bb7e2a58 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -12,7 +12,7 @@ use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{PolyTraitRef, Region, RegionVid}; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use std::collections::hash_map::Entry; use std::collections::VecDeque; @@ -27,8 +27,8 @@ pub enum RegionTarget<'tcx> { #[derive(Default, Debug, Clone)] pub struct RegionDeps<'tcx> { - larger: FxHashSet>, - smaller: FxHashSet>, + larger: FxIndexSet>, + smaller: FxIndexSet>, } pub enum AutoTraitResult { @@ -266,7 +266,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { })); let computed_preds = param_env.caller_bounds().iter(); - let mut user_computed_preds: FxHashSet<_> = user_env.caller_bounds().iter().collect(); + let mut user_computed_preds: FxIndexSet<_> = user_env.caller_bounds().iter().collect(); let mut new_env = param_env; let dummy_cause = ObligationCause::dummy(); @@ -389,7 +389,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { /// not just one specific lifetime (e.g., `'static`). fn add_user_pred( &self, - user_computed_preds: &mut FxHashSet>, + user_computed_preds: &mut FxIndexSet>, new_pred: ty::Predicate<'tcx>, ) { let mut should_add_new = true; @@ -585,7 +585,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { &self, ty: Ty<'_>, nested: impl Iterator>>, - computed_preds: &mut FxHashSet>, + computed_preds: &mut FxIndexSet>, fresh_preds: &mut FxHashSet>, predicates: &mut VecDeque>, select: &mut SelectionContext<'_, 'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 21516c93efb53..91bf5f0b39e73 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use super::TraitEngine; use super::{ChalkFulfillmentContext, FulfillmentContext}; use crate::infer::InferCtxtExt; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::infer::at::ToTrace; use rustc_infer::infer::canonical::{ @@ -153,10 +153,10 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { param_env: ty::ParamEnv<'tcx>, span: Span, def_id: LocalDefId, - ) -> FxHashSet> { + ) -> FxIndexSet> { let tcx = self.infcx.tcx; let assumed_wf_types = tcx.assumed_wf_types(def_id); - let mut implied_bounds = FxHashSet::default(); + let mut implied_bounds = FxIndexSet::default(); let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); let cause = ObligationCause::misc(span, hir_id); for ty in assumed_wf_types { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index c7dee4a18ac5d..2525b9fdd470b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -14,7 +14,7 @@ use crate::traits::query::normalize::AtExt as _; use crate::traits::specialize::to_pretty_impl_header; use on_unimplemented::OnUnimplementedNote; use on_unimplemented::TypeErrCtxtExt as _; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_errors::{ pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, Style, @@ -378,7 +378,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { index: Option, // None if this is an old error } - let mut error_map: FxHashMap<_, Vec<_>> = self + let mut error_map: FxIndexMap<_, Vec<_>> = self .reported_trait_errors .borrow() .iter() diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index b1a161c353637..e1092a788e32b 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -2,7 +2,7 @@ use crate::infer::InferCtxt; use crate::traits::query::type_op::{self, TypeOp, TypeOpOutput}; use crate::traits::query::NoSolution; use crate::traits::ObligationCause; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::HirId; use rustc_middle::ty::{self, ParamEnv, Ty}; @@ -22,7 +22,7 @@ pub trait InferCtxtExt<'a, 'tcx> { &'a self, param_env: ty::ParamEnv<'tcx>, body_id: hir::HirId, - tys: FxHashSet>, + tys: FxIndexSet>, ) -> Bounds<'a, 'tcx>; } @@ -103,7 +103,7 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> { &'a self, param_env: ParamEnv<'tcx>, body_id: HirId, - tys: FxHashSet>, + tys: FxIndexSet>, ) -> Bounds<'a, 'tcx> { tys.into_iter() .map(move |ty| { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 84be1ced520fe..f0d9a1c913979 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2,6 +2,12 @@ //! //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html#selection +// FIXME: The `map` field in ProvisionalEvaluationCache should be changed to +// a `FxIndexMap` to avoid query instability, but right now it causes a perf regression. This would be +// fixed or at least lightened by the addition of the `drain_filter` method to `FxIndexMap` +// Relevant: https://github.com/rust-lang/rust/pull/103723 and https://github.com/bluss/indexmap/issues/242 +#![allow(rustc::potential_query_instability)] + use self::EvaluationResult::*; use self::SelectionCandidate::*; @@ -24,7 +30,8 @@ use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::project::ProjectAndUnifyResult; use crate::traits::project::ProjectionCacheKeyExt; use crate::traits::ProjectionCacheKey; -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{Diagnostic, ErrorGuaranteed}; use rustc_hir as hir; diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index c891658582a0a..43819b3f490b1 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -16,7 +16,7 @@ use crate::errors::NegativePositiveConflict; use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause}; -use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; +use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{struct_span_err, DiagnosticBuilder, EmissionGuarantee}; use rustc_hir::def_id::{DefId, LocalDefId}; 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 // FIXME: Currently only handles ?Sized. // Needs to support ?Move and ?DynSized when they are implemented. - let mut types_without_default_bounds = FxHashSet::default(); + let mut types_without_default_bounds = FxIndexSet::default(); let sized_trait = tcx.lang_items().sized_trait(); if !substs.is_empty() {