From c12d46973830f6f91e668f69c5085a7ef7a93901 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Wed, 17 Jun 2026 15:12:28 +0300 Subject: [PATCH 1/5] Remove `lower_to_hir` query --- compiler/rustc_ast_lowering/src/lib.rs | 45 ++++++++++--------- compiler/rustc_hir/src/arena.rs | 1 + compiler/rustc_middle/src/hir/map.rs | 6 +-- compiler/rustc_middle/src/hir/mod.rs | 14 +++--- compiler/rustc_middle/src/queries.rs | 5 --- compiler/rustc_middle/src/ty/context.rs | 7 +++ ...ult-trait-shadow-cycle-issue-151358.stderr | 2 - .../query-cycle-printing-issue-151358.stderr | 2 - .../resolve/query-cycle-issue-124901.stderr | 2 - 9 files changed, 44 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b8d708d42ff10..3661ebc654000 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -43,6 +43,7 @@ use rustc_ast::node_id::NodeMap; use rustc_ast::visit::{self, Visitor}; use rustc_ast::{self as ast, *}; use rustc_attr_parsing::{AttributeParser, OmitDoc, Recovery, ShouldEmit}; +use rustc_data_structures::either::Either; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hash::{StableHash, StableHasher}; @@ -61,6 +62,7 @@ use rustc_hir::{ }; use rustc_index::{Idx, IndexVec}; use rustc_macros::extension; +use rustc_middle::hir::ProjectedMaybeOwner; use rustc_middle::queries::Providers; use rustc_middle::span_bug; use rustc_middle::ty::{PerOwnerResolverData, ResolverAstLowering, TyCtxt}; @@ -94,7 +96,7 @@ pub mod stability; pub fn provide(providers: &mut Providers) { providers.index_ast = index_ast; - providers.lower_to_hir = lower_to_hir; + providers.hir_owner = lower_to_hir; } struct LoweringContext<'a, 'hir> { @@ -615,7 +617,7 @@ fn index_ast<'tcx>( } #[instrument(level = "trace", skip(tcx))] -fn lower_to_hir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::MaybeOwner<'_> { +fn lower_to_hir<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ProjectedMaybeOwner<'tcx> { // Queries that borrow `resolver_for_lowering`. tcx.ensure_done().output_filenames(()); tcx.ensure_done().early_lint_checks(()); @@ -628,24 +630,21 @@ fn lower_to_hir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::MaybeOwner<'_> { // The item did not exist in the AST, it was created while lowering another item. // `parent_id` may be different from the direct parent of `def_id`, // for instance use-trees are lowered by the first sibling. - let mut parent_info = tcx.lower_to_hir(parent_id); - if let hir::MaybeOwner::NonOwner(hir_id) = parent_info { + let mut parent_info = tcx.hir_owner(parent_id); + if let ProjectedMaybeOwner::NonOwner(hir_id) = parent_info { // `parent_id` could also not be a owner either. // For instance if `def_id` is an enum variant field, // the direct parent is the enum variant. // In that case `hir_id.owner` point to the actual HIR owner // and skips all non-owner parents, so fetch the HIR associated to it. - parent_info = tcx.lower_to_hir(hir_id.owner); + parent_info = tcx.hir_owner(hir_id.owner); } let parent_info = parent_info.unwrap(); - *parent_info.children.get(&def_id).unwrap_or_else(|| { - panic!( - "{:?} does not appear in children of {:?}", - def_id, - parent_info.nodes.node().def_id() - ) - }) + let owner = parent_info.children.get(&def_id).unwrap(); + + tcx.feed_hir_attr_map(def_id, owner); + ProjectedMaybeOwner::new(*owner) }; let Some((resolver, node)) = resolver_and_node else { @@ -659,20 +658,26 @@ fn lower_to_hir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::MaybeOwner<'_> { let item = match &node { // The item existed in the AST. - AstOwner::Crate(c) => item_lowerer.lower_crate(&c), - AstOwner::Item(item) => item_lowerer.lower_item(&item), - AstOwner::TraitItem(item) => item_lowerer.lower_trait_item(&item), - AstOwner::ImplItem(item) => item_lowerer.lower_impl_item(&item), - AstOwner::ForeignItem(item) => item_lowerer.lower_foreign_item(&item), - AstOwner::NestedUseTree(owner_id) => fallback_to_ancestor(*owner_id), + AstOwner::Crate(c) => Either::Left(item_lowerer.lower_crate(&c)), + AstOwner::Item(item) => Either::Left(item_lowerer.lower_item(&item)), + AstOwner::TraitItem(item) => Either::Left(item_lowerer.lower_trait_item(&item)), + AstOwner::ImplItem(item) => Either::Left(item_lowerer.lower_impl_item(&item)), + AstOwner::ForeignItem(item) => Either::Left(item_lowerer.lower_foreign_item(&item)), + AstOwner::NestedUseTree(owner_id) => Either::Right(fallback_to_ancestor(*owner_id)), // The item existed in the AST, but is not a HIR owner. // Fetch the correct information from its parent. - AstOwner::NonOwner => fallback_to_ancestor(tcx.local_parent(def_id)), + AstOwner::NonOwner => Either::Right(fallback_to_ancestor(tcx.local_parent(def_id))), }; tcx.sess.time("drop_ast", || mem::drop(node)); - item + match item { + Either::Left(item) => { + tcx.feed_hir_attr_map(def_id, &item); + ProjectedMaybeOwner::new(item) + } + Either::Right(owner) => owner, + } } #[derive(Copy, Clone, PartialEq, Debug)] diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index 180cb6497e7ab..cf67e0c5e0459 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -9,6 +9,7 @@ macro_rules! arena_types { [] attribute: rustc_hir::Attribute, [] owner_info: rustc_hir::OwnerInfo<'tcx>, [] macro_def: rustc_ast::MacroDef, + [] children: rustc_data_structures::unord::UnordMap>, ]); ) } diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 785cf2548fda7..4fb2ec40fc0a4 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -1207,10 +1207,10 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh { let mut stable_hasher = StableHasher::new(); // hir_body_hash for owner in krate.owners() { - if let Some(info) = tcx.lower_to_hir(owner.def_id).as_owner() { - info.stable_hash(&mut hcx, &mut stable_hasher); - } + tcx.hir_owner(owner.def_id).stable_hash(&mut hcx, &mut stable_hasher); + tcx.hir_attr_map(owner).stable_hash(&mut hcx, &mut stable_hasher); } + upstream_crates.stable_hash(&mut hcx, &mut stable_hasher); source_file_names.stable_hash(&mut hcx, &mut stable_hasher); debugger_visualizers.stable_hash(&mut hcx, &mut stable_hasher); diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index a074ff3340275..a062989cad2b5 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -11,6 +11,7 @@ use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hash::{StableHash, StableHasher}; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{DynSend, DynSync, try_par_for_each_in}; +use rustc_data_structures::unord::UnordMap; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap, LocalModDefId}; use rustc_hir::lints::DelayedLints; @@ -403,6 +404,8 @@ pub struct ProjectedOwnerInfo<'tcx> { #[stable_hash(ignore)] delayed_lints: &'tcx Steal, + #[stable_hash(ignore)] + pub children: &'tcx UnordMap>, } impl<'tcx> ProjectedOwnerInfo<'tcx> { @@ -411,8 +414,9 @@ impl<'tcx> ProjectedOwnerInfo<'tcx> { parenting: &'tcx LocalDefIdMap, trait_map: &'tcx ItemLocalMap<&'tcx [TraitCandidate<'tcx>]>, delayed_lints: &'tcx Steal, + children: &'tcx UnordMap>, ) -> ProjectedOwnerInfo<'tcx> { - ProjectedOwnerInfo { nodes, parenting, trait_map, delayed_lints } + ProjectedOwnerInfo { nodes, parenting, trait_map, delayed_lints, children } } } @@ -430,6 +434,7 @@ impl<'tcx> ProjectedMaybeOwner<'tcx> { parenting: &o.parenting, trait_map: &o.trait_map, delayed_lints: &o.delayed_lints, + children: &o.children, }), MaybeOwner::NonOwner(hir_id) => ProjectedMaybeOwner::NonOwner(hir_id), } @@ -442,8 +447,8 @@ impl<'tcx> ProjectedMaybeOwner<'tcx> { } } - pub fn unwrap(&'tcx self) -> &'tcx ProjectedOwnerInfo<'tcx> { - self.as_owner().unwrap_or_else(|| panic!("Not a HIR owner")) + pub fn unwrap(&self) -> ProjectedOwnerInfo<'tcx> { + self.as_owner().copied().unwrap_or_else(|| panic!("Not a HIR owner")) } } @@ -451,9 +456,6 @@ pub fn provide(providers: &mut Providers) { providers.hir_crate_items = map::hir_crate_items; providers.crate_hash = map::crate_hash; providers.hir_module_items = map::hir_module_items; - providers.hir_attr_map = - |tcx, id| tcx.lower_to_hir(id).as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs); - providers.hir_owner = |tcx, def_id| ProjectedMaybeOwner::new(tcx.lower_to_hir(def_id)); providers.hir_owner_parent_q = |tcx, owner_id| tcx.hir_owner_parent_impl(owner_id); providers.def_span = |tcx, def_id| tcx.hir_span(tcx.local_def_id_to_hir_id(def_id)); providers.def_ident_span = |tcx, def_id| { diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index c01ff3d5d0561..62e54b975dc82 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -215,11 +215,6 @@ rustc_queries! { desc { "getting the source span" } } - query lower_to_hir(def_id: LocalDefId) -> hir::MaybeOwner<'tcx> { - eval_always - desc { "lowering HIR for `{}`", tcx.def_path_str(def_id) } - } - query hir_owner(def_id: LocalDefId) -> rustc_middle::hir::ProjectedMaybeOwner<'tcx> { desc { "getting owner for `{}`", tcx.def_path_str(def_id) } feedable diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index c6fa3801fb1bc..061bb5f7b8fb7 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -28,6 +28,7 @@ use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{ self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal, }; +use rustc_data_structures::unord::UnordMap; use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, MultiSpan}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId}; @@ -621,6 +622,11 @@ impl<'tcx> TyCtxt<'tcx> { } TyCtxtFeed { tcx: self, key }.visibility(vis.to_def_id()) } + + pub fn feed_hir_attr_map(self, def_id: LocalDefId, owner: &hir::MaybeOwner<'tcx>) { + TyCtxtFeed { tcx: self, key: hir::OwnerId { def_id } } + .hir_attr_map(owner.as_owner().map_or(hir::AttributeMap::EMPTY, |o| &o.attrs)); + } } impl<'tcx, K: Copy> TyCtxtFeed<'tcx, K> { @@ -648,6 +654,7 @@ impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> { self.tcx.arena.alloc(Default::default()), self.tcx.arena.alloc(Default::default()), self.tcx.arena.alloc(Steal::new(Default::default())), + self.tcx.hir_arena.alloc(UnordMap::>::default()), ))); self.feed_owner_id().hir_attr_map(hir::AttributeMap::EMPTY); diff --git a/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr b/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr index f224cd8f1063e..6063a1b603a93 100644 --- a/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr +++ b/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr @@ -1,7 +1,6 @@ error: internal compiler error: query cycle when printing cycle detected | = note: ...when getting owner for `Default` - = note: ...which requires lowering HIR for `Default`... = note: ...which requires perform lints prior to AST lowering... = note: ...which requires looking up span for `Default`... = note: ...which again requires getting owner for `Default`, completing the cycle @@ -11,7 +10,6 @@ error: internal compiler error: query cycle when printing cycle detected error[E0391]: cycle detected when getting the resolver for lowering | = note: ...which requires getting owner for `Default`... - = note: ...which requires lowering HIR for `Default`... = note: ...which requires perform lints prior to AST lowering... = note: ...which again requires getting the resolver for lowering, completing the cycle = note: for more information, see and diff --git a/tests/ui/query-system/query-cycle-printing-issue-151358.stderr b/tests/ui/query-system/query-cycle-printing-issue-151358.stderr index f224cd8f1063e..6063a1b603a93 100644 --- a/tests/ui/query-system/query-cycle-printing-issue-151358.stderr +++ b/tests/ui/query-system/query-cycle-printing-issue-151358.stderr @@ -1,7 +1,6 @@ error: internal compiler error: query cycle when printing cycle detected | = note: ...when getting owner for `Default` - = note: ...which requires lowering HIR for `Default`... = note: ...which requires perform lints prior to AST lowering... = note: ...which requires looking up span for `Default`... = note: ...which again requires getting owner for `Default`, completing the cycle @@ -11,7 +10,6 @@ error: internal compiler error: query cycle when printing cycle detected error[E0391]: cycle detected when getting the resolver for lowering | = note: ...which requires getting owner for `Default`... - = note: ...which requires lowering HIR for `Default`... = note: ...which requires perform lints prior to AST lowering... = note: ...which again requires getting the resolver for lowering, completing the cycle = note: for more information, see and diff --git a/tests/ui/resolve/query-cycle-issue-124901.stderr b/tests/ui/resolve/query-cycle-issue-124901.stderr index f224cd8f1063e..6063a1b603a93 100644 --- a/tests/ui/resolve/query-cycle-issue-124901.stderr +++ b/tests/ui/resolve/query-cycle-issue-124901.stderr @@ -1,7 +1,6 @@ error: internal compiler error: query cycle when printing cycle detected | = note: ...when getting owner for `Default` - = note: ...which requires lowering HIR for `Default`... = note: ...which requires perform lints prior to AST lowering... = note: ...which requires looking up span for `Default`... = note: ...which again requires getting owner for `Default`, completing the cycle @@ -11,7 +10,6 @@ error: internal compiler error: query cycle when printing cycle detected error[E0391]: cycle detected when getting the resolver for lowering | = note: ...which requires getting owner for `Default`... - = note: ...which requires lowering HIR for `Default`... = note: ...which requires perform lints prior to AST lowering... = note: ...which again requires getting the resolver for lowering, completing the cycle = note: for more information, see and From e8e2cd17bec82db2e51041557d6cd0297385c27c Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Thu, 18 Jun 2026 09:38:23 +0300 Subject: [PATCH 2/5] Revert "Remove `lower_to_hir` query" This reverts commit c12d46973830f6f91e668f69c5085a7ef7a93901. --- compiler/rustc_ast_lowering/src/lib.rs | 45 +++++++++---------- compiler/rustc_hir/src/arena.rs | 1 - compiler/rustc_middle/src/hir/map.rs | 6 +-- compiler/rustc_middle/src/hir/mod.rs | 14 +++--- compiler/rustc_middle/src/queries.rs | 5 +++ compiler/rustc_middle/src/ty/context.rs | 7 --- ...ult-trait-shadow-cycle-issue-151358.stderr | 2 + .../query-cycle-printing-issue-151358.stderr | 2 + .../resolve/query-cycle-issue-124901.stderr | 2 + 9 files changed, 40 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 3661ebc654000..b8d708d42ff10 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -43,7 +43,6 @@ use rustc_ast::node_id::NodeMap; use rustc_ast::visit::{self, Visitor}; use rustc_ast::{self as ast, *}; use rustc_attr_parsing::{AttributeParser, OmitDoc, Recovery, ShouldEmit}; -use rustc_data_structures::either::Either; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hash::{StableHash, StableHasher}; @@ -62,7 +61,6 @@ use rustc_hir::{ }; use rustc_index::{Idx, IndexVec}; use rustc_macros::extension; -use rustc_middle::hir::ProjectedMaybeOwner; use rustc_middle::queries::Providers; use rustc_middle::span_bug; use rustc_middle::ty::{PerOwnerResolverData, ResolverAstLowering, TyCtxt}; @@ -96,7 +94,7 @@ pub mod stability; pub fn provide(providers: &mut Providers) { providers.index_ast = index_ast; - providers.hir_owner = lower_to_hir; + providers.lower_to_hir = lower_to_hir; } struct LoweringContext<'a, 'hir> { @@ -617,7 +615,7 @@ fn index_ast<'tcx>( } #[instrument(level = "trace", skip(tcx))] -fn lower_to_hir<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ProjectedMaybeOwner<'tcx> { +fn lower_to_hir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::MaybeOwner<'_> { // Queries that borrow `resolver_for_lowering`. tcx.ensure_done().output_filenames(()); tcx.ensure_done().early_lint_checks(()); @@ -630,21 +628,24 @@ fn lower_to_hir<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ProjectedMaybeOw // The item did not exist in the AST, it was created while lowering another item. // `parent_id` may be different from the direct parent of `def_id`, // for instance use-trees are lowered by the first sibling. - let mut parent_info = tcx.hir_owner(parent_id); - if let ProjectedMaybeOwner::NonOwner(hir_id) = parent_info { + let mut parent_info = tcx.lower_to_hir(parent_id); + if let hir::MaybeOwner::NonOwner(hir_id) = parent_info { // `parent_id` could also not be a owner either. // For instance if `def_id` is an enum variant field, // the direct parent is the enum variant. // In that case `hir_id.owner` point to the actual HIR owner // and skips all non-owner parents, so fetch the HIR associated to it. - parent_info = tcx.hir_owner(hir_id.owner); + parent_info = tcx.lower_to_hir(hir_id.owner); } let parent_info = parent_info.unwrap(); - let owner = parent_info.children.get(&def_id).unwrap(); - - tcx.feed_hir_attr_map(def_id, owner); - ProjectedMaybeOwner::new(*owner) + *parent_info.children.get(&def_id).unwrap_or_else(|| { + panic!( + "{:?} does not appear in children of {:?}", + def_id, + parent_info.nodes.node().def_id() + ) + }) }; let Some((resolver, node)) = resolver_and_node else { @@ -658,26 +659,20 @@ fn lower_to_hir<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ProjectedMaybeOw let item = match &node { // The item existed in the AST. - AstOwner::Crate(c) => Either::Left(item_lowerer.lower_crate(&c)), - AstOwner::Item(item) => Either::Left(item_lowerer.lower_item(&item)), - AstOwner::TraitItem(item) => Either::Left(item_lowerer.lower_trait_item(&item)), - AstOwner::ImplItem(item) => Either::Left(item_lowerer.lower_impl_item(&item)), - AstOwner::ForeignItem(item) => Either::Left(item_lowerer.lower_foreign_item(&item)), - AstOwner::NestedUseTree(owner_id) => Either::Right(fallback_to_ancestor(*owner_id)), + AstOwner::Crate(c) => item_lowerer.lower_crate(&c), + AstOwner::Item(item) => item_lowerer.lower_item(&item), + AstOwner::TraitItem(item) => item_lowerer.lower_trait_item(&item), + AstOwner::ImplItem(item) => item_lowerer.lower_impl_item(&item), + AstOwner::ForeignItem(item) => item_lowerer.lower_foreign_item(&item), + AstOwner::NestedUseTree(owner_id) => fallback_to_ancestor(*owner_id), // The item existed in the AST, but is not a HIR owner. // Fetch the correct information from its parent. - AstOwner::NonOwner => Either::Right(fallback_to_ancestor(tcx.local_parent(def_id))), + AstOwner::NonOwner => fallback_to_ancestor(tcx.local_parent(def_id)), }; tcx.sess.time("drop_ast", || mem::drop(node)); - match item { - Either::Left(item) => { - tcx.feed_hir_attr_map(def_id, &item); - ProjectedMaybeOwner::new(item) - } - Either::Right(owner) => owner, - } + item } #[derive(Copy, Clone, PartialEq, Debug)] diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index cf67e0c5e0459..180cb6497e7ab 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -9,7 +9,6 @@ macro_rules! arena_types { [] attribute: rustc_hir::Attribute, [] owner_info: rustc_hir::OwnerInfo<'tcx>, [] macro_def: rustc_ast::MacroDef, - [] children: rustc_data_structures::unord::UnordMap>, ]); ) } diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 4fb2ec40fc0a4..785cf2548fda7 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -1207,10 +1207,10 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh { let mut stable_hasher = StableHasher::new(); // hir_body_hash for owner in krate.owners() { - tcx.hir_owner(owner.def_id).stable_hash(&mut hcx, &mut stable_hasher); - tcx.hir_attr_map(owner).stable_hash(&mut hcx, &mut stable_hasher); + if let Some(info) = tcx.lower_to_hir(owner.def_id).as_owner() { + info.stable_hash(&mut hcx, &mut stable_hasher); + } } - upstream_crates.stable_hash(&mut hcx, &mut stable_hasher); source_file_names.stable_hash(&mut hcx, &mut stable_hasher); debugger_visualizers.stable_hash(&mut hcx, &mut stable_hasher); diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index a062989cad2b5..a074ff3340275 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -11,7 +11,6 @@ use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hash::{StableHash, StableHasher}; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{DynSend, DynSync, try_par_for_each_in}; -use rustc_data_structures::unord::UnordMap; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap, LocalModDefId}; use rustc_hir::lints::DelayedLints; @@ -404,8 +403,6 @@ pub struct ProjectedOwnerInfo<'tcx> { #[stable_hash(ignore)] delayed_lints: &'tcx Steal, - #[stable_hash(ignore)] - pub children: &'tcx UnordMap>, } impl<'tcx> ProjectedOwnerInfo<'tcx> { @@ -414,9 +411,8 @@ impl<'tcx> ProjectedOwnerInfo<'tcx> { parenting: &'tcx LocalDefIdMap, trait_map: &'tcx ItemLocalMap<&'tcx [TraitCandidate<'tcx>]>, delayed_lints: &'tcx Steal, - children: &'tcx UnordMap>, ) -> ProjectedOwnerInfo<'tcx> { - ProjectedOwnerInfo { nodes, parenting, trait_map, delayed_lints, children } + ProjectedOwnerInfo { nodes, parenting, trait_map, delayed_lints } } } @@ -434,7 +430,6 @@ impl<'tcx> ProjectedMaybeOwner<'tcx> { parenting: &o.parenting, trait_map: &o.trait_map, delayed_lints: &o.delayed_lints, - children: &o.children, }), MaybeOwner::NonOwner(hir_id) => ProjectedMaybeOwner::NonOwner(hir_id), } @@ -447,8 +442,8 @@ impl<'tcx> ProjectedMaybeOwner<'tcx> { } } - pub fn unwrap(&self) -> ProjectedOwnerInfo<'tcx> { - self.as_owner().copied().unwrap_or_else(|| panic!("Not a HIR owner")) + pub fn unwrap(&'tcx self) -> &'tcx ProjectedOwnerInfo<'tcx> { + self.as_owner().unwrap_or_else(|| panic!("Not a HIR owner")) } } @@ -456,6 +451,9 @@ pub fn provide(providers: &mut Providers) { providers.hir_crate_items = map::hir_crate_items; providers.crate_hash = map::crate_hash; providers.hir_module_items = map::hir_module_items; + providers.hir_attr_map = + |tcx, id| tcx.lower_to_hir(id).as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs); + providers.hir_owner = |tcx, def_id| ProjectedMaybeOwner::new(tcx.lower_to_hir(def_id)); providers.hir_owner_parent_q = |tcx, owner_id| tcx.hir_owner_parent_impl(owner_id); providers.def_span = |tcx, def_id| tcx.hir_span(tcx.local_def_id_to_hir_id(def_id)); providers.def_ident_span = |tcx, def_id| { diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 62e54b975dc82..c01ff3d5d0561 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -215,6 +215,11 @@ rustc_queries! { desc { "getting the source span" } } + query lower_to_hir(def_id: LocalDefId) -> hir::MaybeOwner<'tcx> { + eval_always + desc { "lowering HIR for `{}`", tcx.def_path_str(def_id) } + } + query hir_owner(def_id: LocalDefId) -> rustc_middle::hir::ProjectedMaybeOwner<'tcx> { desc { "getting owner for `{}`", tcx.def_path_str(def_id) } feedable diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 061bb5f7b8fb7..c6fa3801fb1bc 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -28,7 +28,6 @@ use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{ self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal, }; -use rustc_data_structures::unord::UnordMap; use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, MultiSpan}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId}; @@ -622,11 +621,6 @@ impl<'tcx> TyCtxt<'tcx> { } TyCtxtFeed { tcx: self, key }.visibility(vis.to_def_id()) } - - pub fn feed_hir_attr_map(self, def_id: LocalDefId, owner: &hir::MaybeOwner<'tcx>) { - TyCtxtFeed { tcx: self, key: hir::OwnerId { def_id } } - .hir_attr_map(owner.as_owner().map_or(hir::AttributeMap::EMPTY, |o| &o.attrs)); - } } impl<'tcx, K: Copy> TyCtxtFeed<'tcx, K> { @@ -654,7 +648,6 @@ impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> { self.tcx.arena.alloc(Default::default()), self.tcx.arena.alloc(Default::default()), self.tcx.arena.alloc(Steal::new(Default::default())), - self.tcx.hir_arena.alloc(UnordMap::>::default()), ))); self.feed_owner_id().hir_attr_map(hir::AttributeMap::EMPTY); diff --git a/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr b/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr index 6063a1b603a93..f224cd8f1063e 100644 --- a/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr +++ b/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr @@ -1,6 +1,7 @@ error: internal compiler error: query cycle when printing cycle detected | = note: ...when getting owner for `Default` + = note: ...which requires lowering HIR for `Default`... = note: ...which requires perform lints prior to AST lowering... = note: ...which requires looking up span for `Default`... = note: ...which again requires getting owner for `Default`, completing the cycle @@ -10,6 +11,7 @@ error: internal compiler error: query cycle when printing cycle detected error[E0391]: cycle detected when getting the resolver for lowering | = note: ...which requires getting owner for `Default`... + = note: ...which requires lowering HIR for `Default`... = note: ...which requires perform lints prior to AST lowering... = note: ...which again requires getting the resolver for lowering, completing the cycle = note: for more information, see and diff --git a/tests/ui/query-system/query-cycle-printing-issue-151358.stderr b/tests/ui/query-system/query-cycle-printing-issue-151358.stderr index 6063a1b603a93..f224cd8f1063e 100644 --- a/tests/ui/query-system/query-cycle-printing-issue-151358.stderr +++ b/tests/ui/query-system/query-cycle-printing-issue-151358.stderr @@ -1,6 +1,7 @@ error: internal compiler error: query cycle when printing cycle detected | = note: ...when getting owner for `Default` + = note: ...which requires lowering HIR for `Default`... = note: ...which requires perform lints prior to AST lowering... = note: ...which requires looking up span for `Default`... = note: ...which again requires getting owner for `Default`, completing the cycle @@ -10,6 +11,7 @@ error: internal compiler error: query cycle when printing cycle detected error[E0391]: cycle detected when getting the resolver for lowering | = note: ...which requires getting owner for `Default`... + = note: ...which requires lowering HIR for `Default`... = note: ...which requires perform lints prior to AST lowering... = note: ...which again requires getting the resolver for lowering, completing the cycle = note: for more information, see and diff --git a/tests/ui/resolve/query-cycle-issue-124901.stderr b/tests/ui/resolve/query-cycle-issue-124901.stderr index 6063a1b603a93..f224cd8f1063e 100644 --- a/tests/ui/resolve/query-cycle-issue-124901.stderr +++ b/tests/ui/resolve/query-cycle-issue-124901.stderr @@ -1,6 +1,7 @@ error: internal compiler error: query cycle when printing cycle detected | = note: ...when getting owner for `Default` + = note: ...which requires lowering HIR for `Default`... = note: ...which requires perform lints prior to AST lowering... = note: ...which requires looking up span for `Default`... = note: ...which again requires getting owner for `Default`, completing the cycle @@ -10,6 +11,7 @@ error: internal compiler error: query cycle when printing cycle detected error[E0391]: cycle detected when getting the resolver for lowering | = note: ...which requires getting owner for `Default`... + = note: ...which requires lowering HIR for `Default`... = note: ...which requires perform lints prior to AST lowering... = note: ...which again requires getting the resolver for lowering, completing the cycle = note: for more information, see and From 257f1f1d442bdd3265684272bdb658a7d21ec5ee Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Thu, 18 Jun 2026 10:14:44 +0300 Subject: [PATCH 3/5] Make `lower_to_hir` `no_hash` --- compiler/rustc_middle/src/hir/map.rs | 3 ++- compiler/rustc_middle/src/queries.rs | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 785cf2548fda7..f6fe812d73f25 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -1207,8 +1207,9 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh { let mut stable_hasher = StableHasher::new(); // hir_body_hash for owner in krate.owners() { - if let Some(info) = tcx.lower_to_hir(owner.def_id).as_owner() { + if let Some(info) = tcx.hir_owner(owner.def_id).as_owner() { info.stable_hash(&mut hcx, &mut stable_hasher); + tcx.hir_attr_map(owner).stable_hash(&mut hcx, &mut stable_hasher); } } upstream_crates.stable_hash(&mut hcx, &mut stable_hasher); diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index c01ff3d5d0561..d748495cdcff8 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -217,6 +217,7 @@ rustc_queries! { query lower_to_hir(def_id: LocalDefId) -> hir::MaybeOwner<'tcx> { eval_always + no_hash desc { "lowering HIR for `{}`", tcx.def_path_str(def_id) } } From 52d4aa5f9d9fd63c393b0efe1885eb1a3da84d8c Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Thu, 18 Jun 2026 11:45:50 +0300 Subject: [PATCH 4/5] Remove hash from `hir::MaybeOwner` --- compiler/rustc_ast_lowering/src/lib.rs | 15 --------------- compiler/rustc_hir/src/hir.rs | 5 +---- compiler/rustc_hir/src/stable_hash_impls.rs | 11 +---------- 3 files changed, 2 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b8d708d42ff10..fbf32dfe8a9aa 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -45,7 +45,6 @@ use rustc_ast::{self as ast, *}; use rustc_attr_parsing::{AttributeParser, OmitDoc, Recovery, ShouldEmit}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sorted_map::SortedMap; -use rustc_data_structures::stable_hash::{StableHash, StableHasher}; use rustc_data_structures::steal::Steal; use rustc_data_structures::tagged_ptr::TaggedRef; use rustc_data_structures::unord::ExtendUnord; @@ -884,21 +883,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let nodes = hir::OwnerNodes { opt_hash: bodies_hash, nodes, bodies }; let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaque }; - let opt_hash = self.tcx.needs_hir_hash().then(|| { - self.tcx.with_stable_hashing_context(|mut hcx| { - let mut stable_hasher = StableHasher::new(); - bodies_hash.unwrap().stable_hash(&mut hcx, &mut stable_hasher); - attrs_hash.unwrap().stable_hash(&mut hcx, &mut stable_hasher); - // Do not hash delayed_lints. - parenting.stable_hash(&mut hcx, &mut stable_hasher); - trait_map.stable_hash(&mut hcx, &mut stable_hasher); - children.stable_hash(&mut hcx, &mut stable_hasher); - stable_hasher.finish() - }) - }); - self.arena.alloc(hir::OwnerInfo { - opt_hash, nodes, parenting, attrs, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 8d886e7ac6fbf..60a6ac7a202ae 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1738,9 +1738,6 @@ pub struct OwnerInfo<'hir> { /// WARNING: The delayed lints are not hashed as a part of the `OwnerInfo`, and therefore /// should only be accessed in `eval_always` queries. pub delayed_lints: Steal, - - // Only present when the crate hash is needed. - pub opt_hash: Option, } impl<'tcx> OwnerInfo<'tcx> { @@ -1750,7 +1747,7 @@ impl<'tcx> OwnerInfo<'tcx> { } } -#[derive(Copy, Clone, Debug, StableHash)] +#[derive(Copy, Clone, Debug)] pub enum MaybeOwner<'tcx> { Owner(&'tcx OwnerInfo<'tcx>), NonOwner(HirId), diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index 3eadf0744df33..afbbda45e305d 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -1,7 +1,7 @@ use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt, StableHasher}; use crate::HashIgnoredAttrId; -use crate::hir::{AttributeMap, OwnerInfo, OwnerNodes}; +use crate::hir::{AttributeMap, OwnerNodes}; // The following implementations of StableHash for `ItemId`, `TraitItemId`, and // `ImplItemId` deserve special attention. Normally we do not hash `NodeId`s within @@ -28,15 +28,6 @@ impl<'tcx> StableHash for AttributeMap<'tcx> { } } -impl<'tcx> StableHash for OwnerInfo<'tcx> { - fn stable_hash(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { - // We ignore the other fields since these refer to information included in - // `opt_hash` which is hashed in the collector and used for the crate hash. - let OwnerInfo { opt_hash, .. } = *self; - opt_hash.unwrap().stable_hash(hcx, hasher); - } -} - impl StableHash for HashIgnoredAttrId { fn stable_hash(&self, _hcx: &mut Hcx, _hasher: &mut StableHasher) { /* we don't hash HashIgnoredAttrId, we ignore them */ From 1d79bb729a0dc4c4df395ee9b6bdab5e2986af62 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Thu, 18 Jun 2026 15:49:13 +0300 Subject: [PATCH 5/5] Exclude no hash eval always queries from incremental compilation --- compiler/rustc_query_impl/src/execution.rs | 31 +++++++++++++++------ compiler/rustc_query_impl/src/query_impl.rs | 24 +++++++++++----- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index 5b59f005a4908..c3960278dce61 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -283,7 +283,7 @@ fn wait_for_query<'tcx, C: QueryCache>( /// Shared main part of both [`execute_query_incr_inner`] and [`execute_query_non_incr_inner`]. #[inline(never)] -fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>( +fn try_execute_query<'tcx, C: QueryCache, const INCR: bool, const NO_HASH_EVAL_ALWAYS: bool>( query: &'tcx QueryVTable<'tcx, C>, tcx: TyCtxt<'tcx>, span: Span, @@ -327,7 +327,7 @@ fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>( let (value, dep_node_index) = if INCR { execute_job_incr(query, tcx, key, dep_node.unwrap(), id) } else { - execute_job_non_incr(query, tcx, key, id) + execute_job_non_incr::(query, tcx, key, id) }; if query.feedable { @@ -409,18 +409,23 @@ fn check_feedable_consistency<'tcx, C: QueryCache>( // Fast path for when incr. comp. is off. #[inline(always)] -fn execute_job_non_incr<'tcx, C: QueryCache>( +fn execute_job_non_incr<'tcx, C: QueryCache, const NO_HASH_EVAL_ALWAYS: bool>( query: &'tcx QueryVTable<'tcx, C>, tcx: TyCtxt<'tcx>, key: C::Key, job_id: QueryJobId, ) -> (C::Value, DepNodeIndex) { - debug_assert!(!tcx.dep_graph.is_fully_enabled()); + debug_assert!(NO_HASH_EVAL_ALWAYS || !tcx.dep_graph.is_fully_enabled()); let prof_timer = tcx.prof.query_provider(); // Call the query provider. let value = start_query(job_id, query.depth_limit, || (query.invoke_provider_fn)(tcx, key)); - let dep_node_index = tcx.dep_graph.next_virtual_depnode_index(); + let dep_node_index = if NO_HASH_EVAL_ALWAYS { + DepNodeIndex::FOREVER_RED_NODE + } else { + tcx.dep_graph.next_virtual_depnode_index() + }; + prof_timer.finish_with_query_invocation_id(dep_node_index.into()); // Sanity: Fingerprint the key and the result to assert they don't contain anything unhashable. @@ -613,7 +618,17 @@ pub(super) fn execute_query_non_incr_inner<'tcx, C: QueryCache>( span: Span, key: C::Key, ) -> C::Value { - ensure_sufficient_stack(|| try_execute_query::(query, tcx, span, key, None).0) + ensure_sufficient_stack(|| try_execute_query::(query, tcx, span, key, None).0) +} + +#[inline(always)] +pub(super) fn execute_query_non_incr_no_hash_eval_always_inner<'tcx, C: QueryCache>( + query: &'tcx QueryVTable<'tcx, C>, + tcx: TyCtxt<'tcx>, + span: Span, + key: C::Key, +) -> C::Value { + ensure_sufficient_stack(|| try_execute_query::(query, tcx, span, key, None).0) } /// Called by a macro-generated impl of [`QueryVTable::execute_query_fn`], @@ -636,7 +651,7 @@ pub(super) fn execute_query_incr_inner<'tcx, C: QueryCache>( } let (result, dep_node_index) = ensure_sufficient_stack(|| { - try_execute_query::(query, tcx, span, key, Some(dep_node)) + try_execute_query::(query, tcx, span, key, Some(dep_node)) }); if let Some(dep_node_index) = dep_node_index { tcx.dep_graph.read_index(dep_node_index) @@ -660,7 +675,7 @@ pub(crate) fn force_query_dep_node<'tcx, C: QueryCache>( }; ensure_sufficient_stack(|| { - try_execute_query::(query, tcx, DUMMY_SP, key, Some(dep_node)) + try_execute_query::(query, tcx, DUMMY_SP, key, Some(dep_node)) }); // We did manage to recover a key and force the node, though it's up to diff --git a/compiler/rustc_query_impl/src/query_impl.rs b/compiler/rustc_query_impl/src/query_impl.rs index 3720d9fd80547..a58cf5c4ed205 100644 --- a/compiler/rustc_query_impl/src/query_impl.rs +++ b/compiler/rustc_query_impl/src/query_impl.rs @@ -58,13 +58,23 @@ macro_rules! define_queries { ) -> Option>> { #[cfg(debug_assertions)] let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered(); - crate::execution::execute_query_incr_inner( - &tcx.query_system.query_vtables.$name, - tcx, - span, - key, - mode - ) + + if cfg!(all($no_hash, $eval_always)) { + Some(crate::execution::execute_query_non_incr_no_hash_eval_always_inner( + &tcx.query_system.query_vtables.$name, + tcx, + span, + key, + )) + } else { + crate::execution::execute_query_incr_inner( + &tcx.query_system.query_vtables.$name, + tcx, + span, + key, + mode + ) + } } }