From c32c48114a8176064e7d7b5ea3ca14e2330861e8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 3 Feb 2026 14:18:08 +1100 Subject: [PATCH 01/10] Improve `is_ignored_attr`. It has a single use. It doesn't need to be public. It doesn't use `self` and so doesn't need to be in the trait. And `IGNORED_ATTRIBUTES` can be moved within it. --- compiler/rustc_query_system/src/ich/hcx.rs | 9 +-------- .../rustc_query_system/src/ich/impls_syntax.rs | 18 ++++++++++++++++-- compiler/rustc_query_system/src/ich/mod.rs | 12 ------------ 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_query_system/src/ich/hcx.rs b/compiler/rustc_query_system/src/ich/hcx.rs index 840f0b35266d0..f350db26eccc9 100644 --- a/compiler/rustc_query_system/src/ich/hcx.rs +++ b/compiler/rustc_query_system/src/ich/hcx.rs @@ -5,9 +5,7 @@ use rustc_hir::definitions::DefPathHash; use rustc_session::Session; use rustc_session::cstore::Untracked; use rustc_span::source_map::SourceMap; -use rustc_span::{BytePos, CachingSourceMapView, DUMMY_SP, SourceFile, Span, SpanData, Symbol}; - -use crate::ich; +use rustc_span::{BytePos, CachingSourceMapView, DUMMY_SP, SourceFile, Span, SpanData}; /// This is the context state available during incr. comp. hashing. It contains /// enough information to transform `DefId`s and `HirId`s into stable `DefPath`s (i.e., @@ -73,11 +71,6 @@ impl<'a> StableHashingContext<'a> { } } - #[inline] - pub fn is_ignored_attr(&self, name: Symbol) -> bool { - ich::IGNORED_ATTRIBUTES.contains(&name) - } - #[inline] pub fn hashing_controls(&self) -> HashingControls { self.hashing_controls.clone() diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs index fe6fb3d651946..3cd25f3a5b9c3 100644 --- a/compiler/rustc_query_system/src/ich/impls_syntax.rs +++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs @@ -3,7 +3,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hir::{self as hir, HashIgnoredAttrId}; -use rustc_span::SourceFile; +use rustc_span::{SourceFile, Symbol, sym}; use smallvec::SmallVec; use crate::ich::StableHashingContext; @@ -24,7 +24,7 @@ impl<'a> HashStable> for [hir::Attribute] { .filter(|attr| { attr.is_doc_comment().is_none() // FIXME(jdonszelmann) have a better way to handle ignored attrs - && !attr.name().is_some_and(|ident| hcx.is_ignored_attr(ident)) + && !attr.name().is_some_and(|ident| is_ignored_attr(ident)) }) .collect(); @@ -35,6 +35,20 @@ impl<'a> HashStable> for [hir::Attribute] { } } +#[inline] +fn is_ignored_attr(name: Symbol) -> bool { + const IGNORED_ATTRIBUTES: &[Symbol] = &[ + sym::cfg_trace, // FIXME(#138844) should this really be ignored? + sym::rustc_if_this_changed, + sym::rustc_then_this_would_need, + sym::rustc_clean, + sym::rustc_partition_reused, + sym::rustc_partition_codegened, + sym::rustc_expected_cgu_reuse, + ]; + IGNORED_ATTRIBUTES.contains(&name) +} + impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> { fn hash_attr_id(&mut self, _id: &HashIgnoredAttrId, _hasher: &mut StableHasher) { /* we don't hash HashIgnoredAttrId, we ignore them */ diff --git a/compiler/rustc_query_system/src/ich/mod.rs b/compiler/rustc_query_system/src/ich/mod.rs index 72a7f3b8f970a..99575299c9781 100644 --- a/compiler/rustc_query_system/src/ich/mod.rs +++ b/compiler/rustc_query_system/src/ich/mod.rs @@ -1,18 +1,6 @@ //! ICH - Incremental Compilation Hash -use rustc_span::{Symbol, sym}; - pub use self::hcx::StableHashingContext; mod hcx; mod impls_syntax; - -pub const IGNORED_ATTRIBUTES: &[Symbol] = &[ - sym::cfg_trace, // FIXME should this really be ignored? - sym::rustc_if_this_changed, - sym::rustc_then_this_would_need, - sym::rustc_clean, - sym::rustc_partition_reused, - sym::rustc_partition_codegened, - sym::rustc_expected_cgu_reuse, -]; From c9f827754a106f0fc82a57077ac96fc4dc2d5344 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 3 Feb 2026 14:56:41 +1100 Subject: [PATCH 02/10] Make `HashingControls` impl `Copy`. It has a single `bool` field. --- compiler/rustc_data_structures/src/stable_hasher.rs | 2 +- compiler/rustc_query_system/src/ich/hcx.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 3a64c924cc224..9fb4d4352c2f6 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -607,7 +607,7 @@ where /// result (for example, using a `Fingerprint` produced while /// hashing `Span`s when a `Fingerprint` without `Span`s is /// being requested) -#[derive(Clone, Hash, Eq, PartialEq, Debug)] +#[derive(Clone, Copy, Hash, Eq, PartialEq, Debug)] pub struct HashingControls { pub hash_spans: bool, } diff --git a/compiler/rustc_query_system/src/ich/hcx.rs b/compiler/rustc_query_system/src/ich/hcx.rs index f350db26eccc9..fb73178a726bc 100644 --- a/compiler/rustc_query_system/src/ich/hcx.rs +++ b/compiler/rustc_query_system/src/ich/hcx.rs @@ -73,7 +73,7 @@ impl<'a> StableHashingContext<'a> { #[inline] pub fn hashing_controls(&self) -> HashingControls { - self.hashing_controls.clone() + self.hashing_controls } } @@ -115,7 +115,7 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { #[inline] fn hashing_controls(&self) -> HashingControls { - self.hashing_controls.clone() + self.hashing_controls } } From cd3c9329fb57ca3e4eae4396b268937b102316c3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 3 Feb 2026 15:25:52 +1100 Subject: [PATCH 03/10] Fix control flow in `assert_default_hashing_controls`. Calling `match` on a struct is a really weird thing to do. As the name suggests, it's an assert, so let's write it as one. Also clarify the comment a little. --- compiler/rustc_span/src/hygiene.rs | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 05f4c8e268a9c..07a85ad75daa6 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -132,19 +132,21 @@ impl !PartialOrd for LocalExpnId {} /// to maintain separate versions of `ExpnData` hashes for each permutation /// of `HashingControls` settings. fn assert_default_hashing_controls(ctx: &impl HashStableContext, msg: &str) { - match ctx.hashing_controls() { - // Note that we require that `hash_spans` be set according to the global - // `-Z incremental-ignore-spans` option. Normally, this option is disabled, - // which will cause us to require that this method always be called with `Span` hashing - // enabled. - // - // Span hashing can also be disabled without `-Z incremental-ignore-spans`. - // This is the case for instance when building a hash for name mangling. - // Such configuration must not be used for metadata. - HashingControls { hash_spans } - if hash_spans != ctx.unstable_opts_incremental_ignore_spans() => {} - other => panic!("Attempted hashing of {msg} with non-default HashingControls: {other:?}"), - } + let hashing_controls = ctx.hashing_controls(); + let HashingControls { hash_spans } = hashing_controls; + + // Note that we require that `hash_spans` be the inverse of the global + // `-Z incremental-ignore-spans` option. Normally, this option is disabled, + // in which case `hash_spans` must be true. + // + // Span hashing can also be disabled without `-Z incremental-ignore-spans`. + // This is the case for instance when building a hash for name mangling. + // Such configuration must not be used for metadata. + assert_eq!( + hash_spans, + !ctx.unstable_opts_incremental_ignore_spans(), + "Attempted hashing of {msg} with non-default HashingControls: {hashing_controls:?}" + ); } /// A unique hash value associated to an expansion. From e2edce0221ecef2ef1aaa2e58158730151e58f53 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 3 Feb 2026 15:34:29 +1100 Subject: [PATCH 04/10] Remove `rustc_span::HashStableContext::hash_spans`. It reads the `HashingControls::span` field, but there is also the `hashing_controls` method. No need to have two different ways of doing it. --- compiler/rustc_query_system/src/ich/hcx.rs | 5 ----- compiler/rustc_span/src/lib.rs | 3 +-- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/compiler/rustc_query_system/src/ich/hcx.rs b/compiler/rustc_query_system/src/ich/hcx.rs index fb73178a726bc..ec416b8f807cb 100644 --- a/compiler/rustc_query_system/src/ich/hcx.rs +++ b/compiler/rustc_query_system/src/ich/hcx.rs @@ -85,11 +85,6 @@ impl<'a> HashStable> for ast::NodeId { } impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { - #[inline] - fn hash_spans(&self) -> bool { - self.hashing_controls.hash_spans - } - #[inline] fn unstable_opts_incremental_ignore_spans(&self) -> bool { self.incremental_ignore_spans diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index a178f3260d30c..0ad80b9d7879a 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -2799,7 +2799,6 @@ impl InnerSpan { /// instead of implementing everything in rustc_middle. pub trait HashStableContext { fn def_path_hash(&self, def_id: DefId) -> DefPathHash; - fn hash_spans(&self) -> bool; /// Accesses `sess.opts.unstable_opts.incremental_ignore_spans` since /// we don't have easy access to a `Session` fn unstable_opts_incremental_ignore_spans(&self) -> bool; @@ -2832,7 +2831,7 @@ where const TAG_INVALID_SPAN: u8 = 1; const TAG_RELATIVE_SPAN: u8 = 2; - if !ctx.hash_spans() { + if !ctx.hashing_controls().hash_spans { return; } From 7298e1736619078bd57fef427e23a3371902f972 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 3 Feb 2026 15:50:08 +1100 Subject: [PATCH 05/10] Remove `rustc_hir::HashStableContext::hash_attr_id`. It has a single impl, which does nothing, as you'd expect when hashing a type called `HashIgnoredAttrId`! So this commit just removes it, and `HashIgnoredAttrId::hash_stable` ends up doing nothing (with a comment) instead of calling the trait method to do nothing. --- compiler/rustc_hir/src/stable_hash_impls.rs | 8 +++----- compiler/rustc_query_system/src/ich/impls_syntax.rs | 6 +----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index 16e8bac3d8a4d..a3f4415ec343d 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -11,9 +11,7 @@ use crate::lints::DelayedLints; /// Requirements for a `StableHashingContext` to be used in this crate. /// This is a hack to allow using the `HashStable_Generic` derive macro /// instead of implementing everything in `rustc_middle`. -pub trait HashStableContext: rustc_ast::HashStableContext + rustc_abi::HashStableContext { - fn hash_attr_id(&mut self, id: &HashIgnoredAttrId, hasher: &mut StableHasher); -} +pub trait HashStableContext: rustc_ast::HashStableContext + rustc_abi::HashStableContext {} impl ToStableHashKey for BodyId { type KeyType = (DefPathHash, ItemLocalId); @@ -104,7 +102,7 @@ impl HashStable for Crate<'_> { } impl HashStable for HashIgnoredAttrId { - fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { - hcx.hash_attr_id(self, hasher) + fn hash_stable(&self, _hcx: &mut HirCtx, _hasher: &mut StableHasher) { + /* we don't hash HashIgnoredAttrId, we ignore them */ } } diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs index 3cd25f3a5b9c3..7a079272cfe69 100644 --- a/compiler/rustc_query_system/src/ich/impls_syntax.rs +++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs @@ -49,11 +49,7 @@ fn is_ignored_attr(name: Symbol) -> bool { IGNORED_ATTRIBUTES.contains(&name) } -impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> { - fn hash_attr_id(&mut self, _id: &HashIgnoredAttrId, _hasher: &mut StableHasher) { - /* we don't hash HashIgnoredAttrId, we ignore them */ - } -} +impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {} impl<'a> HashStable> for SourceFile { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { From 99b9f51725033a83653d99d04f0fc54cd67bd2a0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 3 Feb 2026 16:08:41 +1100 Subject: [PATCH 06/10] Merge two fields in `StableHashingContext`. The new type makes the behaviour clearer: we start with the cache in an "unused" form and then instantiate it once it is actually used. --- compiler/rustc_query_system/src/ich/hcx.rs | 24 +++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_query_system/src/ich/hcx.rs b/compiler/rustc_query_system/src/ich/hcx.rs index ec416b8f807cb..28d40b53b6907 100644 --- a/compiler/rustc_query_system/src/ich/hcx.rs +++ b/compiler/rustc_query_system/src/ich/hcx.rs @@ -7,6 +7,14 @@ use rustc_session::cstore::Untracked; use rustc_span::source_map::SourceMap; use rustc_span::{BytePos, CachingSourceMapView, DUMMY_SP, SourceFile, Span, SpanData}; +// Very often, we are hashing something that does not need the `CachingSourceMapView`, so we +// initialize it lazily. +#[derive(Clone)] +enum CachingSourceMap<'a> { + Unused(&'a SourceMap), + InUse(CachingSourceMapView<'a>), +} + /// This is the context state available during incr. comp. hashing. It contains /// enough information to transform `DefId`s and `HirId`s into stable `DefPath`s (i.e., /// a reference to the `TyCtxt`) and it holds a few caches for speeding up various @@ -17,10 +25,7 @@ pub struct StableHashingContext<'a> { // The value of `-Z incremental-ignore-spans`. // This field should only be used by `unstable_opts_incremental_ignore_span` incremental_ignore_spans: bool, - // Very often, we are hashing something that does not need the - // `CachingSourceMapView`, so we initialize it lazily. - raw_source_map: &'a SourceMap, - caching_source_map: Option>, + caching_source_map: CachingSourceMap<'a>, hashing_controls: HashingControls, } @@ -32,8 +37,7 @@ impl<'a> StableHashingContext<'a> { StableHashingContext { untracked, incremental_ignore_spans: sess.opts.unstable_opts.incremental_ignore_spans, - caching_source_map: None, - raw_source_map: sess.source_map(), + caching_source_map: CachingSourceMap::Unused(sess.source_map()), hashing_controls: HashingControls { hash_spans: hash_spans_initial }, } } @@ -63,10 +67,10 @@ impl<'a> StableHashingContext<'a> { #[inline] pub fn source_map(&mut self) -> &mut CachingSourceMapView<'a> { match self.caching_source_map { - Some(ref mut sm) => sm, - ref mut none => { - *none = Some(CachingSourceMapView::new(self.raw_source_map)); - none.as_mut().unwrap() + CachingSourceMap::InUse(ref mut sm) => sm, + CachingSourceMap::Unused(sm) => { + self.caching_source_map = CachingSourceMap::InUse(CachingSourceMapView::new(sm)); + self.source_map() // this recursive call will hit the `InUse` case } } } From f729340aab3443e54f9a66c7294b8295507c67d3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 3 Feb 2026 17:03:36 +1100 Subject: [PATCH 07/10] Inline and remove two `StableHashingContext` methods. They both have a single use. Also adjust a couple of visibilities. --- compiler/rustc_query_system/src/ich/hcx.rs | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_query_system/src/ich/hcx.rs b/compiler/rustc_query_system/src/ich/hcx.rs index 28d40b53b6907..56a5ac47f4cf9 100644 --- a/compiler/rustc_query_system/src/ich/hcx.rs +++ b/compiler/rustc_query_system/src/ich/hcx.rs @@ -51,21 +51,7 @@ impl<'a> StableHashingContext<'a> { } #[inline] - pub fn def_path_hash(&self, def_id: DefId) -> DefPathHash { - if let Some(def_id) = def_id.as_local() { - self.local_def_path_hash(def_id) - } else { - self.untracked.cstore.read().def_path_hash(def_id) - } - } - - #[inline] - pub fn local_def_path_hash(&self, def_id: LocalDefId) -> DefPathHash { - self.untracked.definitions.read().def_path_hash(def_id) - } - - #[inline] - pub fn source_map(&mut self) -> &mut CachingSourceMapView<'a> { + fn source_map(&mut self) -> &mut CachingSourceMapView<'a> { match self.caching_source_map { CachingSourceMap::InUse(ref mut sm) => sm, CachingSourceMap::Unused(sm) => { @@ -96,7 +82,11 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { #[inline] fn def_path_hash(&self, def_id: DefId) -> DefPathHash { - self.def_path_hash(def_id) + if let Some(def_id) = def_id.as_local() { + self.untracked.definitions.read().def_path_hash(def_id) + } else { + self.untracked.cstore.read().def_path_hash(def_id) + } } #[inline] From 93a1a8064d2385633c77a66cf6c2bdade0120a63 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 4 Feb 2026 15:10:42 +1100 Subject: [PATCH 08/10] Move some `impl`s. `HashStableContext` impls should be in `hcx.rs`, and `HashStable` impls should be in `impls_syntax.rs`. This commit moves a few that are in the wrong file. --- compiler/rustc_query_system/src/ich/hcx.rs | 13 ++++--------- compiler/rustc_query_system/src/ich/impls_syntax.rs | 12 +++++++----- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_query_system/src/ich/hcx.rs b/compiler/rustc_query_system/src/ich/hcx.rs index 56a5ac47f4cf9..397ec7994f181 100644 --- a/compiler/rustc_query_system/src/ich/hcx.rs +++ b/compiler/rustc_query_system/src/ich/hcx.rs @@ -1,5 +1,4 @@ -use rustc_ast as ast; -use rustc_data_structures::stable_hasher::{HashStable, HashingControls, StableHasher}; +use rustc_data_structures::stable_hasher::HashingControls; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::definitions::DefPathHash; use rustc_session::Session; @@ -67,13 +66,6 @@ impl<'a> StableHashingContext<'a> { } } -impl<'a> HashStable> for ast::NodeId { - #[inline] - fn hash_stable(&self, _: &mut StableHashingContext<'a>, _: &mut StableHasher) { - panic!("Node IDs should not appear in incremental state"); - } -} - impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { #[inline] fn unstable_opts_incremental_ignore_spans(&self) -> bool { @@ -108,4 +100,7 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { } } +impl<'a> rustc_abi::HashStableContext for StableHashingContext<'a> {} +impl<'a> rustc_ast::HashStableContext for StableHashingContext<'a> {} +impl<'a> rustc_hir::HashStableContext for StableHashingContext<'a> {} impl<'a> rustc_session::HashStableContext for StableHashingContext<'a> {} diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs index 7a079272cfe69..5592f65539716 100644 --- a/compiler/rustc_query_system/src/ich/impls_syntax.rs +++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs @@ -2,14 +2,18 @@ //! from various crates in no particular order. use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_hir::{self as hir, HashIgnoredAttrId}; use rustc_span::{SourceFile, Symbol, sym}; use smallvec::SmallVec; +use {rustc_ast as ast, rustc_hir as hir}; use crate::ich::StableHashingContext; -impl<'ctx> rustc_abi::HashStableContext for StableHashingContext<'ctx> {} -impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> {} +impl<'a> HashStable> for ast::NodeId { + #[inline] + fn hash_stable(&self, _: &mut StableHashingContext<'a>, _: &mut StableHasher) { + panic!("Node IDs should not appear in incremental state"); + } +} impl<'a> HashStable> for [hir::Attribute] { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { @@ -49,8 +53,6 @@ fn is_ignored_attr(name: Symbol) -> bool { IGNORED_ATTRIBUTES.contains(&name) } -impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {} - impl<'a> HashStable> for SourceFile { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { let SourceFile { From 09eb4973960822b93dff415dc385d1e4fb3c1150 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 4 Feb 2026 15:54:28 +1100 Subject: [PATCH 09/10] Remove `Resolver::create_stable_hashing_context`. It only has two uses. We can instead use `with_stable_hashing_context`, which has more than 30 uses. --- Cargo.lock | 1 - compiler/rustc_resolve/Cargo.toml | 1 - compiler/rustc_resolve/src/lib.rs | 5 --- compiler/rustc_resolve/src/macros.rs | 48 +++++++++++++++------------- 4 files changed, 26 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 23abc6626aaba..496ceb0b84037 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4570,7 +4570,6 @@ dependencies = [ "rustc_macros", "rustc_metadata", "rustc_middle", - "rustc_query_system", "rustc_session", "rustc_span", "smallvec", diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index 01e268d911d24..feb0a93d0788a 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -21,7 +21,6 @@ rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_metadata = { path = "../rustc_metadata" } rustc_middle = { path = "../rustc_middle" } -rustc_query_system = { path = "../rustc_query_system" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 36ec173cc571f..0912b46f473f4 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -72,7 +72,6 @@ use rustc_middle::ty::{ self, DelegationFnSig, DelegationInfo, Feed, MainDefinition, RegisteredTools, ResolverAstLowering, ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility, }; -use rustc_query_system::ich::StableHashingContext; use rustc_session::config::CrateType; use rustc_session::lint::builtin::PRIVATE_MACRO_USE; use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency}; @@ -1839,10 +1838,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ResolverOutputs { global_ctxt, ast_lowering } } - fn create_stable_hashing_context(&self) -> StableHashingContext<'_> { - StableHashingContext::new(self.tcx.sess, self.tcx.untracked()) - } - fn cstore(&self) -> FreezeReadGuard<'_, CStore> { CStore::from_tcx(self.tcx) } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index b933c2b9d0362..e0973271da52d 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -222,17 +222,19 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { ) -> LocalExpnId { let parent_module = parent_module_id.map(|module_id| self.local_def_id(module_id).to_def_id()); - let expn_id = LocalExpnId::fresh( - ExpnData::allow_unstable( - ExpnKind::AstPass(pass), - call_site, - self.tcx.sess.edition(), - features.into(), - None, - parent_module, - ), - self.create_stable_hashing_context(), - ); + let expn_id = self.tcx.with_stable_hashing_context(|hcx| { + LocalExpnId::fresh( + ExpnData::allow_unstable( + ExpnKind::AstPass(pass), + call_site, + self.tcx.sess.edition(), + features.into(), + None, + parent_module, + ), + hcx, + ) + }); let parent_scope = parent_module.map_or(self.empty_module, |def_id| self.expect_module(def_id)); @@ -322,17 +324,19 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { let span = invoc.span(); let def_id = if deleg_impl.is_some() { None } else { res.opt_def_id() }; - invoc_id.set_expn_data( - ext.expn_data( - parent_scope.expansion, - span, - fast_print_path(path), - kind, - def_id, - def_id.map(|def_id| self.macro_def_scope(def_id).nearest_parent_mod()), - ), - self.create_stable_hashing_context(), - ); + self.tcx.with_stable_hashing_context(|hcx| { + invoc_id.set_expn_data( + ext.expn_data( + parent_scope.expansion, + span, + fast_print_path(path), + kind, + def_id, + def_id.map(|def_id| self.macro_def_scope(def_id).nearest_parent_mod()), + ), + hcx, + ) + }); Ok(ext) } From e35fd451a090e01ae10331dcbf87f1813708a86d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 4 Feb 2026 16:55:23 +1100 Subject: [PATCH 10/10] Add a useful comment about the `RawList` stable hash cache. I tried removing it to see what happened. Not a good idea! --- compiler/rustc_middle/src/ty/impls_ty.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs index ac45ce887c9a7..95a1a1bf5bce5 100644 --- a/compiler/rustc_middle/src/ty/impls_ty.rs +++ b/compiler/rustc_middle/src/ty/impls_ty.rs @@ -20,6 +20,9 @@ where T: HashStable>, { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { + // Note: this cache makes an *enormous* performance difference on certain benchmarks. E.g. + // without it, compiling `diesel-2.2.10` can be 74% slower, and compiling + // `deeply-nested-multi` can be ~4,000x slower(!) thread_local! { static CACHE: RefCell> = RefCell::new(Default::default());