From 609f6493e0234f67db56c9fe7eab637336ee82f2 Mon Sep 17 00:00:00 2001 From: Hameer Abbasi Date: Sun, 20 Feb 2022 16:35:57 +0100 Subject: [PATCH 1/4] Modify StableSet with a HashStable implementation. --- .../src/stable_hasher.rs | 15 +------- .../rustc_data_structures/src/stable_set.rs | 34 +++++++++++++++++-- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index e8d81d4b937ab..6502a123d4523 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -544,19 +544,6 @@ where } } -impl HashStable for ::std::collections::HashSet -where - K: ToStableHashKey + Eq, - R: BuildHasher, -{ - fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { - stable_hash_reduce(hcx, hasher, self.iter(), self.len(), |hasher, hcx, key| { - let key = key.to_stable_hash_key(hcx); - key.hash_stable(hcx, hasher); - }); - } -} - impl HashStable for ::std::collections::BTreeMap where K: ToStableHashKey, @@ -583,7 +570,7 @@ where } } -fn stable_hash_reduce( +pub fn stable_hash_reduce( hcx: &mut HCX, hasher: &mut StableHasher, mut collection: C, diff --git a/compiler/rustc_data_structures/src/stable_set.rs b/compiler/rustc_data_structures/src/stable_set.rs index c7ca74f5fbd9d..6f9d1df35fe89 100644 --- a/compiler/rustc_data_structures/src/stable_set.rs +++ b/compiler/rustc_data_structures/src/stable_set.rs @@ -3,6 +3,8 @@ use std::borrow::Borrow; use std::fmt; use std::hash::Hash; +use crate::stable_hasher::{stable_hash_reduce, HashStable, StableHasher, ToStableHashKey}; + /// A deterministic wrapper around FxHashSet that does not provide iteration support. /// /// It supports insert, remove, get functions from FxHashSet. @@ -16,6 +18,7 @@ impl Default for StableSet where T: Eq + Hash, { + #[inline] fn default() -> StableSet { StableSet::new() } @@ -25,6 +28,7 @@ impl fmt::Debug for StableSet where T: Eq + Hash + fmt::Debug, { + #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self.base) } @@ -34,6 +38,7 @@ impl PartialEq> for StableSet where T: Eq + Hash, { + #[inline] fn eq(&self, other: &StableSet) -> bool { self.base == other.base } @@ -42,19 +47,22 @@ where impl Eq for StableSet where T: Eq + Hash {} impl StableSet { + #[inline] pub fn new() -> StableSet { StableSet { base: FxHashSet::default() } } - pub fn into_sorted_vector(self) -> Vec + #[inline] + pub fn into_sorted_vector(self, hcx: &HCX) -> Vec where - T: Ord, + T: ToStableHashKey, { let mut vector = self.base.into_iter().collect::>(); - vector.sort_unstable(); + vector.sort_by_cached_key(|x| x.to_stable_hash_key(hcx)); vector } + #[inline] pub fn get(&self, value: &Q) -> Option<&T> where T: Borrow, @@ -63,10 +71,12 @@ impl StableSet { self.base.get(value) } + #[inline] pub fn insert(&mut self, value: T) -> bool { self.base.insert(value) } + #[inline] pub fn remove(&mut self, value: &Q) -> bool where T: Borrow, @@ -74,4 +84,22 @@ impl StableSet { { self.base.remove(value) } + + #[inline] + pub fn contains(&self, value: &T) -> bool { + self.base.contains(value) + } +} + +impl HashStable for StableSet +where + T: ToStableHashKey + Eq, +{ + #[inline] + fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { + stable_hash_reduce(hcx, hasher, self.base.iter(), self.base.len(), |hasher, hcx, key| { + let key = key.to_stable_hash_key(hcx); + key.hash_stable(hcx, hasher); + }); + } } From 72c9dd7c806ca2ce9c05512151ac1a5dd571c52c Mon Sep 17 00:00:00 2001 From: Hameer Abbasi Date: Sun, 20 Feb 2022 16:36:22 +0100 Subject: [PATCH 2/4] Attempt at replacing all occurrences. --- compiler/rustc_codegen_ssa/src/base.rs | 2 +- compiler/rustc_data_structures/src/fx.rs | 2 +- .../rustc_data_structures/src/stable_set.rs | 39 +++++++++++++++++-- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_middle/src/middle/mod.rs | 11 ++++-- .../src/middle/resolve_lifetime.rs | 5 ++- compiler/rustc_middle/src/middle/stability.rs | 9 ++++- compiler/rustc_middle/src/query/mod.rs | 12 +++--- compiler/rustc_middle/src/ty/context.rs | 7 ++-- compiler/rustc_middle/src/ty/mod.rs | 3 +- compiler/rustc_middle/src/ty/print/pretty.rs | 3 +- compiler/rustc_middle/src/ty/query.rs | 5 ++- compiler/rustc_passes/src/stability.rs | 2 +- compiler/rustc_resolve/src/late/lifetimes.rs | 7 ++-- compiler/rustc_resolve/src/lib.rs | 3 +- compiler/rustc_typeck/src/check/mod.rs | 2 +- compiler/rustc_typeck/src/check/writeback.rs | 3 +- 17 files changed, 85 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 010560248054e..f7dae40efb2af 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -910,7 +910,7 @@ pub fn provide(providers: &mut Providers) { }; let (defids, _) = tcx.collect_and_partition_mono_items(cratenum); - for id in &*defids { + for id in defids.sorted_vector() { let CodegenFnAttrs { optimize, .. } = tcx.codegen_fn_attrs(*id); match optimize { attr::OptimizeAttr::None => continue, diff --git a/compiler/rustc_data_structures/src/fx.rs b/compiler/rustc_data_structures/src/fx.rs index bbeb193dba32b..584ef7bdb1d82 100644 --- a/compiler/rustc_data_structures/src/fx.rs +++ b/compiler/rustc_data_structures/src/fx.rs @@ -9,6 +9,6 @@ pub type FxIndexSet = indexmap::IndexSet>; macro_rules! define_id_collections { ($map_name:ident, $set_name:ident, $key:ty) => { pub type $map_name = $crate::fx::FxHashMap<$key, T>; - pub type $set_name = $crate::fx::FxHashSet<$key>; + pub type $set_name = $crate::stable_set::StableSet<$key>; }; } diff --git a/compiler/rustc_data_structures/src/stable_set.rs b/compiler/rustc_data_structures/src/stable_set.rs index 6f9d1df35fe89..abb4c9c594e40 100644 --- a/compiler/rustc_data_structures/src/stable_set.rs +++ b/compiler/rustc_data_structures/src/stable_set.rs @@ -9,8 +9,11 @@ use crate::stable_hasher::{stable_hash_reduce, HashStable, StableHasher, ToStabl /// /// It supports insert, remove, get functions from FxHashSet. /// It also allows to convert hashset to a sorted vector with the method `into_sorted_vector()`. -#[derive(Clone)] -pub struct StableSet { +#[derive(Clone, Encodable, Decodable)] +pub struct StableSet +where + T: Eq + Hash, +{ base: FxHashSet, } @@ -62,6 +65,16 @@ impl StableSet { vector } + #[inline] + pub fn sorted_vector(&self, hcx: &HCX) -> Vec<&T> + where + T: ToStableHashKey, + { + let mut vector = self.base.iter().collect::>(); + vector.sort_by_cached_key(|x| x.to_stable_hash_key(hcx)); + vector + } + #[inline] pub fn get(&self, value: &Q) -> Option<&T> where @@ -93,7 +106,7 @@ impl StableSet { impl HashStable for StableSet where - T: ToStableHashKey + Eq, + T: ToStableHashKey + Eq + Hash, { #[inline] fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { @@ -103,3 +116,23 @@ where }); } } + +impl FromIterator for StableSet +where + T: Eq + Hash, +{ + #[inline] + fn from_iter>(iter: Collection) -> Self { + Self { base: iter.into_iter().collect() } + } +} + +impl Extend for StableSet +where + T: Eq + Hash, +{ + #[inline] + fn extend>(&mut self, iter: Iter) { + self.base.extend(iter) + } +} diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 6c758b8e5b633..ee1ba04f4332d 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1742,7 +1742,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { empty_proc_macro!(self); let tcx = self.tcx; let lib_features = tcx.lib_features(()); - self.lazy(lib_features.to_vec()) + self.lazy(lib_features.to_vec(tcx)) } fn encode_diagnostic_items(&mut self) -> Lazy<[(Symbol, DefIndex)]> { diff --git a/compiler/rustc_middle/src/middle/mod.rs b/compiler/rustc_middle/src/middle/mod.rs index fc35cafcc77a1..dfc30477e5cdf 100644 --- a/compiler/rustc_middle/src/middle/mod.rs +++ b/compiler/rustc_middle/src/middle/mod.rs @@ -3,23 +3,26 @@ pub mod dependency_format; pub mod exported_symbols; pub mod lang_items; pub mod lib_features { - use rustc_data_structures::fx::{FxHashMap, FxHashSet}; + use rustc_data_structures::{fx::FxHashMap, stable_set::StableSet}; use rustc_span::symbol::Symbol; + use crate::ty::TyCtxt; + #[derive(HashStable, Debug)] pub struct LibFeatures { // A map from feature to stabilisation version. pub stable: FxHashMap, - pub unstable: FxHashSet, + pub unstable: StableSet, } impl LibFeatures { - pub fn to_vec(&self) -> Vec<(Symbol, Option)> { + pub fn to_vec(&self, tcx: TyCtxt<'_>) -> Vec<(Symbol, Option)> { + let hcx = tcx.create_stable_hashing_context(); let mut all_features: Vec<_> = self .stable .iter() .map(|(f, s)| (*f, Some(*s))) - .chain(self.unstable.iter().map(|f| (*f, None))) + .chain(self.unstable.sorted_vector(&hcx).into_iter().map(|f| (*f, None))) .collect(); all_features.sort_unstable_by(|a, b| a.0.as_str().partial_cmp(b.0.as_str()).unwrap()); all_features diff --git a/compiler/rustc_middle/src/middle/resolve_lifetime.rs b/compiler/rustc_middle/src/middle/resolve_lifetime.rs index 98375cbad9f9b..92dd97c4b3d79 100644 --- a/compiler/rustc_middle/src/middle/resolve_lifetime.rs +++ b/compiler/rustc_middle/src/middle/resolve_lifetime.rs @@ -2,7 +2,8 @@ use crate::ty; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::stable_set::StableSet; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::ItemLocalId; use rustc_macros::HashStable; @@ -63,7 +64,7 @@ pub struct ResolveLifetimes { /// Set of lifetime def ids that are late-bound; a region can /// be late-bound if (a) it does NOT appear in a where-clause and /// (b) it DOES appear in the arguments. - pub late_bound: FxHashMap>, + pub late_bound: FxHashMap>, pub late_bound_vars: FxHashMap>>, } diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index fd6e241346db8..e9c9e25f2a0bc 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -7,12 +7,13 @@ use crate::ty::{self, DefIdTree, TyCtxt}; use rustc_ast::NodeId; use rustc_attr::{self as attr, ConstStability, Deprecation, Stability}; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::stable_set::StableSet; use rustc_errors::{Applicability, Diagnostic}; use rustc_feature::GateIssue; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX}; -use rustc_hir::{self, HirId}; +use rustc_hir::{self, def_id::CrateNum, HirId}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE}; use rustc_session::lint::{BuiltinLintDiagnostics, Level, Lint, LintBuffer}; @@ -63,6 +64,12 @@ pub struct Index { pub stab_map: FxHashMap, pub const_stab_map: FxHashMap, pub depr_map: FxHashMap, + + /// Maps for each crate whether it is part of the staged API. + pub staged_api: FxHashMap, + + /// Features enabled for this crate. + pub active_features: StableSet, } impl Index { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 89761bf4e27a0..5a4ab611505c5 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -775,7 +775,7 @@ rustc_queries! { /// The second return value maps from ADTs to ignored derived traits (e.g. Debug and Clone) and /// their respective impl (i.e., part of the derive macro) query live_symbols_and_ignored_derived_traits(_: ()) -> ( - FxHashSet, + StableSet, FxHashMap> ) { storage(ArenaCacheSelector<'tcx>) @@ -828,7 +828,7 @@ rustc_queries! { } } - query used_trait_imports(key: LocalDefId) -> &'tcx FxHashSet { + query used_trait_imports(key: LocalDefId) -> &'tcx StableSet { desc { |tcx| "used_trait_imports `{}`", tcx.def_path_str(key.to_def_id()) } cache_on_disk_if { true } } @@ -978,7 +978,7 @@ rustc_queries! { desc { "checking for private elements in public interfaces" } } - query reachable_set(_: ()) -> FxHashSet { + query reachable_set(_: ()) -> StableSet { storage(ArenaCacheSelector<'tcx>) desc { "reachability" } } @@ -1055,7 +1055,7 @@ rustc_queries! { cache_on_disk_if { true } } - query asm_target_features(def_id: DefId) -> &'tcx FxHashSet { + query asm_target_features(def_id: DefId) -> &'tcx StableSet { desc { |tcx| "computing target features for inline asm of `{}`", tcx.def_path_str(def_id) } } @@ -1506,7 +1506,7 @@ rustc_queries! { desc { "looking up a named region" } } query is_late_bound_map(_: LocalDefId) -> - Option<(LocalDefId, &'tcx FxHashSet)> { + Option<(LocalDefId, &'tcx StableSet)> { desc { "testing if a region is late bound" } } /// For a given item (like a struct), gets the default lifetimes to be used @@ -1645,7 +1645,7 @@ rustc_queries! { query maybe_unused_extern_crates(_: ()) -> &'tcx [(LocalDefId, Span)] { desc { "looking up all possibly unused extern crates" } } - query names_imported_by_glob_use(def_id: LocalDefId) -> &'tcx FxHashSet { + query names_imported_by_glob_use(def_id: LocalDefId) -> &'tcx StableSet { desc { |tcx| "names_imported_by_glob_use for `{}`", tcx.def_path_str(def_id.to_def_id()) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 6ca8f8b1309fa..946b8863ccaa9 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -25,12 +25,13 @@ use crate::ty::{ }; use rustc_ast as ast; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::intern::Interned; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::stable_set::StableSet; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{self, Lock, Lrc, WorkerLocal}; use rustc_data_structures::vec_map::VecMap; @@ -480,7 +481,7 @@ pub struct TypeckResults<'tcx> { /// This is used for warning unused imports. During type /// checking, this `Lrc` should not be cloned: it must have a ref-count /// of 1 so that we can insert things into the set mutably. - pub used_trait_imports: Lrc>, + pub used_trait_imports: Lrc>, /// If any errors occurred while type-checking this body, /// this field will be set to `Some(ErrorGuaranteed)`. @@ -2208,7 +2209,7 @@ impl<'tcx> TyCtxt<'tcx> { /// to identify which traits may define a given associated type to help avoid cycle errors. /// Returns a `DefId` iterator. fn super_traits_of(self, trait_def_id: DefId) -> impl Iterator + 'tcx { - let mut set = FxHashSet::default(); + let mut set = StableSet::default(); let mut stack = vec![trait_def_id]; set.insert(trait_def_id); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6e3dc92a2332f..413bfd472120e 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -18,6 +18,7 @@ pub use adt::*; pub use assoc::*; pub use generics::*; use rustc_data_structures::fingerprint::Fingerprint; +use rustc_data_structures::stable_set::StableSet; pub use vtable::*; use crate::metadata::ModChild; @@ -135,7 +136,7 @@ pub struct ResolverOutputs { pub maybe_unused_trait_imports: FxHashSet, pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>, pub reexport_map: FxHashMap>, - pub glob_map: FxHashMap>, + pub glob_map: FxHashMap>, /// Extern prelude entries. The value is `true` if the entry was introduced /// via `extern crate` item and not `--extern` option or compiler built-in. pub extern_prelude: FxHashMap, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 9a9c529f24552..d396473890530 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2763,8 +2763,9 @@ fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap { let unique_symbols_rev: &mut FxHashMap<(Namespace, Symbol), Option> = &mut FxHashMap::default(); + let hcx = tcx.create_stable_hashing_context(); for symbol_set in tcx.resolutions(()).glob_map.values() { - for symbol in symbol_set { + for symbol in symbol_set.sorted_vector(&hcx) { unique_symbols_rev.insert((Namespace::TypeNS, *symbol), None); unique_symbols_rev.insert((Namespace::ValueNS, *symbol), None); unique_symbols_rev.insert((Namespace::MacroNS, *symbol), None); diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index 9e48c569c253a..5008b487d643b 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -33,10 +33,13 @@ use crate::ty::subst::{GenericArg, SubstsRef}; use crate::ty::util::AlwaysRequiresDrop; use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt}; use rustc_ast::expand::allocator::AllocatorKind; -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; +use rustc_data_structures::{ + fx::{FxHashMap, FxIndexMap}, + stable_set::StableSet, +}; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def::DefKind; diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 84b4a803403f9..00ed3f4d7964f 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -898,7 +898,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { // We always collect the lib features declared in the current crate, even if there are // no unknown features, because the collection also does feature attribute validation. - let local_defined_features = tcx.lib_features(()).to_vec(); + let local_defined_features = tcx.lib_features(()).to_vec(tcx); if !remaining_lib_features.is_empty() { check_features(&mut remaining_lib_features, &local_defined_features); diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index afb19d7df9fce..00c44f1ee7108 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -8,6 +8,7 @@ use crate::late::diagnostics::{ForLifetimeSpanType, MissingLifetimeSpot}; use rustc_ast::walk_list; +use rustc_ast_lowering::ResolverAstLowering; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_errors::{struct_span_err, Applicability, Diagnostic}; use rustc_hir as hir; @@ -468,14 +469,14 @@ fn do_resolve( named_region_map } -fn convert_named_region_map(named_region_map: NamedRegionMap) -> ResolveLifetimes { +fn convert_named_region_map(named_region_map: NamedRegionMap, tcx: TyCtxt<'_>) -> ResolveLifetimes { let mut rl = ResolveLifetimes::default(); - + let hcx = tcx.create_stable_hashing_context(); for (hir_id, v) in named_region_map.defs { let map = rl.defs.entry(hir_id.owner).or_default(); map.insert(hir_id.local_id, v); } - for hir_id in named_region_map.late_bound { + for hir_id in named_region_map.late_bound.sorted_vector(&hcx) { let map = rl.late_bound.entry(hir_id.owner).or_default(); map.insert(hir_id.local_id); } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index a09a225a2b5d7..f239ec1a9a9ea 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -24,6 +24,7 @@ #[macro_use] extern crate tracing; +use rustc_data_structures::stable_set::StableSet; pub use rustc_hir::def::{Namespace, PerNS}; use Determinacy::*; @@ -975,7 +976,7 @@ pub struct Resolver<'a> { underscore_disambiguator: u32, /// Maps glob imports to the names of items actually imported. - glob_map: FxHashMap>, + glob_map: FxHashMap>, /// Visibilities in "lowered" form, for all entities that have them. visibilities: FxHashMap, used_imports: FxHashSet, diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index 19d52f430fcd5..e00fed5a74fd5 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -312,7 +312,7 @@ fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool { } } -fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &FxHashSet { +fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &StableSet { &*tcx.typeck(def_id).used_trait_imports } diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs index 72a50d02ad88f..e4d2386af6dc7 100644 --- a/compiler/rustc_typeck/src/check/writeback.rs +++ b/compiler/rustc_typeck/src/check/writeback.rs @@ -425,8 +425,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let fcx_typeck_results = self.fcx.typeck_results.borrow(); let fcx_coercion_casts = fcx_typeck_results.coercion_casts(); assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner); + let hcx = self.tcx().create_stable_hashing_context(); - for local_id in fcx_coercion_casts { + for local_id in fcx_coercion_casts.sorted_vector(&hcx) { self.typeck_results.set_coercion_cast(*local_id); } } From fb669bcb6d509030dfa041a24da6979306bb67a2 Mon Sep 17 00:00:00 2001 From: Hameer Abbasi Date: Sun, 27 Mar 2022 16:07:00 +0200 Subject: [PATCH 3/4] Do some suggested changes, push to show compilation errors. --- compiler/rustc_codegen_ssa/src/base.rs | 15 ++++++--------- compiler/rustc_data_structures/src/stable_set.rs | 16 ++++++++++++++++ compiler/rustc_middle/src/middle/stability.rs | 9 +-------- compiler/rustc_middle/src/ty/context.rs | 4 ++-- compiler/rustc_middle/src/ty/mod.rs | 3 +-- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- 6 files changed, 27 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index f7dae40efb2af..4316555b1a95d 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -910,17 +910,14 @@ pub fn provide(providers: &mut Providers) { }; let (defids, _) = tcx.collect_and_partition_mono_items(cratenum); - for id in defids.sorted_vector() { + if defids.any(|x| { let CodegenFnAttrs { optimize, .. } = tcx.codegen_fn_attrs(*id); - match optimize { - attr::OptimizeAttr::None => continue, - attr::OptimizeAttr::Size => continue, - attr::OptimizeAttr::Speed => { - return for_speed; - } - } + optimize == attr::OptimizeAttr::Speed + }) { + for_speed + } else { + tcx.sess.opts.optimize } - tcx.sess.opts.optimize }; } diff --git a/compiler/rustc_data_structures/src/stable_set.rs b/compiler/rustc_data_structures/src/stable_set.rs index abb4c9c594e40..4b6b0c3e168d8 100644 --- a/compiler/rustc_data_structures/src/stable_set.rs +++ b/compiler/rustc_data_structures/src/stable_set.rs @@ -102,6 +102,22 @@ impl StableSet { pub fn contains(&self, value: &T) -> bool { self.base.contains(value) } + + #[inline] + pub fn any(&self, f: F) -> bool + where + F: FnMut(&T) -> bool, + { + self.base.iter().any(f) + } + + #[inline] + pub fn all(&self, f: F) -> bool + where + F: FnMut(&T) -> bool, + { + self.base.iter().all(f) + } } impl HashStable for StableSet diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index e9c9e25f2a0bc..fd6e241346db8 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -7,13 +7,12 @@ use crate::ty::{self, DefIdTree, TyCtxt}; use rustc_ast::NodeId; use rustc_attr::{self as attr, ConstStability, Deprecation, Stability}; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::stable_set::StableSet; use rustc_errors::{Applicability, Diagnostic}; use rustc_feature::GateIssue; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX}; -use rustc_hir::{self, def_id::CrateNum, HirId}; +use rustc_hir::{self, HirId}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE}; use rustc_session::lint::{BuiltinLintDiagnostics, Level, Lint, LintBuffer}; @@ -64,12 +63,6 @@ pub struct Index { pub stab_map: FxHashMap, pub const_stab_map: FxHashMap, pub depr_map: FxHashMap, - - /// Maps for each crate whether it is part of the staged API. - pub staged_api: FxHashMap, - - /// Features enabled for this crate. - pub active_features: StableSet, } impl Index { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 946b8863ccaa9..1f84bcd628883 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -31,7 +31,7 @@ use rustc_data_structures::memmap::Mmap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::stable_set::StableSet; +use rustc_data_structures::stable_set::{FxHashSet, StableSet}; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{self, Lock, Lrc, WorkerLocal}; use rustc_data_structures::vec_map::VecMap; @@ -2209,7 +2209,7 @@ impl<'tcx> TyCtxt<'tcx> { /// to identify which traits may define a given associated type to help avoid cycle errors. /// Returns a `DefId` iterator. fn super_traits_of(self, trait_def_id: DefId) -> impl Iterator + 'tcx { - let mut set = StableSet::default(); + let mut set = FxHashSet::default(); let mut stack = vec![trait_def_id]; set.insert(trait_def_id); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 413bfd472120e..6e3dc92a2332f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -18,7 +18,6 @@ pub use adt::*; pub use assoc::*; pub use generics::*; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::stable_set::StableSet; pub use vtable::*; use crate::metadata::ModChild; @@ -136,7 +135,7 @@ pub struct ResolverOutputs { pub maybe_unused_trait_imports: FxHashSet, pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>, pub reexport_map: FxHashMap>, - pub glob_map: FxHashMap>, + pub glob_map: FxHashMap>, /// Extern prelude entries. The value is `true` if the entry was introduced /// via `extern crate` item and not `--extern` option or compiler built-in. pub extern_prelude: FxHashMap, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index d396473890530..6065cdd3a4a88 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2765,7 +2765,7 @@ fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap { let hcx = tcx.create_stable_hashing_context(); for symbol_set in tcx.resolutions(()).glob_map.values() { - for symbol in symbol_set.sorted_vector(&hcx) { + for symbol in symbol_set { unique_symbols_rev.insert((Namespace::TypeNS, *symbol), None); unique_symbols_rev.insert((Namespace::ValueNS, *symbol), None); unique_symbols_rev.insert((Namespace::MacroNS, *symbol), None); From d505d55ffbd109f73c01331f12662342d9ccdc81 Mon Sep 17 00:00:00 2001 From: Hameer Abbasi Date: Fri, 8 Apr 2022 18:59:25 +0200 Subject: [PATCH 4/4] Add stable iteration API. --- compiler/rustc_data_structures/src/lib.rs | 1 + .../src/stable_iterator.rs | 73 +++++++++++++++++++ .../rustc_data_structures/src/stable_set.rs | 43 +++++++---- compiler/rustc_middle/src/ty/context.rs | 4 +- compiler/rustc_middle/src/ty/print/pretty.rs | 1 - compiler/rustc_resolve/src/late/lifetimes.rs | 3 +- 6 files changed, 107 insertions(+), 18 deletions(-) create mode 100644 compiler/rustc_data_structures/src/stable_iterator.rs diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 1a3fe65252156..a07714af785ad 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -87,6 +87,7 @@ pub mod svh; pub use ena::snapshot_vec; pub mod memmap; pub mod sorted_map; +pub mod stable_iterator; pub mod stable_set; #[macro_use] pub mod stable_hasher; diff --git a/compiler/rustc_data_structures/src/stable_iterator.rs b/compiler/rustc_data_structures/src/stable_iterator.rs new file mode 100644 index 0000000000000..e6ef24e6c2a11 --- /dev/null +++ b/compiler/rustc_data_structures/src/stable_iterator.rs @@ -0,0 +1,73 @@ +use std::iter::Chain; + +use crate::stable_hasher::ToStableHashKey; + +pub struct StableIterator { + inner: I, +} + +impl> StableIterator { + #[inline] + pub fn map U>(self, f: F) -> StableIterator> { + StableIterator { inner: self.inner.map(f) } + } + + #[inline] + pub fn into_sorted(self, hcx: &HCX) -> Vec + where + T: ToStableHashKey, + { + let mut items: Vec = self.inner.collect(); + items.sort_by_cached_key(|x| x.to_stable_hash_key(hcx)); + items + } + + #[inline] + pub fn any bool>(&mut self, f: F) -> bool { + self.inner.any(f) + } + + #[inline] + pub fn all bool>(&mut self, f: F) -> bool { + self.inner.all(f) + } + + #[inline] + pub fn chain>(self, other: StableIterator) -> StableChain { + self.inner.chain(other.inner).into() + } +} + +pub trait IntoStableIterator { + type IntoIter: Iterator; + fn into_stable_iter(self) -> StableIterator; +} + +impl> IntoStableIterator for S { + type IntoIter = I; + + #[inline] + fn into_stable_iter(self) -> StableIterator { + StableIterator { inner: self.into_iter() } + } +} + +pub struct StableChain { + inner: Chain, +} + +impl> IntoStableIterator for StableChain { + type IntoIter = Chain; + + #[inline] + fn into_stable_iter(self) -> StableIterator { + self.inner.into_stable_iter() + } +} + +impl From> for StableChain { + #[inline] + fn from(inner: Chain) -> Self { + Self { inner } + } +} diff --git a/compiler/rustc_data_structures/src/stable_set.rs b/compiler/rustc_data_structures/src/stable_set.rs index 4b6b0c3e168d8..e777ec3920fe4 100644 --- a/compiler/rustc_data_structures/src/stable_set.rs +++ b/compiler/rustc_data_structures/src/stable_set.rs @@ -1,9 +1,11 @@ pub use rustc_hash::FxHashSet; use std::borrow::Borrow; +use std::collections::hash_set; use std::fmt; use std::hash::Hash; use crate::stable_hasher::{stable_hash_reduce, HashStable, StableHasher, ToStableHashKey}; +use crate::stable_iterator::{IntoStableIterator, StableIterator}; /// A deterministic wrapper around FxHashSet that does not provide iteration support. /// @@ -103,20 +105,8 @@ impl StableSet { self.base.contains(value) } - #[inline] - pub fn any(&self, f: F) -> bool - where - F: FnMut(&T) -> bool, - { - self.base.iter().any(f) - } - - #[inline] - pub fn all(&self, f: F) -> bool - where - F: FnMut(&T) -> bool, - { - self.base.iter().all(f) + pub fn stable_iter<'a>(&'a self) -> StableIterator> { + (&self).into_stable_iter() } } @@ -143,6 +133,31 @@ where } } +impl IntoStableIterator for StableSet { + type IntoIter = hash_set::IntoIter; + #[inline] + fn into_stable_iter(self) -> StableIterator { + self.base.into_stable_iter() + } +} + +impl<'a, T: Eq + Hash> IntoStableIterator for &'a StableSet { + type IntoIter = hash_set::Iter<'a, T>; + #[inline] + fn into_stable_iter(self) -> StableIterator { + self.base.iter().into_stable_iter() + } +} + +impl From> for StableSet +where + T: Eq + Hash, +{ + fn from(base: FxHashSet) -> Self { + Self { base: base } + } +} + impl Extend for StableSet where T: Eq + Hash, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1f84bcd628883..2aac2ac73b0e8 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2952,7 +2952,9 @@ pub fn provide(providers: &mut ty::query::Providers) { providers.maybe_unused_extern_crates = |tcx, ()| &tcx.resolutions(()).maybe_unused_extern_crates[..]; providers.names_imported_by_glob_use = |tcx, id| { - tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default()) + &StableSet::from( + tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default()), + ) }; providers.extern_mod_stmt_cnum = diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 6065cdd3a4a88..9a9c529f24552 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2763,7 +2763,6 @@ fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap { let unique_symbols_rev: &mut FxHashMap<(Namespace, Symbol), Option> = &mut FxHashMap::default(); - let hcx = tcx.create_stable_hashing_context(); for symbol_set in tcx.resolutions(()).glob_map.values() { for symbol in symbol_set { unique_symbols_rev.insert((Namespace::TypeNS, *symbol), None); diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 00c44f1ee7108..0bff85f531d72 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -469,9 +469,8 @@ fn do_resolve( named_region_map } -fn convert_named_region_map(named_region_map: NamedRegionMap, tcx: TyCtxt<'_>) -> ResolveLifetimes { +fn convert_named_region_map(named_region_map: NamedRegionMap) -> ResolveLifetimes { let mut rl = ResolveLifetimes::default(); - let hcx = tcx.create_stable_hashing_context(); for (hir_id, v) in named_region_map.defs { let map = rl.defs.entry(hir_id.owner).or_default(); map.insert(hir_id.local_id, v);