diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 6469f389bf91b..370fdcad45997 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -7,6 +7,8 @@ //! `tcx.inherent_impls(def_id)`). That value, however, //! is computed by selecting an idea from this table. +use hir::def_id::LOCAL_CRATE; +use hir::{ItemId, OwnerId}; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -19,8 +21,8 @@ use rustc_span::Span; /// On-demand query: yields a map containing all types mapped to their inherent impls. pub fn crate_inherent_impls(tcx: TyCtxt<'_>, (): ()) -> CrateInherentImpls { let mut collect = InherentCollect { tcx, impls_map: Default::default() }; - for id in tcx.hir().items() { - collect.check_item(id); + for id in tcx.impls_in_crate(LOCAL_CRATE) { + collect.check_item(ItemId { owner_id: OwnerId { def_id: id.expect_local() } }); } collect.impls_map } @@ -177,9 +179,7 @@ impl<'tcx> InherentCollect<'tcx> { } fn check_item(&mut self, id: hir::ItemId) { - if !matches!(self.tcx.def_kind(id.owner_id), DefKind::Impl) { - return; - } + debug_assert!(matches!(self.tcx.def_kind(id.owner_id), DefKind::Impl)); let item = self.tcx.hir().item(id); let hir::ItemKind::Impl(hir::Impl { of_trait: None, self_ty: ty, ref items, .. }) = item.kind else { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index a8000aa3c8a83..d707403dab2de 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -4,10 +4,9 @@ use crate::rmeta::table::TableBuilder; use crate::rmeta::*; use rustc_ast::Attribute; -use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::memmap::{Mmap, MmapMut}; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator}; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_hir as hir; @@ -1896,42 +1895,27 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let mut fx_hash_map: FxHashMap)>> = FxHashMap::default(); - for id in tcx.hir().items() { - if matches!(tcx.def_kind(id.owner_id), DefKind::Impl) { - if let Some(trait_ref) = tcx.impl_trait_ref(id.owner_id) { - let trait_ref = trait_ref.subst_identity(); - - let simplified_self_ty = fast_reject::simplify_type( - self.tcx, - trait_ref.self_ty(), - TreatParams::AsInfer, - ); - - fx_hash_map - .entry(trait_ref.def_id) - .or_default() - .push((id.owner_id.def_id.local_def_index, simplified_self_ty)); - } + for id in tcx.impls_in_crate(LOCAL_CRATE) { + if let Some(trait_ref) = tcx.impl_trait_ref(id) { + let trait_ref = trait_ref.subst_identity(); + + let simplified_self_ty = + fast_reject::simplify_type(self.tcx, trait_ref.self_ty(), TreatParams::AsInfer); + + fx_hash_map + .entry(trait_ref.def_id) + .or_default() + .push((id.expect_local().local_def_index, simplified_self_ty)); } } - let mut all_impls: Vec<_> = fx_hash_map.into_iter().collect(); - - // Bring everything into deterministic order for hashing - all_impls.sort_by_cached_key(|&(trait_def_id, _)| tcx.def_path_hash(trait_def_id)); + let all_impls: Vec<_> = fx_hash_map.into_iter().collect(); let all_impls: Vec<_> = all_impls .into_iter() - .map(|(trait_def_id, mut impls)| { - // Bring everything into deterministic order for hashing - impls.sort_by_cached_key(|&(index, _)| { - tcx.hir().def_path_hash(LocalDefId { local_def_index: index }) - }); - - TraitImpls { - trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index), - impls: self.lazy_array(&impls), - } + .map(|(trait_def_id, impls)| TraitImpls { + trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index), + impls: self.lazy_array(&impls), }) .collect(); @@ -1942,22 +1926,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("EncodeContext::encode_traits_and_impls()"); empty_proc_macro!(self); let tcx = self.tcx; - let mut all_impls: Vec<_> = tcx.crate_inherent_impls(()).incoherent_impls.iter().collect(); - tcx.with_stable_hashing_context(|mut ctx| { - all_impls.sort_by_cached_key(|&(&simp, _)| { - let mut hasher = StableHasher::new(); - simp.hash_stable(&mut ctx, &mut hasher); - hasher.finish::() - }) - }); + let all_impls: Vec<_> = tcx.crate_inherent_impls(()).incoherent_impls.iter().collect(); let all_impls: Vec<_> = all_impls .into_iter() .map(|(&simp, impls)| { - let mut impls: Vec<_> = + let impls: Vec<_> = impls.into_iter().map(|def_id| def_id.local_def_index).collect(); - impls.sort_by_cached_key(|&local_def_index| { - tcx.hir().def_path_hash(LocalDefId { local_def_index }) - }); IncoherentImpls { self_ty: simp, impls: self.lazy_array(impls) } }) @@ -2279,10 +2253,22 @@ pub fn provide(providers: &mut Providers) { } } - // Bring everything into deterministic order. - traits.sort_by_cached_key(|&def_id| tcx.def_path_hash(def_id)); + // We don't need to sort, since the default order is source-code order. tcx.arena.alloc_slice(&traits) }, + impls_in_crate: |tcx, cnum| { + assert_eq!(cnum, LOCAL_CRATE); + + let mut impls = Vec::new(); + for id in tcx.hir().items() { + if matches!(tcx.def_kind(id.owner_id), DefKind::Impl) { + impls.push(id.owner_id.to_def_id()) + } + } + + // We don't need to sort, since the default order is source-code order. + tcx.arena.alloc_slice(&impls) + }, ..*providers } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index b3acf815e0c10..a7d71f9b5defb 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1809,6 +1809,13 @@ rustc_queries! { separate_provide_extern } + /// A list of all impls in a crate. + query impls_in_crate(_: CrateNum) -> &'tcx [DefId] { + eval_always + desc { "fetching trait to impl map in a crate" } + separate_provide_extern + } + /// The list of symbols exported from the given crate. /// /// - All names contained in `exported_symbols(cnum)` are guaranteed to diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs index 17763128cd143..dcf31a8751bfa 100644 --- a/src/tools/clippy/clippy_lints/src/same_name_method.rs +++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs @@ -1,7 +1,8 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{HirId, Impl, ItemKind, Node, Path, QPath, TraitRef, TyKind}; +use rustc_hir::def_id::LOCAL_CRATE; +use rustc_hir::{HirId, Impl, ItemId, ItemKind, Node, OwnerId, Path, QPath, TraitRef, TyKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::AssocKind; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -51,10 +52,14 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { fn check_crate_post(&mut self, cx: &LateContext<'tcx>) { let mut map = FxHashMap::::default(); - for id in cx.tcx.hir().items() { - if matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl) - && let item = cx.tcx.hir().item(id) - && let ItemKind::Impl(Impl { + for id in cx.tcx.impls_in_crate(LOCAL_CRATE) { + let id = ItemId { owner_id: OwnerId { def_id: id.expect_local() } }; + + debug_assert!(matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl)); + // impls_in_crate returns only items with DefKind::Impl, so this will always be true. + + let item = cx.tcx.hir().item(id); + if let ItemKind::Impl(Impl { items, of_trait, self_ty,