diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index b442483346d6c..57a99e74c21ad 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -177,7 +177,7 @@ fn exported_symbols_provider_local( // Can we skip the later sorting? let mut symbols: Vec<_> = tcx.with_stable_hashing_context(|hcx| { tcx.reachable_non_generics(LOCAL_CRATE) - .to_sorted(&hcx) + .to_sorted(&hcx, true) .into_iter() .map(|(&def_id, &info)| (ExportedSymbol::NonGeneric(def_id), info)) .collect() diff --git a/compiler/rustc_data_structures/src/unord.rs b/compiler/rustc_data_structures/src/unord.rs index 1e71629a7c4e0..d29b49872741c 100644 --- a/compiler/rustc_data_structures/src/unord.rs +++ b/compiler/rustc_data_structures/src/unord.rs @@ -14,7 +14,7 @@ use std::{ use crate::{ fingerprint::Fingerprint, - stable_hasher::{HashStable, StableHasher, ToStableHashKey}, + stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey}, }; /// `UnordItems` is the order-less version of `Iterator`. It only contains methods @@ -158,6 +158,7 @@ pub struct UnordSet { } impl Default for UnordSet { + #[inline] fn default() -> Self { Self { inner: FxHashSet::default() } } @@ -207,6 +208,46 @@ impl UnordSet { UnordItems(self.inner.into_iter()) } + #[inline] + pub fn to_sorted(&self, hcx: &HCX, cache_sort_key: bool) -> Vec<&V> + where + V: ToStableHashKey, + { + let mut items: Vec<&V> = self.inner.iter().collect(); + if cache_sort_key { + items.sort_by_cached_key(|k| k.to_stable_hash_key(hcx)); + } else { + items.sort_unstable_by_key(|k| k.to_stable_hash_key(hcx)); + } + + items + } + + #[inline] + pub fn to_sorted_stable_ord(&self) -> Vec + where + V: Ord + StableOrd + Copy, + { + let mut items: Vec = self.inner.iter().copied().collect(); + items.sort_unstable(); + items + } + + #[inline] + pub fn into_sorted(self, hcx: &HCX, cache_sort_key: bool) -> Vec + where + V: ToStableHashKey, + { + let mut items: Vec = self.inner.into_iter().collect(); + if cache_sort_key { + items.sort_by_cached_key(|k| k.to_stable_hash_key(hcx)); + } else { + items.sort_unstable_by_key(|k| k.to_stable_hash_key(hcx)); + } + + items + } + // We can safely extend this UnordSet from a set of unordered values because that // won't expose the internal ordering anywhere. #[inline] @@ -221,12 +262,14 @@ impl UnordSet { } impl Extend for UnordSet { + #[inline] fn extend>(&mut self, iter: T) { self.inner.extend(iter) } } impl FromIterator for UnordSet { + #[inline] fn from_iter>(iter: T) -> Self { UnordSet { inner: FxHashSet::from_iter(iter) } } @@ -254,24 +297,28 @@ pub struct UnordMap { } impl Default for UnordMap { + #[inline] fn default() -> Self { Self { inner: FxHashMap::default() } } } impl Extend<(K, V)> for UnordMap { + #[inline] fn extend>(&mut self, iter: T) { self.inner.extend(iter) } } impl FromIterator<(K, V)> for UnordMap { + #[inline] fn from_iter>(iter: T) -> Self { UnordMap { inner: FxHashMap::from_iter(iter) } } } impl> From> for UnordMap { + #[inline] fn from(items: UnordItems<(K, V), I>) -> Self { UnordMap { inner: FxHashMap::from_iter(items.0) } } @@ -351,30 +398,56 @@ impl UnordMap { self.inner.extend(items.0) } - pub fn to_sorted(&self, hcx: &HCX) -> Vec<(&K, &V)> + #[inline] + pub fn to_sorted(&self, hcx: &HCX, cache_sort_key: bool) -> Vec<(&K, &V)> where K: ToStableHashKey, { let mut items: Vec<(&K, &V)> = self.inner.iter().collect(); - items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx)); + if cache_sort_key { + items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx)); + } else { + items.sort_unstable_by_key(|(k, _)| k.to_stable_hash_key(hcx)); + } + items } - pub fn into_sorted(self, hcx: &HCX) -> Vec<(K, V)> + #[inline] + pub fn to_sorted_stable_ord(&self) -> Vec<(K, &V)> + where + K: Ord + StableOrd + Copy, + { + let mut items: Vec<(K, &V)> = self.inner.iter().map(|(&k, v)| (k, v)).collect(); + items.sort_unstable_by_key(|&(k, _)| k); + items + } + + #[inline] + pub fn into_sorted(self, hcx: &HCX, cache_sort_key: bool) -> Vec<(K, V)> where K: ToStableHashKey, { let mut items: Vec<(K, V)> = self.inner.into_iter().collect(); - items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx)); + if cache_sort_key { + items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx)); + } else { + items.sort_unstable_by_key(|(k, _)| k.to_stable_hash_key(hcx)); + } items } - pub fn values_sorted(&self, hcx: &HCX) -> impl Iterator + #[inline] + pub fn values_sorted(&self, hcx: &HCX, cache_sort_key: bool) -> impl Iterator where K: ToStableHashKey, { let mut items: Vec<(&K, &V)> = self.inner.iter().collect(); - items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx)); + if cache_sort_key { + items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx)); + } else { + items.sort_unstable_by_key(|(k, _)| k.to_stable_hash_key(hcx)); + } items.into_iter().map(|(_, v)| v) } } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 6e6b63beca2a7..250f4cd3f65fb 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -19,7 +19,6 @@ use rustc_middle::ty::TypeckResults; use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::Span; -use smallvec::SmallVec; use std::mem; use std::ops::ControlFlow; @@ -450,9 +449,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let common_hir_owner = fcx_typeck_results.hir_owner; let fcx_closure_kind_origins = - fcx_typeck_results.closure_kind_origins().items_in_stable_order(self.tcx()); + fcx_typeck_results.closure_kind_origins().items_in_stable_order(); - for (&local_id, origin) in fcx_closure_kind_origins { + for (local_id, origin) in fcx_closure_kind_origins { let hir_id = hir::HirId { owner: common_hir_owner, local_id }; let place_span = origin.0; let place = self.resolve(origin.1.clone(), &place_span); @@ -465,14 +464,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner); - self.tcx().with_stable_hashing_context(|hcx| { - let fcx_coercion_casts: SmallVec<[_; 32]> = - fcx_typeck_results.coercion_casts().items().cloned().into_sorted_small_vec(&hcx); - - for local_id in fcx_coercion_casts { - self.typeck_results.set_coercion_cast(local_id); - } - }); + let fcx_coercion_casts = fcx_typeck_results.coercion_casts().to_sorted_stable_ord(); + for local_id in fcx_coercion_casts { + self.typeck_results.set_coercion_cast(local_id); + } } fn visit_user_provided_tys(&mut self) { @@ -482,10 +477,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { if self.rustc_dump_user_substs { let sorted_user_provided_types = - fcx_typeck_results.user_provided_types().items_in_stable_order(self.tcx()); + fcx_typeck_results.user_provided_types().items_in_stable_order(); let mut errors_buffer = Vec::new(); - for (&local_id, c_ty) in sorted_user_provided_types { + for (local_id, c_ty) in sorted_user_provided_types { let hir_id = hir::HirId { owner: common_hir_owner, local_id }; if let ty::UserType::TypeOf(_, user_substs) = c_ty.value { @@ -661,10 +656,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner); let common_hir_owner = fcx_typeck_results.hir_owner; - let fcx_liberated_fn_sigs = - fcx_typeck_results.liberated_fn_sigs().items_in_stable_order(self.tcx()); + let fcx_liberated_fn_sigs = fcx_typeck_results.liberated_fn_sigs().items_in_stable_order(); - for (&local_id, &fn_sig) in fcx_liberated_fn_sigs { + for (local_id, &fn_sig) in fcx_liberated_fn_sigs { let hir_id = hir::HirId { owner: common_hir_owner, local_id }; let fn_sig = self.resolve(fn_sig, &hir_id); self.typeck_results.liberated_fn_sigs_mut().insert(hir_id, fn_sig); @@ -676,10 +670,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner); let common_hir_owner = fcx_typeck_results.hir_owner; - let fcx_fru_field_types = - fcx_typeck_results.fru_field_types().items_in_stable_order(self.tcx()); + let fcx_fru_field_types = fcx_typeck_results.fru_field_types().items_in_stable_order(); - for (&local_id, ftys) in fcx_fru_field_types { + for (local_id, ftys) in fcx_fru_field_types { let hir_id = hir::HirId { owner: common_hir_owner, local_id }; let ftys = self.resolve(ftys.clone(), &hir_id); self.typeck_results.fru_field_types_mut().insert(hir_id, ftys); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index c3292681cc6ab..5b6f327c5c2c0 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1188,7 +1188,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } let inherent_impls = tcx.with_stable_hashing_context(|hcx| { - tcx.crate_inherent_impls(()).inherent_impls.to_sorted(&hcx) + tcx.crate_inherent_impls(()).inherent_impls.to_sorted(&hcx, true) }); for (def_id, implementations) in inherent_impls { diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 0eaa47178c05d..2902c6dc556e4 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -27,7 +27,7 @@ use rustc_session::Session; use rustc_span::Span; use std::{collections::hash_map::Entry, hash::Hash, iter}; -use super::{RvalueScopes, TyCtxt}; +use super::RvalueScopes; #[derive(TyEncodable, TyDecodable, Debug, HashStable)] pub struct TypeckResults<'tcx> { @@ -575,9 +575,8 @@ impl<'a, V> LocalTableInContext<'a, V> { self.data.items().map(|(id, value)| (*id, value)) } - #[allow(rustc::pass_by_value)] - pub fn items_in_stable_order(&self, tcx: TyCtxt<'_>) -> Vec<(&'a ItemLocalId, &'a V)> { - tcx.with_stable_hashing_context(|hcx| self.data.to_sorted(&hcx)) + pub fn items_in_stable_order(&self) -> Vec<(ItemLocalId, &'a V)> { + self.data.to_sorted_stable_ord() } } diff --git a/src/tools/clippy/clippy_lints/src/inherent_impl.rs b/src/tools/clippy/clippy_lints/src/inherent_impl.rs index 81b37ce5dfc2d..e9b2e31a769ad 100644 --- a/src/tools/clippy/clippy_lints/src/inherent_impl.rs +++ b/src/tools/clippy/clippy_lints/src/inherent_impl.rs @@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl { let inherent_impls = cx .tcx - .with_stable_hashing_context(|hcx| cx.tcx.crate_inherent_impls(()).inherent_impls.to_sorted(&hcx)); + .with_stable_hashing_context(|hcx| cx.tcx.crate_inherent_impls(()).inherent_impls.to_sorted(&hcx, true)); for (_, impl_ids) in inherent_impls.into_iter().filter(|(&id, impls)| { impls.len() > 1 diff --git a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs index 1c61c6e551c35..3371b4cce32c1 100644 --- a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs +++ b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs @@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingTraitMethods { } cx.tcx.with_stable_hashing_context(|hcx| { - for assoc in provided.values_sorted(&hcx) { + for assoc in provided.values_sorted(&hcx, true) { let source_map = cx.tcx.sess.source_map(); let definition_span = source_map.guess_head_span(cx.tcx.def_span(assoc.def_id));