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);