Auto merge of #119192 - michaelwoerister:mcp533-push, r=cjgillot
Replace a number of FxHashMaps/Sets with stable-iteration-order alternatives This PR replaces almost all of the remaining `FxHashMap`s in query results with either `FxIndexMap` or `UnordMap`. The only case that is missing is the `EffectiveVisibilities` struct which turned out to not be straightforward to transform. Once that is done too, we can remove the `HashStable` implementation from `HashMap`. The first commit adds the `StableCompare` trait which is a companion trait to `StableOrd`. Some types like `Symbol` can be compared in a cross-session stable way, but their `Ord` implementation is not stable. In such cases, a `StableCompare` implementation can be provided to offer a lightweight way for stable sorting. The more heavyweight option is to sort via `ToStableHashKey`, but then sorting needs to have access to a stable hashing context and `ToStableHashKey` can also be expensive as in the case of `Symbol` where it has to allocate a `String`. The rest of the commits are rather mechanical and don't overlap, so they are best reviewed individually. Part of [MCP 533](https://github.com/rust-lang/compiler-team/issues/533).
This commit is contained in:
commit
b8c207435c
30 changed files with 256 additions and 147 deletions
|
@ -103,7 +103,7 @@ macro_rules! arena_types {
|
|||
[] dep_kind: rustc_middle::dep_graph::DepKindStruct<'tcx>,
|
||||
|
||||
[decode] trait_impl_trait_tys:
|
||||
rustc_data_structures::fx::FxHashMap<
|
||||
rustc_data_structures::unord::UnordMap<
|
||||
rustc_hir::def_id::DefId,
|
||||
rustc_middle::ty::EarlyBinder<rustc_middle::ty::Ty<'tcx>>
|
||||
>,
|
||||
|
|
|
@ -4,7 +4,7 @@ pub mod dependency_format;
|
|||
pub mod exported_symbols;
|
||||
pub mod lang_items;
|
||||
pub mod lib_features {
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::unord::UnordMap;
|
||||
use rustc_span::{symbol::Symbol, Span};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
|
@ -16,15 +16,16 @@ pub mod lib_features {
|
|||
|
||||
#[derive(HashStable, Debug, Default)]
|
||||
pub struct LibFeatures {
|
||||
pub stability: FxHashMap<Symbol, (FeatureStability, Span)>,
|
||||
pub stability: UnordMap<Symbol, (FeatureStability, Span)>,
|
||||
}
|
||||
|
||||
impl LibFeatures {
|
||||
pub fn to_vec(&self) -> Vec<(Symbol, FeatureStability)> {
|
||||
let mut all_features: Vec<_> =
|
||||
self.stability.iter().map(|(&sym, &(stab, _))| (sym, stab)).collect();
|
||||
all_features.sort_unstable_by(|(a, _), (b, _)| a.as_str().cmp(b.as_str()));
|
||||
all_features
|
||||
pub fn to_sorted_vec(&self) -> Vec<(Symbol, FeatureStability)> {
|
||||
self.stability
|
||||
.to_sorted_stable_ord()
|
||||
.iter()
|
||||
.map(|(&sym, &(stab, _))| (sym, stab))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,12 +7,11 @@
|
|||
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/borrow_check.html
|
||||
|
||||
use crate::ty::TyCtxt;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_data_structures::unord::UnordMap;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::{HirIdMap, Node};
|
||||
use rustc_macros::HashStable;
|
||||
use rustc_query_system::ich::StableHashingContext;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
use std::fmt;
|
||||
|
@ -205,7 +204,7 @@ impl Scope {
|
|||
pub type ScopeDepth = u32;
|
||||
|
||||
/// The region scope tree encodes information about region relationships.
|
||||
#[derive(Default, Debug)]
|
||||
#[derive(Default, Debug, HashStable)]
|
||||
pub struct ScopeTree {
|
||||
/// If not empty, this body is the root of this region hierarchy.
|
||||
pub root_body: Option<hir::HirId>,
|
||||
|
@ -306,7 +305,7 @@ pub struct ScopeTree {
|
|||
/// The reason is that semantically, until the `box` expression returns,
|
||||
/// the values are still owned by their containing expressions. So
|
||||
/// we'll see that `&x`.
|
||||
pub yield_in_scope: FxHashMap<Scope, Vec<YieldData>>,
|
||||
pub yield_in_scope: UnordMap<Scope, Vec<YieldData>>,
|
||||
}
|
||||
|
||||
/// Identifies the reason that a given expression is an rvalue candidate
|
||||
|
@ -404,23 +403,3 @@ impl ScopeTree {
|
|||
self.yield_in_scope.get(&scope).map(Deref::deref)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for ScopeTree {
|
||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||
let ScopeTree {
|
||||
root_body,
|
||||
ref parent_map,
|
||||
ref var_map,
|
||||
ref destruction_scopes,
|
||||
ref rvalue_candidates,
|
||||
ref yield_in_scope,
|
||||
} = *self;
|
||||
|
||||
root_body.hash_stable(hcx, hasher);
|
||||
parent_map.hash_stable(hcx, hasher);
|
||||
var_map.hash_stable(hcx, hasher);
|
||||
destruction_scopes.hash_stable(hcx, hasher);
|
||||
rvalue_candidates.hash_stable(hcx, hasher);
|
||||
yield_in_scope.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use crate::ty;
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{ItemLocalId, OwnerId};
|
||||
|
@ -51,7 +51,7 @@ pub enum ObjectLifetimeDefault {
|
|||
pub struct ResolveBoundVars {
|
||||
/// Maps from every use of a named (not anonymous) lifetime to a
|
||||
/// `Region` describing how that region is bound
|
||||
pub defs: FxHashMap<OwnerId, FxHashMap<ItemLocalId, ResolvedArg>>,
|
||||
pub defs: FxIndexMap<OwnerId, FxIndexMap<ItemLocalId, ResolvedArg>>,
|
||||
|
||||
pub late_bound_vars: FxHashMap<OwnerId, FxHashMap<ItemLocalId, Vec<ty::BoundVariableKind>>>,
|
||||
pub late_bound_vars: FxIndexMap<OwnerId, FxIndexMap<ItemLocalId, Vec<ty::BoundVariableKind>>>,
|
||||
}
|
||||
|
|
|
@ -8,11 +8,11 @@ use rustc_ast::NodeId;
|
|||
use rustc_attr::{
|
||||
self as attr, ConstStability, DefaultBodyStability, DeprecatedSince, Deprecation, Stability,
|
||||
};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::unord::UnordMap;
|
||||
use rustc_errors::{Applicability, Diagnostic};
|
||||
use rustc_feature::GateIssue;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap};
|
||||
use rustc_hir::{self as hir, HirId};
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE};
|
||||
|
@ -61,10 +61,10 @@ impl DeprecationEntry {
|
|||
pub struct Index {
|
||||
/// This is mostly a cache, except the stabilities of local items
|
||||
/// are filled by the annotator.
|
||||
pub stab_map: FxHashMap<LocalDefId, Stability>,
|
||||
pub const_stab_map: FxHashMap<LocalDefId, ConstStability>,
|
||||
pub default_body_stab_map: FxHashMap<LocalDefId, DefaultBodyStability>,
|
||||
pub depr_map: FxHashMap<LocalDefId, DeprecationEntry>,
|
||||
pub stab_map: LocalDefIdMap<Stability>,
|
||||
pub const_stab_map: LocalDefIdMap<ConstStability>,
|
||||
pub default_body_stab_map: LocalDefIdMap<DefaultBodyStability>,
|
||||
pub depr_map: LocalDefIdMap<DeprecationEntry>,
|
||||
/// Mapping from feature name to feature name based on the `implied_by` field of `#[unstable]`
|
||||
/// attributes. If a `#[unstable(feature = "implier", implied_by = "impliee")]` attribute
|
||||
/// exists, then this map will have a `impliee -> implier` entry.
|
||||
|
@ -77,7 +77,7 @@ pub struct Index {
|
|||
/// to know that the feature implies another feature. If it were reversed, and the `#[stable]`
|
||||
/// attribute had an `implies` meta item, then a map would be necessary when avoiding a "use of
|
||||
/// unstable feature" error for a feature that was implied.
|
||||
pub implications: FxHashMap<Symbol, Symbol>,
|
||||
pub implications: UnordMap<Symbol, Symbol>,
|
||||
}
|
||||
|
||||
impl Index {
|
||||
|
|
|
@ -57,11 +57,11 @@ use rustc_ast as ast;
|
|||
use rustc_ast::expand::{allocator::AllocatorKind, StrippedCfgItem};
|
||||
use rustc_attr as attr;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
|
||||
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||
use rustc_data_structures::steal::Steal;
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_data_structures::unord::UnordSet;
|
||||
use rustc_data_structures::unord::{UnordMap, UnordSet};
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, DocLinkResMap};
|
||||
|
@ -264,7 +264,7 @@ rustc_queries! {
|
|||
}
|
||||
|
||||
query collect_return_position_impl_trait_in_trait_tys(key: DefId)
|
||||
-> Result<&'tcx FxHashMap<DefId, ty::EarlyBinder<Ty<'tcx>>>, ErrorGuaranteed>
|
||||
-> Result<&'tcx DefIdMap<ty::EarlyBinder<Ty<'tcx>>>, ErrorGuaranteed>
|
||||
{
|
||||
desc { "comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process" }
|
||||
cache_on_disk_if { key.is_local() }
|
||||
|
@ -611,7 +611,7 @@ rustc_queries! {
|
|||
desc { "erasing regions from `{}`", ty }
|
||||
}
|
||||
|
||||
query wasm_import_module_map(_: CrateNum) -> &'tcx FxHashMap<DefId, String> {
|
||||
query wasm_import_module_map(_: CrateNum) -> &'tcx DefIdMap<String> {
|
||||
arena_cache
|
||||
desc { "getting wasm import module map" }
|
||||
}
|
||||
|
@ -1537,7 +1537,7 @@ rustc_queries! {
|
|||
/// added or removed in any upstream crate. Instead use the narrower
|
||||
/// `upstream_monomorphizations_for`, `upstream_drop_glue_for`, or, even
|
||||
/// better, `Instance::upstream_monomorphization()`.
|
||||
query upstream_monomorphizations(_: ()) -> &'tcx DefIdMap<FxHashMap<GenericArgsRef<'tcx>, CrateNum>> {
|
||||
query upstream_monomorphizations(_: ()) -> &'tcx DefIdMap<UnordMap<GenericArgsRef<'tcx>, CrateNum>> {
|
||||
arena_cache
|
||||
desc { "collecting available upstream monomorphizations" }
|
||||
}
|
||||
|
@ -1550,7 +1550,7 @@ rustc_queries! {
|
|||
/// You likely want to call `Instance::upstream_monomorphization()`
|
||||
/// instead of invoking this query directly.
|
||||
query upstream_monomorphizations_for(def_id: DefId)
|
||||
-> Option<&'tcx FxHashMap<GenericArgsRef<'tcx>, CrateNum>>
|
||||
-> Option<&'tcx UnordMap<GenericArgsRef<'tcx>, CrateNum>>
|
||||
{
|
||||
desc { |tcx|
|
||||
"collecting available upstream monomorphizations for `{}`",
|
||||
|
@ -1662,7 +1662,7 @@ rustc_queries! {
|
|||
desc { "resolving lifetimes" }
|
||||
}
|
||||
query named_variable_map(_: hir::OwnerId) ->
|
||||
Option<&'tcx FxHashMap<ItemLocalId, ResolvedArg>> {
|
||||
Option<&'tcx FxIndexMap<ItemLocalId, ResolvedArg>> {
|
||||
desc { "looking up a named region" }
|
||||
}
|
||||
query is_late_bound_map(_: hir::OwnerId) -> Option<&'tcx FxIndexSet<ItemLocalId>> {
|
||||
|
@ -1678,7 +1678,7 @@ rustc_queries! {
|
|||
separate_provide_extern
|
||||
}
|
||||
query late_bound_vars_map(_: hir::OwnerId)
|
||||
-> Option<&'tcx FxHashMap<ItemLocalId, Vec<ty::BoundVariableKind>>> {
|
||||
-> Option<&'tcx FxIndexMap<ItemLocalId, Vec<ty::BoundVariableKind>>> {
|
||||
desc { "looking up late bound vars" }
|
||||
}
|
||||
|
||||
|
@ -1734,7 +1734,7 @@ rustc_queries! {
|
|||
separate_provide_extern
|
||||
arena_cache
|
||||
}
|
||||
query stability_implications(_: CrateNum) -> &'tcx FxHashMap<Symbol, Symbol> {
|
||||
query stability_implications(_: CrateNum) -> &'tcx UnordMap<Symbol, Symbol> {
|
||||
arena_cache
|
||||
desc { "calculating the implications between `#[unstable]` features defined in a crate" }
|
||||
separate_provide_extern
|
||||
|
@ -1786,7 +1786,7 @@ rustc_queries! {
|
|||
}
|
||||
/// Collects the "trimmed", shortest accessible paths to all items for diagnostics.
|
||||
/// See the [provider docs](`rustc_middle::ty::print::trimmed_def_paths`) for more info.
|
||||
query trimmed_def_paths(_: ()) -> &'tcx FxHashMap<DefId, Symbol> {
|
||||
query trimmed_def_paths(_: ()) -> &'tcx DefIdMap<Symbol> {
|
||||
arena_cache
|
||||
desc { "calculating trimmed def paths" }
|
||||
}
|
||||
|
@ -2077,7 +2077,7 @@ rustc_queries! {
|
|||
desc { "computing autoderef types for `{}`", goal.value.value }
|
||||
}
|
||||
|
||||
query supported_target_features(_: CrateNum) -> &'tcx FxHashMap<String, Option<Symbol>> {
|
||||
query supported_target_features(_: CrateNum) -> &'tcx UnordMap<String, Option<Symbol>> {
|
||||
arena_cache
|
||||
eval_always
|
||||
desc { "looking up supported target features" }
|
||||
|
|
|
@ -2,7 +2,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
|||
use rustc_data_structures::memmap::Mmap;
|
||||
use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, RwLock};
|
||||
use rustc_data_structures::unhash::UnhashMap;
|
||||
use rustc_data_structures::unord::UnordSet;
|
||||
use rustc_data_structures::unord::{UnordMap, UnordSet};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, StableCrateId, LOCAL_CRATE};
|
||||
use rustc_hir::definitions::DefPathHash;
|
||||
use rustc_index::{Idx, IndexVec};
|
||||
|
@ -764,7 +764,7 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx UnordSet<LocalDefId>
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
|
||||
for &'tcx FxHashMap<DefId, ty::EarlyBinder<Ty<'tcx>>>
|
||||
for &'tcx UnordMap<DefId, ty::EarlyBinder<Ty<'tcx>>>
|
||||
{
|
||||
#[inline]
|
||||
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
||||
|
|
|
@ -38,6 +38,7 @@ use rustc_data_structures::intern::Interned;
|
|||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::steal::Steal;
|
||||
use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
|
||||
use rustc_data_structures::unord::UnordMap;
|
||||
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, StashKey};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
|
||||
|
@ -655,7 +656,7 @@ pub struct CratePredicatesMap<'tcx> {
|
|||
/// For each struct with outlive bounds, maps to a vector of the
|
||||
/// predicate of its outlive bounds. If an item has no outlives
|
||||
/// bounds, it will have no entry.
|
||||
pub predicates: FxHashMap<DefId, &'tcx [(Clause<'tcx>, Span)]>,
|
||||
pub predicates: DefIdMap<&'tcx [(Clause<'tcx>, Span)]>,
|
||||
}
|
||||
|
||||
impl<'tcx> Clause<'tcx> {
|
||||
|
@ -2658,7 +2659,7 @@ pub fn provide(providers: &mut Providers) {
|
|||
#[derive(Clone, Debug, Default, HashStable)]
|
||||
pub struct CrateInherentImpls {
|
||||
pub inherent_impls: LocalDefIdMap<Vec<DefId>>,
|
||||
pub incoherent_impls: FxHashMap<SimplifiedType, Vec<LocalDefId>>,
|
||||
pub incoherent_impls: UnordMap<SimplifiedType, Vec<LocalDefId>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, HashStable)]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::unord::UnordMap;
|
||||
use rustc_hir::def_id::DefIndex;
|
||||
use rustc_index::{Idx, IndexVec};
|
||||
use std::hash::Hash;
|
||||
|
||||
use crate::ty;
|
||||
|
||||
|
@ -24,8 +25,8 @@ impl<I: Idx + 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for IndexVe
|
|||
type Value<'tcx> = IndexVec<I, T::Value<'tcx>>;
|
||||
}
|
||||
|
||||
impl<I: 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for FxHashMap<I, T> {
|
||||
type Value<'tcx> = FxHashMap<I, T::Value<'tcx>>;
|
||||
impl<I: Hash + Eq + 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for UnordMap<I, T> {
|
||||
type Value<'tcx> = UnordMap<I, T::Value<'tcx>>;
|
||||
}
|
||||
|
||||
impl<T: ParameterizedOverTcx> ParameterizedOverTcx for ty::Binder<'static, T> {
|
||||
|
|
|
@ -12,7 +12,7 @@ use rustc_apfloat::Float;
|
|||
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{self, CtorKind, DefKind, Namespace};
|
||||
use rustc_hir::def_id::{DefIdSet, ModDefId, CRATE_DEF_ID, LOCAL_CRATE};
|
||||
use rustc_hir::def_id::{DefIdMap, DefIdSet, ModDefId, CRATE_DEF_ID, LOCAL_CRATE};
|
||||
use rustc_hir::definitions::{DefKey, DefPathDataName};
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_session::config::TrimmedDefPaths;
|
||||
|
@ -3049,8 +3049,8 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
|
|||
///
|
||||
/// See also [`DelayDm`](rustc_error_messages::DelayDm) and [`with_no_trimmed_paths!`].
|
||||
// this is pub to be able to intra-doc-link it
|
||||
pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap<DefId, Symbol> {
|
||||
let mut map: FxHashMap<DefId, Symbol> = FxHashMap::default();
|
||||
pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> DefIdMap<Symbol> {
|
||||
let mut map: DefIdMap<Symbol> = Default::default();
|
||||
|
||||
if let TrimmedDefPaths::GoodPath = tcx.sess.opts.trimmed_def_paths {
|
||||
// Trimming paths is expensive and not optimized, since we expect it to only be used for error reporting.
|
||||
|
|
|
@ -527,7 +527,7 @@ impl<'a, V> LocalTableInContext<'a, V> {
|
|||
}
|
||||
|
||||
pub fn items_in_stable_order(&self) -> Vec<(ItemLocalId, &'a V)> {
|
||||
self.data.to_sorted_stable_ord()
|
||||
self.data.items().map(|(&k, v)| (k, v)).into_sorted_stable_ord_by_key(|(k, _)| k)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue