From bfe40ed753f18b89ec9eca60699e638279b9de7b Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Tue, 21 Apr 2026 23:53:45 +0000 Subject: [PATCH 1/8] Stop stealing ResolverAstLowering. --- compiler/rustc_ast_lowering/src/asm.rs | 2 +- compiler/rustc_ast_lowering/src/block.rs | 2 +- compiler/rustc_ast_lowering/src/contract.rs | 2 +- compiler/rustc_ast_lowering/src/delegation.rs | 13 +++++----- .../src/delegation/generics.rs | 6 ++--- compiler/rustc_ast_lowering/src/expr.rs | 4 +-- .../rustc_ast_lowering/src/expr/closure.rs | 2 +- compiler/rustc_ast_lowering/src/format.rs | 6 ++--- compiler/rustc_ast_lowering/src/item.rs | 10 +++---- compiler/rustc_ast_lowering/src/lib.rs | 26 ++++++++++--------- compiler/rustc_ast_lowering/src/pat.rs | 2 +- compiler/rustc_ast_lowering/src/path.rs | 2 +- compiler/rustc_driver_impl/src/pretty.rs | 4 +-- compiler/rustc_interface/src/passes.rs | 10 ++++--- compiler/rustc_middle/src/arena.rs | 8 +++--- compiler/rustc_middle/src/hir/map.rs | 2 +- compiler/rustc_middle/src/hir/mod.rs | 10 +++---- compiler/rustc_middle/src/queries.rs | 5 +++- compiler/rustc_middle/src/ty/context.rs | 2 +- .../rustc_passes/src/debugger_visualizer.rs | 3 +-- compiler/rustc_passes/src/lang_items.rs | 4 +-- src/librustdoc/core.rs | 2 +- 22 files changed, 68 insertions(+), 59 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 5628dffd51358..eff38fe124fe3 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -21,7 +21,7 @@ use crate::{ AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode, }; -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir> LoweringContext<'hir> { pub(crate) fn lower_inline_asm( &mut self, sp: Span, diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs index c70e7d3872d79..870b8897844aa 100644 --- a/compiler/rustc_ast_lowering/src/block.rs +++ b/compiler/rustc_ast_lowering/src/block.rs @@ -6,7 +6,7 @@ use smallvec::SmallVec; use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext}; -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir> LoweringContext<'hir> { pub(super) fn lower_block( &mut self, b: &Block, diff --git a/compiler/rustc_ast_lowering/src/contract.rs b/compiler/rustc_ast_lowering/src/contract.rs index 4b2ee21ca5980..6cd36142176cd 100644 --- a/compiler/rustc_ast_lowering/src/contract.rs +++ b/compiler/rustc_ast_lowering/src/contract.rs @@ -4,7 +4,7 @@ use thin_vec::thin_vec; use crate::LoweringContext; -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir> LoweringContext<'hir> { /// Lowered contracts are guarded with the `contract_checks` compiler flag, /// i.e. the flag turns into a boolean guard in the lowered HIR. The reason /// for not eliminating the contract code entirely when the `contract_checks` diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 44dd26180bd16..44c9e110c80c3 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -127,7 +127,8 @@ pub(crate) fn delegations_resolutions( ) -> FxIndexMap> { let krate = tcx.hir_crate(()); - let (resolver, ast_crate) = &*krate.delayed_resolver.borrow(); + let (resolver, _) = tcx.resolver_for_lowering(); + let ast_crate = &*krate.ast_krate.borrow(); // FIXME!!!(fn_delegation): make ast index lifetime same as resolver, // as it is too bad to reindex whole crate on each delegation lowering. @@ -179,7 +180,7 @@ fn check_for_cycles(tcx: TyCtxt<'_>, mut def_id: DefId, span: Span) -> Result<() } } -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir> LoweringContext<'hir> { fn is_method(&self, def_id: DefId, span: Span) -> bool { match self.tcx.def_kind(def_id) { DefKind::Fn => false, @@ -772,13 +773,13 @@ impl<'hir> LoweringContext<'_, 'hir> { } } -struct SelfResolver<'a, 'b, 'hir> { - ctxt: &'a mut LoweringContext<'b, 'hir>, +struct SelfResolver<'a, 'hir> { + ctxt: &'a mut LoweringContext<'hir>, path_id: NodeId, self_param_id: NodeId, } -impl SelfResolver<'_, '_, '_> { +impl SelfResolver<'_, '_> { fn try_replace_id(&mut self, id: NodeId) { if let Some(res) = self.ctxt.get_partial_res(id) && let Some(Res::Local(sig_id)) = res.full_res() @@ -789,7 +790,7 @@ impl SelfResolver<'_, '_, '_> { } } -impl<'ast> Visitor<'ast> for SelfResolver<'_, '_, '_> { +impl<'ast> Visitor<'ast> for SelfResolver<'_, '_> { fn visit_id(&mut self, id: NodeId) { self.try_replace_id(id); } diff --git a/compiler/rustc_ast_lowering/src/delegation/generics.rs b/compiler/rustc_ast_lowering/src/delegation/generics.rs index f8e3528750035..f5e4a7164d40f 100644 --- a/compiler/rustc_ast_lowering/src/delegation/generics.rs +++ b/compiler/rustc_ast_lowering/src/delegation/generics.rs @@ -114,7 +114,7 @@ impl DelegationGenericsKind { impl<'hir> HirOrTyGenerics<'hir> { pub(super) fn into_hir_generics( &mut self, - ctx: &mut LoweringContext<'_, 'hir>, + ctx: &mut LoweringContext<'hir>, span: Span, ) -> &mut HirOrTyGenerics<'hir> { if let HirOrTyGenerics::Ty(ty) = self { @@ -140,7 +140,7 @@ impl<'hir> HirOrTyGenerics<'hir> { pub(super) fn into_generic_args( &self, - ctx: &mut LoweringContext<'_, 'hir>, + ctx: &mut LoweringContext<'hir>, span: Span, ) -> &'hir hir::GenericArgs<'hir> { match self { @@ -203,7 +203,7 @@ impl<'hir> GenericsGenerationResults<'hir> { } } -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir> LoweringContext<'hir> { pub(super) fn uplift_delegation_generics( &mut self, delegation: &Delegation, diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 23c7159cb91fe..c2a570728a1a0 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -116,7 +116,7 @@ impl<'v> rustc_ast::visit::Visitor<'v> for WillCreateDefIdsVisitor { } } -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir> LoweringContext<'hir> { fn with_move_expr_bindings( &mut self, state: Option>, @@ -1169,7 +1169,7 @@ impl<'hir> LoweringContext<'_, 'hir> { whole_span: Span, ) -> hir::ExprKind<'hir> { // Return early in case of an ordinary assignment. - fn is_ordinary(lower_ctx: &mut LoweringContext<'_, '_>, lhs: &Expr) -> bool { + fn is_ordinary(lower_ctx: &mut LoweringContext<'_>, lhs: &Expr) -> bool { match &lhs.kind { ExprKind::Array(..) | ExprKind::Struct(..) diff --git a/compiler/rustc_ast_lowering/src/expr/closure.rs b/compiler/rustc_ast_lowering/src/expr/closure.rs index cc2c6ae2879c1..930eb0b475475 100644 --- a/compiler/rustc_ast_lowering/src/expr/closure.rs +++ b/compiler/rustc_ast_lowering/src/expr/closure.rs @@ -9,7 +9,7 @@ use super::{LoweringContext, MoveExprInitializerFinder, MoveExprState}; use crate::FnDeclKind; use crate::diagnostics::{ClosureCannotBeStatic, CoroutineTooManyParameters}; -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir> LoweringContext<'hir> { // Entry point for `ExprKind::Closure`. Plain closures go through // `lower_expr_plain_closure_with_move_exprs`, which can wrap the lowered // closure in `let` initializers for `move(...)`. Coroutine closures keep the diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index 602635af1324e..2332af6b1bccf 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -8,7 +8,7 @@ use rustc_span::{ByteSymbol, DesugaringKind, Ident, Span, Symbol, sym}; use super::LoweringContext; -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir> LoweringContext<'hir> { pub(crate) fn lower_format_args(&mut self, sp: Span, fmt: &FormatArgs) -> hir::ExprKind<'hir> { // Never call the const constructor of `fmt::Arguments` if the // format_args!() had any arguments _before_ flattening/inlining. @@ -230,7 +230,7 @@ enum ArgumentType { /// ::new_…(arg) /// ``` fn make_argument<'hir>( - ctx: &mut LoweringContext<'_, 'hir>, + ctx: &mut LoweringContext<'hir>, sp: Span, arg: &'hir hir::Expr<'hir>, ty: ArgumentType, @@ -277,7 +277,7 @@ fn make_count( } fn expand_format_args<'hir>( - ctx: &mut LoweringContext<'_, 'hir>, + ctx: &mut LoweringContext<'hir>, macsp: Span, fmt: &FormatArgs, allow_const: bool, diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index a3512f209155b..5fc31e7630103 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -52,7 +52,7 @@ impl<'hir> Owners<'_, 'hir> { pub(super) struct ItemLowerer<'a, 'hir> { pub(super) tcx: TyCtxt<'hir>, - pub(super) resolver: &'a ResolverAstLowering<'hir>, + pub(super) resolver: &'hir ResolverAstLowering<'hir>, pub(super) ast_index: &'a IndexSlice>, pub(super) owners: Owners<'a, 'hir>, } @@ -80,7 +80,7 @@ impl<'hir> ItemLowerer<'_, 'hir> { fn with_lctx( &mut self, owner: NodeId, - f: impl for<'a> FnOnce(&mut LoweringContext<'a, 'hir>) -> hir::OwnerNode<'hir>, + f: impl FnOnce(&mut LoweringContext<'hir>) -> hir::OwnerNode<'hir>, ) { let mut lctx = LoweringContext::new(self.tcx, self.resolver); lctx.with_hir_id_owner(owner, |lctx| f(lctx)); @@ -124,7 +124,7 @@ impl<'hir> ItemLowerer<'_, 'hir> { } } -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir> LoweringContext<'hir> { pub(super) fn lower_mod( &mut self, items: &[Box], @@ -1528,7 +1528,7 @@ impl<'hir> LoweringContext<'_, 'hir> { pub(crate) fn lower_coroutine_body_with_moved_arguments( &mut self, decl: &FnDecl, - lower_body: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::Expr<'hir>, + lower_body: impl FnOnce(&mut LoweringContext<'hir>) -> hir::Expr<'hir>, fn_decl_span: Span, body_span: Span, coroutine_kind: CoroutineKind, @@ -1665,7 +1665,7 @@ impl<'hir> LoweringContext<'_, 'hir> { parameters.push(new_parameter); } - let mkbody = |this: &mut LoweringContext<'_, 'hir>| { + let mkbody = |this: &mut LoweringContext<'hir>| { // Create a block from the user's function body: let user_body = lower_body(this); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 71a707190254f..71f6db50ff601 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -99,9 +99,9 @@ pub fn provide(providers: &mut Providers) { providers.delegations_resolutions = delegation::delegations_resolutions; } -struct LoweringContext<'a, 'hir> { +struct LoweringContext<'hir> { tcx: TyCtxt<'hir>, - resolver: &'a ResolverAstLowering<'hir>, + resolver: &'hir ResolverAstLowering<'hir>, current_disambiguator: PerParentDisambiguatorState, /// Used to allocate HIR nodes. @@ -134,7 +134,7 @@ struct LoweringContext<'a, 'hir> { is_in_dyn_type: bool, current_hir_id_owner: hir::OwnerId, - owner: &'a PerOwnerResolverData<'hir>, + owner: &'hir PerOwnerResolverData<'hir>, item_local_id_counter: hir::ItemLocalId, trait_map: ItemLocalMap<&'hir [TraitCandidate<'hir>]>, @@ -176,8 +176,8 @@ struct LoweringContext<'a, 'hir> { attribute_parser: AttributeParser<'hir>, } -impl<'a, 'hir> LoweringContext<'a, 'hir> { - fn new(tcx: TyCtxt<'hir>, resolver: &'a ResolverAstLowering<'hir>) -> Self { +impl<'hir> LoweringContext<'hir> { + fn new(tcx: TyCtxt<'hir>, resolver: &'hir ResolverAstLowering<'hir>) -> Self { Self { tcx, resolver, @@ -542,7 +542,8 @@ fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { tcx.ensure_done().early_lint_checks(()); tcx.ensure_done().debugger_visualizers(LOCAL_CRATE); tcx.ensure_done().get_lang_items(()); - let (resolver, krate) = tcx.resolver_for_lowering().steal(); + let (resolver, krate) = tcx.resolver_for_lowering(); + let krate = krate.steal(); let ast_index = index_crate(&resolver, &krate); let mut owners = IndexVec::from_fn_n( @@ -552,7 +553,7 @@ fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { let mut lowerer = item::ItemLowerer { tcx, - resolver: &resolver, + resolver, ast_index: &ast_index, owners: Owners::IndexVec(&mut owners), }; @@ -571,15 +572,16 @@ fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { let opt_hir_hash = if tcx.needs_hir_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None }; - let delayed_resolver = Steal::new((resolver, krate)); - mid_hir::Crate::new(owners, delayed_ids, delayed_resolver, opt_hir_hash) + let ast_krate = Steal::new(krate); + mid_hir::Crate::new(owners, delayed_ids, ast_krate, opt_hir_hash) } /// Lowers an AST owner corresponding to `def_id`, now only delegations are lowered this way. fn lower_delayed_owner(tcx: TyCtxt<'_>, def_id: LocalDefId) { let krate = tcx.hir_crate(()); - let (resolver, krate) = &*krate.delayed_resolver.borrow(); + let (resolver, _) = tcx.resolver_for_lowering(); + let krate = &*krate.ast_krate.borrow(); // FIXME!!!(fn_delegation): make ast index lifetime same as resolver, // as it is too bad to reindex whole crate on each delegation lowering. @@ -627,7 +629,7 @@ enum GenericArgsMode { Silence, } -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir> LoweringContext<'hir> { fn create_def( &mut self, node_id: NodeId, @@ -3056,7 +3058,7 @@ impl<'hir> GenericArgsCtor<'hir> { && self.parenthesized == hir::GenericArgsParentheses::No } - fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> { + fn into_generic_args(self, this: &LoweringContext<'hir>) -> &'hir hir::GenericArgs<'hir> { let ga = hir::GenericArgs { args: this.arena.alloc_from_iter(self.args), constraints: self.constraints, diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 8780b70fadfa4..5f0005242a504 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -14,7 +14,7 @@ use crate::{ AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode, }; -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir> LoweringContext<'hir> { pub(crate) fn lower_pat(&mut self, pattern: &Pat) -> &'hir hir::Pat<'hir> { self.arena.alloc(self.lower_pat_mut(pattern)) } diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 42c4af5add12d..13ceae4647df0 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -20,7 +20,7 @@ use crate::{ LifetimeRes, LoweringContext, ParamMode, }; -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir> LoweringContext<'hir> { #[instrument(level = "trace", skip(self))] pub(crate) fn lower_qpath( &mut self, diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 8138fb6a2ff40..3a0a6687dd812 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -214,7 +214,7 @@ impl<'tcx> PrintExtra<'tcx> { { match self { PrintExtra::AfterParsing { krate, .. } => f(krate), - PrintExtra::NeedsAstMap { tcx } => f(&tcx.resolver_for_lowering().borrow().1), + PrintExtra::NeedsAstMap { tcx } => f(&tcx.resolver_for_lowering().1.borrow()), } } @@ -263,7 +263,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { } AstTreeExpanded => { debug!("pretty-printing expanded AST"); - format!("{:#?}", ex.tcx().resolver_for_lowering().borrow().1) + format!("{:#?}", ex.tcx().resolver_for_lowering().1.borrow()) } Hir(s) => { debug!("pretty printing HIR {:?}", s); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 25f2882345358..1c153e0be7f56 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -399,7 +399,8 @@ fn print_macro_stats(ecx: &ExtCtxt<'_>) { fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { let sess = tcx.sess; - let (resolver, krate) = &*tcx.resolver_for_lowering().borrow(); + let (resolver, krate) = tcx.resolver_for_lowering(); + let krate = &*krate.borrow(); let mut lint_buffer = resolver.lint_buffer.steal(); if sess.opts.unstable_opts.input_stats { @@ -786,7 +787,7 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P fn resolver_for_lowering_raw<'tcx>( tcx: TyCtxt<'tcx>, (): (), -) -> (&'tcx Steal<(ty::ResolverAstLowering<'tcx>, Arc)>, &'tcx ty::ResolverGlobalCtxt) { +) -> (&'tcx (ty::ResolverAstLowering<'tcx>, Steal>), &'tcx ty::ResolverGlobalCtxt) { let arenas = Resolver::arenas(); let _ = tcx.registered_tools(()); // Uses `crate_for_resolver`. let (krate, pre_configured_attrs) = tcx.crate_for_resolver(()).steal(); @@ -808,7 +809,7 @@ fn resolver_for_lowering_raw<'tcx>( } = resolver.into_outputs(); let resolutions = tcx.arena.alloc(untracked_resolutions); - (tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, Arc::new(krate)))), resolutions) + (tcx.arena.alloc((untracked_resolver_for_lowering, Steal::new(Arc::new(krate)))), resolutions) } pub fn write_dep_info(tcx: TyCtxt<'_>) { @@ -866,7 +867,8 @@ pub fn write_interface<'tcx>(tcx: TyCtxt<'tcx>) { return; } let _timer = tcx.sess.timer("write_interface"); - let (_, krate) = &*tcx.resolver_for_lowering().borrow(); + let (_, krate) = tcx.resolver_for_lowering(); + let krate = &*krate.borrow(); let krate = rustc_ast_pretty::pprust::print_crate_as_interface( krate, diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index cce43237a3247..5b8622aad38b6 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -30,10 +30,12 @@ macro_rules! arena_types { rustc_hir::def_id::LocalDefId, rustc_middle::ty::DefinitionSiteHiddenType<'tcx>, >, - [] resolver: rustc_data_structures::steal::Steal<( + [] resolver: ( rustc_middle::ty::ResolverAstLowering<'tcx>, - std::sync::Arc, - )>, + rustc_data_structures::steal::Steal< + std::sync::Arc + > + ), [] crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>, [] resolutions: rustc_middle::ty::ResolverGlobalCtxt, [] const_allocs: rustc_middle::mir::interpret::Allocation, diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 333fe67ff919e..50caa533c6819 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -1296,7 +1296,7 @@ fn force_delayed_owners_lowering(tcx: TyCtxt<'_>) { tcx.ensure_done().lower_delayed_owner(id); } - let (_, krate) = krate.delayed_resolver.steal(); + let krate = krate.ast_krate.steal(); let prof = tcx.sess.prof.clone(); // Drop AST to free memory. It can be expensive so try to drop it on a separate thread. diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 29799fef12ada..1f9703a9be912 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -24,7 +24,7 @@ use rustc_macros::{Decodable, Encodable, StableHash}; use rustc_span::{ErrorGuaranteed, ExpnId, Span}; use crate::query::Providers; -use crate::ty::{ResolverAstLowering, TyCtxt}; +use crate::ty::TyCtxt; /// The top-level data structure that stores the entire contents of /// the crate currently being compiled. @@ -38,9 +38,9 @@ pub struct Crate<'hir> { owners: IndexVec>, // Ids of delayed AST owners which are lowered through `lower_delayed_owner` query. pub delayed_ids: FxIndexSet, - // The resolver and AST crate which are set in the end of the `hir_crate` query + // The AST crate which are set in the end of the `hir_crate` query // and then stolen and dropped in `force_delayed_owners_lowering`. - pub delayed_resolver: Steal<(ResolverAstLowering<'hir>, Arc)>, + pub ast_krate: Steal>, // Only present when incr. comp. is enabled. pub opt_hir_hash: Option, } @@ -49,10 +49,10 @@ impl<'hir> Crate<'hir> { pub fn new( owners: IndexVec>, delayed_ids: FxIndexSet, - delayed_resolver: Steal<(ResolverAstLowering<'hir>, Arc)>, + ast_krate: Steal>, opt_hir_hash: Option, ) -> Crate<'hir> { - Crate { owners, delayed_ids, delayed_resolver, opt_hir_hash } + Crate { owners, delayed_ids, ast_krate, opt_hir_hash } } /// Serves as an entry point for getting `MaybeOwner`. As owner can either be in diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 1e0abdcc196fa..86a38d882339f 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -180,7 +180,10 @@ rustc_queries! { desc { "getting the resolver outputs" } } - query resolver_for_lowering_raw(_: ()) -> (&'tcx Steal<(ty::ResolverAstLowering<'tcx>, Arc)>, &'tcx ty::ResolverGlobalCtxt) { + query resolver_for_lowering_raw(_: ()) -> ( + &'tcx (ty::ResolverAstLowering<'tcx>, Steal>), + &'tcx ty::ResolverGlobalCtxt, + ) { eval_always no_hash desc { "getting the resolver for lowering" } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index d6bf72e215e7c..920b8aac07f92 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2730,7 +2730,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn resolver_for_lowering( self, - ) -> &'tcx Steal<(ty::ResolverAstLowering<'tcx>, Arc)> { + ) -> &'tcx (ty::ResolverAstLowering<'tcx>, Steal>) { self.resolver_for_lowering_raw(()).0 } diff --git a/compiler/rustc_passes/src/debugger_visualizer.rs b/compiler/rustc_passes/src/debugger_visualizer.rs index 2f14884a248b9..00b1637be335c 100644 --- a/compiler/rustc_passes/src/debugger_visualizer.rs +++ b/compiler/rustc_passes/src/debugger_visualizer.rs @@ -68,8 +68,7 @@ impl<'ast> rustc_ast::visit::Visitor<'ast> for DebuggerVisualizerCollector<'_> { /// Traverses and collects the debugger visualizers for a specific crate. fn debugger_visualizers(tcx: TyCtxt<'_>, _: LocalCrate) -> Vec { - let resolver_and_krate = tcx.resolver_for_lowering().borrow(); - let krate = &*resolver_and_krate.1; + let krate = &*tcx.resolver_for_lowering().1.borrow(); let mut visitor = DebuggerVisualizerCollector { sess: tcx.sess, visualizers: Vec::new() }; rustc_ast::visit::Visitor::visit_crate(&mut visitor, krate); diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index 6180d6f8c4c27..48ddaafd88eb9 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -246,8 +246,8 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> { /// Traverses and collects all the lang items in all crates. fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems { - let resolver = tcx.resolver_for_lowering().borrow(); - let (resolver, krate) = &*resolver; + let (resolver, krate) = tcx.resolver_for_lowering(); + let krate = &*krate.borrow(); // Initialize the collector. let mut collector = LanguageItemCollector::new(tcx, resolver); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 80c6e8099c8ce..fccfa3f57e930 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -348,7 +348,7 @@ pub(crate) fn run_global_ctxt( let expanded_macros = { // We need for these variables to be removed to ensure that the `Crate` won't be "stolen" // anymore. - let (_resolver, krate) = &*tcx.resolver_for_lowering().borrow(); + let krate = &*tcx.resolver_for_lowering().1.borrow(); source_macro_expansion(&krate, &render_options, output_format, tcx.sess.source_map()) }; From 334a95f9f403715d9cc719559080b874bf650d49 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Fri, 17 Apr 2026 20:44:00 +0000 Subject: [PATCH 2/8] Make lowering incremental. Co-authored-by: Camille Gillot --- compiler/rustc_ast/src/ast.rs | 11 + compiler/rustc_ast_lowering/src/delegation.rs | 105 +++---- compiler/rustc_ast_lowering/src/item.rs | 150 ++++------ compiler/rustc_ast_lowering/src/lib.rs | 266 ++++++++---------- compiler/rustc_driver_impl/src/pretty.rs | 4 +- compiler/rustc_hir/src/hir.rs | 9 +- compiler/rustc_interface/src/passes.rs | 20 +- compiler/rustc_middle/src/arena.rs | 12 +- compiler/rustc_middle/src/hir/map.rs | 32 +-- compiler/rustc_middle/src/hir/mod.rs | 77 +---- compiler/rustc_middle/src/queries.rs | 38 +-- compiler/rustc_middle/src/query/erase.rs | 4 + compiler/rustc_middle/src/ty/context.rs | 15 +- .../rustc_passes/src/debugger_visualizer.rs | 2 +- compiler/rustc_passes/src/lang_items.rs | 1 - src/librustdoc/core.rs | 2 +- .../unused-target-expr-in-glob-or-list.stderr | 44 +-- ...ult-trait-shadow-cycle-issue-151358.stderr | 4 +- tests/ui/pin-ergonomics/pin_v2-attr.stderr | 16 +- .../query-cycle-printing-issue-151358.stderr | 4 +- .../resolve/query-cycle-issue-124901.stderr | 4 +- 21 files changed, 318 insertions(+), 502 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 9d60a16f3ba14..7ee6ab7d8d867 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -4362,6 +4362,17 @@ impl TryFrom for ForeignItemKind { pub type ForeignItem = Item; +#[derive(Debug)] +pub enum AstOwner<'a> { + NonOwner, + Synthetic(rustc_span::def_id::LocalDefId), + Crate(&'a Crate), + Item(&'a Item), + TraitItem(&'a AssocItem), + ImplItem(&'a AssocItem), + ForeignItem(&'a ForeignItem), +} + // Some nodes are used a lot. Make sure they don't unintentionally get bigger. #[cfg(target_pointer_width = "64")] mod size_asserts { diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 44c9e110c80c3..511e9ee5f3ebf 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -46,12 +46,12 @@ use rustc_abi::ExternAbi; use rustc_ast as ast; use rustc_ast::node_id::NodeMap; use rustc_ast::*; -use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; +use rustc_data_structures::fx::FxHashSet; use rustc_hir::attrs::{AttributeKind, InlineAttr}; -use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{self as hir, FnDeclFlags}; use rustc_middle::span_bug; -use rustc_middle::ty::{Asyncness, PerOwnerResolverData, TyCtxt}; +use rustc_middle::ty::{Asyncness, PerOwnerResolverData}; +use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::symbol::kw; use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol}; @@ -62,7 +62,6 @@ use crate::diagnostics::{ }; use crate::{ AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode, - index_crate, }; mod generics; @@ -121,65 +120,6 @@ static ATTRS_ADDITIONS: &[AttrAdditionInfo] = &[ }, ]; -pub(crate) fn delegations_resolutions( - tcx: TyCtxt<'_>, - _: (), -) -> FxIndexMap> { - let krate = tcx.hir_crate(()); - - let (resolver, _) = tcx.resolver_for_lowering(); - let ast_crate = &*krate.ast_krate.borrow(); - - // FIXME!!!(fn_delegation): make ast index lifetime same as resolver, - // as it is too bad to reindex whole crate on each delegation lowering. - let ast_index = index_crate(resolver, ast_crate); - - let mut result = FxIndexMap::>::default(); - - for &def_id in &krate.delayed_ids { - let delegation = ast_index[def_id].delegation().expect("processing delegations"); - let span = delegation.last_segment_span(); - - if let Some(info) = tcx.resolutions(()).delegation_infos.get(&def_id) { - let res = info.resolution_id.map(|id| check_for_cycles(tcx, id, span).map(|_| id)); - result.insert(def_id, res.flatten()); - } else { - tcx.dcx().span_delayed_bug( - span, - format!("delegation resolution record was not found for {def_id:?}"), - ); - } - } - - result -} - -fn check_for_cycles(tcx: TyCtxt<'_>, mut def_id: DefId, span: Span) -> Result<(), ErrorGuaranteed> { - let mut visited: FxHashSet = Default::default(); - - loop { - visited.insert(def_id); - - // If def_id is in local crate and it corresponds to another delegation - // it means that we refer to another delegation as a callee, so in order to obtain - // a signature DefId we obtain NodeId of the callee delegation and try to get signature from it. - if let Some(local_id) = def_id.as_local() - && let Some(info) = tcx.resolutions(()).delegation_infos.get(&local_id) - && let Ok(id) = info.resolution_id - { - def_id = id; - if visited.contains(&def_id) { - return Err(match visited.len() { - 1 => tcx.dcx().emit_err(UnresolvedDelegationCallee { span }), - _ => tcx.dcx().emit_err(CycleInDelegationSignatureResolution { span }), - }); - } - } else { - return Ok(()); - } - } -} - impl<'hir> LoweringContext<'hir> { fn is_method(&self, def_id: DefId, span: Span) -> bool { match self.tcx.def_kind(def_id) { @@ -189,6 +129,32 @@ impl<'hir> LoweringContext<'hir> { } } + fn check_for_cycles(&self, mut def_id: DefId, span: Span) -> Result<(), ErrorGuaranteed> { + let mut visited: FxHashSet = Default::default(); + + loop { + visited.insert(def_id); + + // If def_id is in local crate and it corresponds to another delegation + // it means that we refer to another delegation as a callee, so in order to obtain + // a signature DefId we obtain NodeId of the callee delegation and try to get signature from it. + if let Some(local_id) = def_id.as_local() + && let Some(info) = self.tcx.resolutions(()).delegation_infos.get(&local_id) + && let Ok(id) = info.resolution_id + { + def_id = id; + if visited.contains(&def_id) { + return Err(match visited.len() { + 1 => self.dcx().emit_err(UnresolvedDelegationCallee { span }), + _ => self.dcx().emit_err(CycleInDelegationSignatureResolution { span }), + }); + } + } else { + return Ok(()); + } + } + } + pub(crate) fn lower_delegation( &mut self, delegation: &Delegation, @@ -196,11 +162,20 @@ impl<'hir> LoweringContext<'hir> { ) -> DelegationResults<'hir> { let span = self.lower_span(delegation.last_segment_span()); - let sig_id = self.tcx.delegations_resolutions(()).get(&self.owner.def_id).copied(); + let Some(info) = self.tcx.resolutions(()).delegation_infos.get(&self.owner.def_id) else { + self.dcx().span_delayed_bug( + span, + format!("delegation resolution record was not found for {:?}", self.owner.def_id), + ); + + return self.generate_delegation_error(span, delegation); + }; + + let sig_id = info.resolution_id.and_then(|id| self.check_for_cycles(id, span).map(|_| id)); // Delegation can be missing from the `delegations_resolutions` table // in illegal places such as function bodies in extern blocks (see #151356). - let Some(Ok(sig_id)) = sig_id else { + let Ok(sig_id) = sig_id else { self.dcx().span_delayed_bug( span, format!("LoweringContext: the delegation {:?} is unresolved", item_id), diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 5fc31e7630103..05732921c406e 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1,19 +1,17 @@ use rustc_abi::ExternAbi; use rustc_ast::visit::AssocCtxt; use rustc_ast::*; -use rustc_data_structures::fx::FxIndexMap; use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err}; use rustc_hir::attrs::{AttributeKind, EiiImplResolution}; use rustc_hir::def::{DefKind, PerNS, Res}; -use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; use rustc_hir::{ - self as hir, HirId, ImplItemImplKind, LifetimeSource, PredicateOrigin, Target, find_attr, + self as hir, CRATE_OWNER_ID, HirId, ImplItemImplKind, LifetimeSource, PredicateOrigin, Target, + find_attr, }; -use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::span_bug; use rustc_middle::ty::data_structures::IndexMap; use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; -use rustc_span::def_id::DefId; +use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym}; use smallvec::{SmallVec, smallvec}; @@ -25,36 +23,14 @@ use super::diagnostics::{ }; use super::stability::{enabled_names, gate_unstable_abi}; use super::{ - AstOwner, FnDeclKind, GenericArgsMode, ImplTraitContext, ImplTraitPosition, LoweringContext, - ParamMode, RelaxedBoundForbiddenReason, RelaxedBoundPolicy, ResolverAstLoweringExt, + FnDeclKind, GenericArgsMode, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode, + RelaxedBoundForbiddenReason, RelaxedBoundPolicy, ResolverAstLoweringExt, }; use crate::diagnostics::ConstComptimeFn; -/// Wraps either IndexVec (during `hir_crate`), which acts like a primary -/// storage for most of the MaybeOwners, or FxIndexMap during delayed AST -> HIR -/// lowering of delegations (`lower_delayed_owner`), -/// in this case we can not modify already created IndexVec, so we use other map. -pub(super) enum Owners<'a, 'hir> { - IndexVec(&'a mut IndexVec>), - Map(&'a mut FxIndexMap>), -} - -impl<'hir> Owners<'_, 'hir> { - fn get_or_insert_mut(&mut self, def_id: LocalDefId) -> &mut hir::MaybeOwner<'hir> { - match self { - Owners::IndexVec(index_vec) => { - index_vec.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom) - } - Owners::Map(map) => map.entry(def_id).or_insert(hir::MaybeOwner::Phantom), - } - } -} - -pub(super) struct ItemLowerer<'a, 'hir> { +pub(super) struct ItemLowerer<'hir> { pub(super) tcx: TyCtxt<'hir>, pub(super) resolver: &'hir ResolverAstLowering<'hir>, - pub(super) ast_index: &'a IndexSlice>, - pub(super) owners: Owners<'a, 'hir>, } /// When we have a ty alias we *may* have two where clauses. To give the best diagnostics, we set the span @@ -76,51 +52,47 @@ fn add_ty_alias_where_clause( if before.0 || !after.0 { before } else { after }; } -impl<'hir> ItemLowerer<'_, 'hir> { +impl<'hir> ItemLowerer<'hir> { fn with_lctx( &mut self, owner: NodeId, f: impl FnOnce(&mut LoweringContext<'hir>) -> hir::OwnerNode<'hir>, - ) { - let mut lctx = LoweringContext::new(self.tcx, self.resolver); - lctx.with_hir_id_owner(owner, |lctx| f(lctx)); - - for (def_id, info) in lctx.children { - let owner = self.owners.get_or_insert_mut(def_id); - assert!( - matches!(owner, hir::MaybeOwner::Phantom), - "duplicate copy of {def_id:?} in lctx.children" - ); - *owner = info; - } + ) -> hir::MaybeOwner<'hir> { + let mut lctx = LoweringContext::new(self.tcx, self.resolver, owner); + + let item = f(&mut lctx); + debug_assert_eq!(lctx.current_hir_id_owner, item.def_id()); + + let info = lctx.make_owner_info(item); + + hir::MaybeOwner::Owner(lctx.arena.alloc(info)) } - pub(super) fn lower_node(&mut self, def_id: LocalDefId) { - let owner = self.owners.get_or_insert_mut(def_id); - if let hir::MaybeOwner::Phantom = owner { - let node = self.ast_index[def_id]; - match node { - AstOwner::NonOwner => {} - AstOwner::Crate(c) => { - assert_eq!(self.resolver.owner_def_id(CRATE_NODE_ID), CRATE_DEF_ID); - self.with_lctx(CRATE_NODE_ID, |lctx| { - let module = lctx.lower_mod(&c.items, &c.spans); - // FIXME(jdonszelman): is dummy span ever a problem here? - lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP, Target::Crate); - hir::OwnerNode::Crate(module) - }) - } - AstOwner::Item(item) => { - self.with_lctx(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item))) - } - AstOwner::AssocItem(item, ctxt) => { - self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt)) - } - AstOwner::ForeignItem(item) => self.with_lctx(item.id, |lctx| { - hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item)) - }), - } - } + #[instrument(level = "debug", skip(self, c))] + pub(super) fn lower_crate(&mut self, c: &Crate) -> hir::MaybeOwner<'hir> { + self.with_lctx(CRATE_NODE_ID, |lctx| { + debug_assert_eq!(lctx.current_hir_id_owner, CRATE_OWNER_ID); + let module = lctx.lower_mod(&c.items, &c.spans); + lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, c.spans.inner_span, Target::Crate); + hir::OwnerNode::Crate(module) + }) + } + + #[instrument(level = "debug", skip(self))] + pub(super) fn lower_item(&mut self, item: &Item) -> hir::MaybeOwner<'hir> { + self.with_lctx(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item))) + } + + pub(super) fn lower_trait_item(&mut self, item: &AssocItem) -> hir::MaybeOwner<'hir> { + self.with_lctx(item.id, |lctx| hir::OwnerNode::TraitItem(lctx.lower_trait_item(item))) + } + + pub(super) fn lower_impl_item(&mut self, item: &AssocItem) -> hir::MaybeOwner<'hir> { + self.with_lctx(item.id, |lctx| hir::OwnerNode::ImplItem(lctx.lower_impl_item(item))) + } + + pub(super) fn lower_foreign_item(&mut self, item: &ForeignItem) -> hir::MaybeOwner<'hir> { + self.with_lctx(item.id, |lctx| hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item))) } } @@ -252,8 +224,9 @@ impl<'hir> LoweringContext<'hir> { } fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> { + let owner_id = self.current_hir_id_owner; + let hir_id: HirId = owner_id.into(); let vis_span = self.lower_span(i.vis.span); - let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id); let extra_hir_attributes = self.generate_extra_attrs_for_item_kind(i.id, &i.kind); let attrs = self.lower_attrs_with_extra( @@ -266,7 +239,7 @@ impl<'hir> LoweringContext<'hir> { let kind = self.lower_item_kind(i.span, i.id, hir_id, attrs, vis_span, &i.kind); let item = hir::Item { - owner_id: hir_id.expect_owner(), + owner_id, kind, vis_span, span: self.lower_span(i.span), @@ -771,21 +744,9 @@ impl<'hir> LoweringContext<'hir> { } } - fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) -> hir::OwnerNode<'hir> { - // Evaluate with the lifetimes in `params` in-scope. - // This is used to track which lifetimes have already been defined, - // and which need to be replicated when lowering an async fn. - match ctxt { - AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)), - AssocCtxt::Impl { of_trait } => { - hir::OwnerNode::ImplItem(self.lower_impl_item(item, of_trait)) - } - } - } - fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> { - let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id); - let owner_id = hir_id.expect_owner(); + let owner_id = self.current_hir_id_owner; + let hir_id: HirId = owner_id.into(); let attrs = self.lower_attrs(hir_id, &i.attrs, i.span, Target::from_foreign_item_kind(&i.kind)); let (ident, kind) = match &i.kind { @@ -968,14 +929,14 @@ impl<'hir> LoweringContext<'hir> { } fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> { - let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id); + let trait_item_def_id = self.current_hir_id_owner; + let hir_id: HirId = trait_item_def_id.into(); let attrs = self.lower_attrs( hir_id, &i.attrs, i.span, Target::from_assoc_item_kind(&i.kind, AssocCtxt::Trait), ); - let trait_item_def_id = hir_id.expect_owner(); let (ident, generics, kind, has_value) = match &i.kind { AssocItemKind::Const(ConstItem { @@ -1222,16 +1183,17 @@ impl<'hir> LoweringContext<'hir> { ident } - fn lower_impl_item( - &mut self, - i: &AssocItem, - is_in_trait_impl: bool, - ) -> &'hir hir::ImplItem<'hir> { + fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> { + let owner_id = self.current_hir_id_owner; + let hir_id: HirId = owner_id.into(); + let parent_id = self.tcx.local_parent(owner_id.def_id); + let is_in_trait_impl = + matches!(self.tcx.def_kind(parent_id), DefKind::Impl { of_trait: true }); + // Since `default impl` is not yet implemented, this is always true in impls. let has_value = true; let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value, || hir::Defaultness::Final); - let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id); let attrs = self.lower_attrs( hir_id, &i.attrs, @@ -1352,7 +1314,7 @@ impl<'hir> LoweringContext<'hir> { }; let item = hir::ImplItem { - owner_id: hir_id.expect_owner(), + owner_id, ident: self.lower_ident(effective_ident), generics, impl_kind, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 71f6db50ff601..3e331e66d9e4d 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -39,28 +39,26 @@ use std::mem; use std::sync::Arc; use rustc_ast::node_id::NodeMap; -use rustc_ast::visit::Visitor; +use rustc_ast::visit::{self, Visitor}; use rustc_ast::{self as ast, *}; use rustc_attr_parsing::{AttributeParser, OmitDoc, Recovery, ShouldEmit}; -use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; +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; use rustc_errors::codes::*; use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle}; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; -use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId}; +use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap}; use rustc_hir::definitions::PerParentDisambiguatorState; use rustc_hir::lints::DelayedLint; use rustc_hir::{ self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource, LifetimeSyntax, MissingLifetimeKind, ParamName, Target, TraitCandidate, find_attr, }; -use rustc_index::{Idx, IndexSlice, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_macros::extension; -use rustc_middle::hir::{self as mid_hir}; use rustc_middle::queries::Providers; use rustc_middle::span_bug; use rustc_middle::ty::{PerOwnerResolverData, ResolverAstLowering, TyCtxt}; @@ -72,7 +70,6 @@ use thin_vec::ThinVec; use tracing::{debug, instrument, trace}; use crate::diagnostics::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait}; -use crate::item::Owners; macro_rules! arena_vec { ($this:expr; $($x:expr),*) => ( @@ -94,9 +91,8 @@ mod path; pub mod stability; pub fn provide(providers: &mut Providers) { - providers.hir_crate = lower_to_hir; - providers.lower_delayed_owner = lower_delayed_owner; - providers.delegations_resolutions = delegation::delegations_resolutions; + providers.index_ast = index_ast; + providers.lower_to_hir = lower_to_hir; } struct LoweringContext<'hir> { @@ -114,7 +110,7 @@ struct LoweringContext<'hir> { /// Attributes inside the owner being lowered. attrs: SortedMap, /// Collect items that were created by lowering the current owner. - children: Vec<(LocalDefId, hir::MaybeOwner<'hir>)>, + children: LocalDefIdMap>, contract_ensures: Option<(Span, Ident, HirId)>, @@ -177,22 +173,32 @@ struct LoweringContext<'hir> { } impl<'hir> LoweringContext<'hir> { - fn new(tcx: TyCtxt<'hir>, resolver: &'hir ResolverAstLowering<'hir>) -> Self { + fn new(tcx: TyCtxt<'hir>, resolver: &'hir ResolverAstLowering<'hir>, owner: NodeId) -> Self { + let current_ast_owner = &resolver.owners[&owner]; + let current_hir_id_owner = hir::OwnerId { def_id: current_ast_owner.def_id }; + let current_disambiguator = resolver + .disambiguators + .get(¤t_hir_id_owner.def_id) + .map(|s| s.steal()) + .unwrap_or_else(|| PerParentDisambiguatorState::new(current_hir_id_owner.def_id)); + Self { tcx, resolver, - current_disambiguator: Default::default(), - owner: &resolver.owners[&CRATE_NODE_ID], + current_disambiguator, + owner: current_ast_owner, arena: tcx.hir_arena, // HirId handling. bodies: Vec::new(), define_opaque: None, attrs: SortedMap::default(), - children: Vec::default(), + children: LocalDefIdMap::default(), contract_ensures: None, - current_hir_id_owner: hir::CRATE_OWNER_ID, - item_local_id_counter: hir::ItemLocalId::ZERO, + current_hir_id_owner, + // 0 corresponds to `owner` lowered as `current_hir_id_owner`, + // and we never call `lower_node_id(owner)`. + item_local_id_counter: hir::ItemLocalId::new(1), ident_and_label_to_local_id: Default::default(), #[cfg(debug_assertions)] node_id_to_local_id: Default::default(), @@ -306,10 +312,6 @@ impl<'tcx> ResolverAstLowering<'tcx> { fn extra_lifetime_params(&self, id: NodeId) -> &[(Ident, NodeId, MissingLifetimeKind)] { self.extra_lifetime_params_map.get(&id).map_or(&[], |v| &v[..]) } - - fn owner_def_id(&self, id: NodeId) -> LocalDefId { - self.owners[&id].def_id - } } /// How relaxed bounds `?Trait` should be treated. @@ -438,25 +440,6 @@ enum FnDeclKind { Impl, } -#[derive(Copy, Clone)] -enum AstOwner<'a> { - NonOwner, - Crate(&'a ast::Crate), - Item(&'a ast::Item), - AssocItem(&'a ast::AssocItem, visit::AssocCtxt), - ForeignItem(&'a ast::ForeignItem), -} - -impl AstOwner<'_> { - fn delegation(&self) -> Option<&ast::Delegation> { - match self { - AstOwner::Item(Item { kind: ItemKind::Delegation(d), .. }) - | AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation(d), .. }, _) => Some(d), - _ => None, - } - } -} - #[derive(Copy, Clone, Debug)] enum TryBlockScope { /// There isn't a `try` block, so a `?` will use `return`. @@ -469,137 +452,114 @@ enum TryBlockScope { Heterogeneous(HirId), } -fn index_crate<'a, 'b>( - resolver: &'b ResolverAstLowering<'b>, - krate: &'a Crate, -) -> IndexVec> { - let mut indexer = Indexer { resolver, index: IndexVec::new() }; - *indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner) = - AstOwner::Crate(krate); - visit::walk_crate(&mut indexer, krate); +fn index_ast<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx IndexVec> { + let (resolver, krate) = tcx.resolver_for_lowering(); + + let mut indexer = Indexer { owners: &resolver.owners, index: IndexVec::new() }; + indexer.visit_crate(&krate); + indexer.insert(CRATE_NODE_ID, AstOwner::Crate(&*krate)); + return tcx.arena.alloc(indexer.index); + + struct Indexer<'s, 'ast> { + owners: &'s NodeMap>, + index: IndexVec>, + } - return indexer.index; + impl<'ast> Indexer<'_, 'ast> { + fn insert(&mut self, id: NodeId, node: AstOwner<'ast>) { + let def_id = self.owners[&id].def_id; + self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner); + self.index[def_id] = node; + } - struct Indexer<'a, 'b> { - resolver: &'b ResolverAstLowering<'b>, - index: IndexVec>, + fn visit_item_id_use_tree(&mut self, tree: &UseTree, parent: LocalDefId) { + match tree.kind { + UseTreeKind::Glob(_) | UseTreeKind::Simple(_) => {} + UseTreeKind::Nested { items: ref nested_vec, span: _ } => { + for &(ref nested, id) in nested_vec { + self.insert(id, AstOwner::Synthetic(parent)); + + let def_id = self.owners[&id].def_id; + self.visit_item_id_use_tree(nested, def_id); + } + } + } + } } - impl<'a, 'b> visit::Visitor<'a> for Indexer<'a, 'b> { - fn visit_attribute(&mut self, _: &'a Attribute) { + impl<'ast> visit::Visitor<'ast> for Indexer<'_, 'ast> { + fn visit_attribute(&mut self, _: &'ast Attribute) { // We do not want to lower expressions that appear in attributes, // as they are not accessible to the rest of the HIR. } - fn visit_item(&mut self, item: &'a ast::Item) { - let def_id = self.resolver.owner_def_id(item.id); - *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::Item(item); - visit::walk_item(self, item) + fn visit_item(&mut self, item: &'ast Item) { + let def_id = self.owners[&item.id].def_id; + if let ItemKind::Use(ref use_tree) = item.kind { + self.visit_item_id_use_tree(use_tree, def_id); + } + visit::walk_item(self, item); + self.insert(item.id, AstOwner::Item(item)); } - fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: visit::AssocCtxt) { - let def_id = self.resolver.owner_def_id(item.id); - *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = - AstOwner::AssocItem(item, ctxt); + fn visit_assoc_item(&mut self, item: &'ast AssocItem, ctxt: visit::AssocCtxt) { visit::walk_assoc_item(self, item, ctxt); + let owner_ref = match ctxt { + visit::AssocCtxt::Trait => AstOwner::TraitItem(item), + visit::AssocCtxt::Impl { .. } => AstOwner::ImplItem(item), + }; + self.insert(item.id, owner_ref); } - fn visit_foreign_item(&mut self, item: &'a ast::ForeignItem) { - let def_id = self.resolver.owner_def_id(item.id); - *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = - AstOwner::ForeignItem(item); + fn visit_foreign_item(&mut self, item: &'ast ForeignItem) { visit::walk_item(self, item); + self.insert(item.id, AstOwner::ForeignItem(item)); } } } -/// Compute the hash for the HIR of the full crate. -/// This hash will then be part of the crate_hash which is stored in the metadata. -fn compute_hir_hash( - tcx: TyCtxt<'_>, - owners: &IndexSlice>, -) -> Fingerprint { - let mut hir_body_nodes: Vec<_> = owners - .iter_enumerated() - .filter_map(|(def_id, info)| { - let info = info.as_owner()?; - let def_path_hash = tcx.hir_def_path_hash(def_id); - Some((def_path_hash, info)) - }) - .collect(); - hir_body_nodes.sort_unstable_by_key(|bn| bn.0); - - tcx.with_stable_hashing_context(|mut hcx| { - let mut stable_hasher = StableHasher::new(); - hir_body_nodes.stable_hash(&mut hcx, &mut stable_hasher); - stable_hasher.finish() - }) -} - -fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { +#[instrument(level = "trace", skip(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(()); tcx.ensure_done().debugger_visualizers(LOCAL_CRATE); tcx.ensure_done().get_lang_items(()); - let (resolver, krate) = tcx.resolver_for_lowering(); - let krate = krate.steal(); - - let ast_index = index_crate(&resolver, &krate); - let mut owners = IndexVec::from_fn_n( - |_| hir::MaybeOwner::Phantom, - tcx.definitions_untracked().num_definitions(), - ); - - let mut lowerer = item::ItemLowerer { - tcx, - resolver, - ast_index: &ast_index, - owners: Owners::IndexVec(&mut owners), - }; + let (resolver, _) = tcx.resolver_for_lowering(); + let ast_index = tcx.index_ast(()); + let node = ast_index.get(def_id); - let mut delayed_ids: FxIndexSet = Default::default(); + let mut item_lowerer = item::ItemLowerer { tcx, resolver }; - for def_id in ast_index.indices() { - if ast_index[def_id].delegation().is_some() { - delayed_ids.insert(def_id); - } else { - lowerer.lower_node(def_id); + // The item existed in the AST. + let parent_id = match node { + Some(AstOwner::Crate(c)) => return item_lowerer.lower_crate(&c), + Some(AstOwner::Item(item)) => return item_lowerer.lower_item(&item), + Some(AstOwner::TraitItem(item)) => { + return item_lowerer.lower_trait_item(&item); } - } - - // Don't hash unless necessary, because it's expensive. - let opt_hir_hash = - if tcx.needs_hir_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None }; - - let ast_krate = Steal::new(krate); - mid_hir::Crate::new(owners, delayed_ids, ast_krate, opt_hir_hash) -} - -/// Lowers an AST owner corresponding to `def_id`, now only delegations are lowered this way. -fn lower_delayed_owner(tcx: TyCtxt<'_>, def_id: LocalDefId) { - let krate = tcx.hir_crate(()); - - let (resolver, _) = tcx.resolver_for_lowering(); - let krate = &*krate.ast_krate.borrow(); - - // FIXME!!!(fn_delegation): make ast index lifetime same as resolver, - // as it is too bad to reindex whole crate on each delegation lowering. - let ast_index = index_crate(resolver, krate); - - let mut map = Default::default(); - let mut lowerer = item::ItemLowerer { - tcx, - resolver: &resolver, - ast_index: &ast_index, - owners: Owners::Map(&mut map), + Some(AstOwner::ImplItem(item)) => { + return item_lowerer.lower_impl_item(&item); + } + Some(AstOwner::ForeignItem(item)) => return item_lowerer.lower_foreign_item(&item), + Some(AstOwner::Synthetic(parent_id)) => *parent_id, + Some(AstOwner::NonOwner) | None => tcx.local_parent(def_id), }; - lowerer.lower_node(def_id); - - for (child_def_id, owner) in map { - tcx.feed_delayed_owner(child_def_id, owner); + // The item did not exist in the AST, it was created by its parent. + let mut parent_info = tcx.lower_to_hir(parent_id); + if let hir::MaybeOwner::NonOwner(hir_id) = parent_info { + parent_info = tcx.lower_to_hir(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() + ) + }) } #[derive(Copy, Clone, PartialEq, Debug)] @@ -668,6 +628,7 @@ impl<'hir> LoweringContext<'hir> { /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name /// resolver (if any). + #[instrument(level = "trace", skip(self), ret)] fn opt_local_def_id(&self, node: NodeId) -> Option { self.node_id_to_def_id .get(&node) @@ -740,6 +701,7 @@ impl<'hir> LoweringContext<'hir> { let current_impl_trait_defs = std::mem::take(&mut self.impl_trait_defs); let current_impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds); let current_delayed_lints = std::mem::take(&mut self.delayed_lints); + let current_children = std::mem::take(&mut self.children); // Do not reset `next_node_id` and `node_id_to_def_id`: // we want `f` to be able to refer to the `LocalDefId`s that the caller created. @@ -776,9 +738,11 @@ impl<'hir> LoweringContext<'hir> { self.impl_trait_defs = current_impl_trait_defs; self.impl_trait_bounds = current_impl_trait_bounds; self.delayed_lints = current_delayed_lints; + self.children = current_children; + self.children.extend_unord(info.children.items().map(|(&def_id, &info)| (def_id, info))); - debug_assert!(!self.children.iter().any(|(id, _)| id == &owner_id.def_id)); - self.children.push((owner_id.def_id, hir::MaybeOwner::Owner(info))); + debug_assert!(!self.children.contains_key(&owner_id.def_id)); + self.children.insert(owner_id.def_id, hir::MaybeOwner::Owner(info)); } fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> { @@ -787,6 +751,7 @@ impl<'hir> LoweringContext<'hir> { let define_opaque = std::mem::take(&mut self.define_opaque); let trait_map = std::mem::take(&mut self.trait_map); let delayed_lints = Steal::new(std::mem::take(&mut self.delayed_lints).into_boxed_slice()); + let children = std::mem::take(&mut self.children); #[cfg(debug_assertions)] for (id, attrs) in attrs.iter() { @@ -807,7 +772,14 @@ impl<'hir> LoweringContext<'hir> { let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies }; let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaque }; - self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map, delayed_lints }) + self.arena.alloc(hir::OwnerInfo { + nodes, + parenting, + attrs, + trait_map, + delayed_lints, + children, + }) } /// This method allocates a new `HirId` for the given `NodeId`. @@ -826,7 +798,7 @@ impl<'hir> LoweringContext<'hir> { let hir_id = HirId { owner, local_id }; if let Some(def_id) = self.opt_local_def_id(ast_node_id) { - self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id))); + self.children.insert(def_id, hir::MaybeOwner::NonOwner(hir_id)); } if let Some(traits) = self.owner.trait_map.get(&ast_node_id) { diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 3a0a6687dd812..79a70844585a1 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -214,7 +214,7 @@ impl<'tcx> PrintExtra<'tcx> { { match self { PrintExtra::AfterParsing { krate, .. } => f(krate), - PrintExtra::NeedsAstMap { tcx } => f(&tcx.resolver_for_lowering().1.borrow()), + PrintExtra::NeedsAstMap { tcx } => f(&tcx.resolver_for_lowering().1), } } @@ -263,7 +263,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { } AstTreeExpanded => { debug!("pretty-printing expanded AST"); - format!("{:#?}", ex.tcx().resolver_for_lowering().1.borrow()) + format!("{:#?}", &ex.tcx().resolver_for_lowering().1) } Hir(s) => { debug!("pretty printing HIR {:?}", s); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 55dffee912252..e28f0103f6de7 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -20,6 +20,7 @@ use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::steal::Steal; use rustc_data_structures::tagged_ptr::TaggedRef; +use rustc_data_structures::unord::UnordMap; use rustc_error_messages::{DiagArgValue, IntoDiagArg}; use rustc_index::IndexVec; use rustc_macros::{Decodable, Encodable, StableHash}; @@ -1728,6 +1729,8 @@ pub struct OwnerInfo<'hir> { /// Map indicating what traits are in scope for places where this /// is relevant; generated by resolve. pub trait_map: ItemLocalMap<&'hir [TraitCandidate<'hir>]>, + /// Owners generated as side-effect by lowering. + pub children: UnordMap>, /// Lints delayed during ast lowering to be emitted /// after hir has completely built @@ -1749,18 +1752,18 @@ impl<'tcx> OwnerInfo<'tcx> { pub enum MaybeOwner<'tcx> { Owner(&'tcx OwnerInfo<'tcx>), NonOwner(HirId), - /// Used as a placeholder for unused LocalDefId. - Phantom, } impl<'tcx> MaybeOwner<'tcx> { + #[inline] pub fn as_owner(self) -> Option<&'tcx OwnerInfo<'tcx>> { match self { MaybeOwner::Owner(i) => Some(i), - MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => None, + MaybeOwner::NonOwner(_) => None, } } + #[inline] pub fn unwrap(self) -> &'tcx OwnerInfo<'tcx> { self.as_owner().unwrap_or_else(|| panic!("Not a HIR owner")) } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 1c153e0be7f56..3f260207c2e5e 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -24,7 +24,7 @@ use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::{LOCAL_CRATE, StableCrateId, StableCrateIdMap}; use rustc_hir::definitions::Definitions; use rustc_hir::limit::Limit; -use rustc_hir::{Attribute, MaybeOwner, Target, find_attr}; +use rustc_hir::{Attribute, Target, find_attr}; use rustc_incremental::setup_dep_graph; use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore, unerased_lint_store}; use rustc_metadata::EncodedMetadata; @@ -400,7 +400,6 @@ fn print_macro_stats(ecx: &ExtCtxt<'_>) { fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { let sess = tcx.sess; let (resolver, krate) = tcx.resolver_for_lowering(); - let krate = &*krate.borrow(); let mut lint_buffer = resolver.lint_buffer.steal(); if sess.opts.unstable_opts.input_stats { @@ -479,7 +478,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { tcx.registered_tools(()), Some(lint_buffer), rustc_lint::BuiltinCombinedEarlyLintPass::new(), - (&**krate, &*krate.attrs), + (krate, &*krate.attrs), ) } @@ -787,7 +786,7 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P fn resolver_for_lowering_raw<'tcx>( tcx: TyCtxt<'tcx>, (): (), -) -> (&'tcx (ty::ResolverAstLowering<'tcx>, Steal>), &'tcx ty::ResolverGlobalCtxt) { +) -> (&'tcx ty::ResolverAstLowering<'tcx>, &'tcx ast::Crate, &'tcx ty::ResolverGlobalCtxt) { let arenas = Resolver::arenas(); let _ = tcx.registered_tools(()); // Uses `crate_for_resolver`. let (krate, pre_configured_attrs) = tcx.crate_for_resolver(()).steal(); @@ -808,8 +807,11 @@ fn resolver_for_lowering_raw<'tcx>( ast_lowering: untracked_resolver_for_lowering, } = resolver.into_outputs(); - let resolutions = tcx.arena.alloc(untracked_resolutions); - (tcx.arena.alloc((untracked_resolver_for_lowering, Steal::new(Arc::new(krate)))), resolutions) + ( + tcx.arena.alloc(untracked_resolver_for_lowering), + tcx.arena.alloc(krate), + tcx.arena.alloc(untracked_resolutions), + ) } pub fn write_dep_info(tcx: TyCtxt<'_>) { @@ -868,7 +870,6 @@ pub fn write_interface<'tcx>(tcx: TyCtxt<'tcx>) { } let _timer = tcx.sess.timer("write_interface"); let (_, krate) = tcx.resolver_for_lowering(); - let krate = &*krate.borrow(); let krate = rustc_ast_pretty::pprust::print_crate_as_interface( krate, @@ -885,12 +886,9 @@ pub fn write_interface<'tcx>(tcx: TyCtxt<'tcx>) { pub static DEFAULT_QUERY_PROVIDERS: LazyLock = LazyLock::new(|| { let providers = &mut Providers::default(); providers.queries.analysis = analysis; - // `hir_delayed_owner` is fed during `lower_delayed_owner`, by default it returns phantom, - // as if this query was not fed it means that `MaybeOwner` does not exist for provided LocalDefId. - providers.queries.hir_delayed_owner = |_, _| MaybeOwner::Phantom; providers.queries.resolver_for_lowering_raw = resolver_for_lowering_raw; providers.queries.stripped_cfg_items = |tcx, _| &tcx.resolutions(()).stripped_cfg_items[..]; - providers.queries.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).1; + providers.queries.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).2; providers.queries.early_lint_checks = early_lint_checks; providers.queries.env_var_os = env_var_os; rustc_ast_lowering::provide(&mut providers.queries); diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 5b8622aad38b6..1dc36196d8cdb 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -30,12 +30,12 @@ macro_rules! arena_types { rustc_hir::def_id::LocalDefId, rustc_middle::ty::DefinitionSiteHiddenType<'tcx>, >, - [] resolver: ( - rustc_middle::ty::ResolverAstLowering<'tcx>, - rustc_data_structures::steal::Steal< - std::sync::Arc - > - ), + [] resolver: rustc_middle::ty::ResolverAstLowering<'tcx>, + [] index_ast: rustc_index::IndexVec< + rustc_span::def_id::LocalDefId, + rustc_ast::AstOwner<'tcx> + >, + [] crate_alone: rustc_ast::Crate, [] crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>, [] resolutions: rustc_middle::ty::ResolverGlobalCtxt, [] const_allocs: rustc_middle::mir::interpret::Allocation, diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 50caa533c6819..785cf2548fda7 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -8,7 +8,7 @@ use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::stable_hash::{StableHash, StableHasher}; use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::{DynSend, DynSync, par_for_each_in, spawn, try_par_for_each_in}; +use rustc_data_structures::sync::{DynSend, DynSync, par_for_each_in, try_par_for_each_in}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalModDefId}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; @@ -1169,11 +1169,8 @@ impl<'tcx> pprust_hir::PpAnn for TyCtxt<'tcx> { } pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh { - let krate = tcx.hir_crate(()); - let hir_body_hash = krate.opt_hir_hash.expect("HIR hash missing while computing crate hash"); - + let krate = tcx.hir_crate_items(()); let upstream_crates = upstream_crates(tcx); - let resolutions = tcx.resolutions(()); // We hash the final, remapped names of all local source files so we @@ -1208,7 +1205,12 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh { let crate_hash: Fingerprint = tcx.with_stable_hashing_context(|mut hcx| { let mut stable_hasher = StableHasher::new(); - hir_body_hash.stable_hash(&mut hcx, &mut stable_hasher); + // 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); + } + } 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); @@ -1290,25 +1292,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod } } -fn force_delayed_owners_lowering(tcx: TyCtxt<'_>) { - let krate = tcx.hir_crate(()); - for &id in &krate.delayed_ids { - tcx.ensure_done().lower_delayed_owner(id); - } - - let krate = krate.ast_krate.steal(); - let prof = tcx.sess.prof.clone(); - - // Drop AST to free memory. It can be expensive so try to drop it on a separate thread. - spawn(move || { - let _timer = prof.verbose_generic_activity("drop_ast"); - drop(krate); - }); -} - pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { - force_delayed_owners_lowering(tcx); - let mut collector = ItemCollector::new(tcx, true); // A "crate collector" and "module collector" start at a diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 1f9703a9be912..4125b9c14eb4b 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -6,84 +6,21 @@ pub mod map; pub mod nested_filter; pub mod place; -use std::sync::Arc; - -use rustc_ast::{self as ast}; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::sorted_map::SortedMap; -use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt, StableHasher}; +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_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap, LocalModDefId}; use rustc_hir::lints::DelayedLints; use rustc_hir::*; -use rustc_index::IndexVec; use rustc_macros::{Decodable, Encodable, StableHash}; use rustc_span::{ErrorGuaranteed, ExpnId, Span}; use crate::query::Providers; use crate::ty::TyCtxt; -/// The top-level data structure that stores the entire contents of -/// the crate currently being compiled. -/// -/// For more details, see the [rustc dev guide]. -/// -/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html -#[derive(Debug)] -pub struct Crate<'hir> { - // This field is private by intention, access it through `owner` method. - owners: IndexVec>, - // Ids of delayed AST owners which are lowered through `lower_delayed_owner` query. - pub delayed_ids: FxIndexSet, - // The AST crate which are set in the end of the `hir_crate` query - // and then stolen and dropped in `force_delayed_owners_lowering`. - pub ast_krate: Steal>, - // Only present when incr. comp. is enabled. - pub opt_hir_hash: Option, -} - -impl<'hir> Crate<'hir> { - pub fn new( - owners: IndexVec>, - delayed_ids: FxIndexSet, - ast_krate: Steal>, - opt_hir_hash: Option, - ) -> Crate<'hir> { - Crate { owners, delayed_ids, ast_krate, opt_hir_hash } - } - - /// Serves as an entry point for getting `MaybeOwner`. As owner can either be in - /// `owners` of `hir_crate` or it can be delayed AST owner (i.e., delegations) - /// we need to firstly check in `hir_crate` and then delayed AST owners. - /// This method can be invoked when not all delayed AST owners are lowered. - pub fn owner(&self, tcx: TyCtxt<'hir>, def_id: LocalDefId) -> MaybeOwner<'hir> { - // Delayed LocalDefId can be in `self.owners` if there exists non-delayed LocalDefId - // which is greater than delayed LocalDefId, we use IndexVec for owners, - // so we will call ensure_contains_elem which will grow it. - if let Some(owner) = self.owners.get(def_id) - && (self.delayed_ids.is_empty() || !matches!(owner, MaybeOwner::Phantom)) - { - return *owner; - } - - if self.delayed_ids.contains(&def_id) { - tcx.ensure_done().lower_delayed_owner(def_id); - } - - tcx.hir_delayed_owner(def_id) - } -} - -impl StableHash for Crate<'_> { - fn stable_hash(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { - let Crate { opt_hir_hash, .. } = self; - opt_hir_hash.unwrap().stable_hash(hcx, hasher) - } -} - /// Gather the LocalDefId for each item-like within a module, including items contained within /// bodies. The Ids are in visitor order. This is used to partition a pass between modules. #[derive(Debug, StableHash, Encodable, Decodable)] @@ -486,7 +423,7 @@ pub enum ProjectedMaybeOwner<'tcx> { } impl<'tcx> ProjectedMaybeOwner<'tcx> { - pub fn new(value: MaybeOwner<'tcx>, def_id: LocalDefId) -> Self { + pub fn new(value: MaybeOwner<'tcx>) -> Self { match value { MaybeOwner::Owner(o) => ProjectedMaybeOwner::Owner(ProjectedOwnerInfo { nodes: &o.nodes, @@ -495,8 +432,6 @@ impl<'tcx> ProjectedMaybeOwner<'tcx> { delayed_lints: &o.delayed_lints, }), MaybeOwner::NonOwner(hir_id) => ProjectedMaybeOwner::NonOwner(hir_id), - // Can't debug fmt `def_id` since it doesn't exist. - MaybeOwner::Phantom => bug!("No HirId for {:?}", def_id.local_def_index), } } @@ -516,11 +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.hir_crate(()).owner(tcx, id.def_id).as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs) - }; - providers.hir_owner = - |tcx, def_id| ProjectedMaybeOwner::new(tcx.hir_crate(()).owner(tcx, def_id), def_id); + 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 86a38d882339f..a88ab20db9466 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -80,7 +80,6 @@ use rustc_span::def_id::LOCAL_CRATE; use rustc_span::{DUMMY_SP, LocalExpnId, Span, Spanned, Symbol}; use rustc_target::spec::PanicStrategy; -use crate::hir::Crate; use crate::infer::canonical::{self, Canonical}; use crate::lint::LintExpectation; use crate::metadata::ModChild; @@ -181,7 +180,8 @@ rustc_queries! { } query resolver_for_lowering_raw(_: ()) -> ( - &'tcx (ty::ResolverAstLowering<'tcx>, Steal>), + &'tcx ty::ResolverAstLowering<'tcx>, + &'tcx ast::Crate, &'tcx ty::ResolverGlobalCtxt, ) { eval_always @@ -189,6 +189,12 @@ rustc_queries! { desc { "getting the resolver for lowering" } } + query index_ast(_: ()) -> &'tcx IndexVec> { + eval_always + no_hash + desc { "getting the AST for lowering" } + } + /// Return the span for a definition. /// /// Contrary to `def_span` below, this query returns the full absolute span of the definition. @@ -200,22 +206,9 @@ rustc_queries! { desc { "getting the source span" } } - /// Represents crate as a whole (as distinct from the top-level crate module). - /// - /// If you call `tcx.hir_crate(())` we will have to assume that any change - /// means that you need to be recompiled. This is because the `hir_crate` - /// query gives you access to all other items. To avoid this fate, do not - /// call `tcx.hir_crate(())`; instead, prefer wrappers like - /// [`TyCtxt::hir_visit_all_item_likes_in_crate`]. - query hir_crate(key: ()) -> &'tcx Crate<'tcx> { - arena_cache - eval_always - desc { "getting the crate HIR" } - } - - query lower_delayed_owner(def_id: LocalDefId) { + query lower_to_hir(key: LocalDefId) -> hir::MaybeOwner<'tcx> { eval_always - desc { "lowering the delayed AST owner `{}`", tcx.def_path_str(def_id) } + desc { "lowering HIR for `{}`", tcx.def_path_str(key.to_def_id()) } } query hir_owner(def_id: LocalDefId) -> rustc_middle::hir::ProjectedMaybeOwner<'tcx> { @@ -223,11 +216,6 @@ rustc_queries! { feedable } - query hir_delayed_owner(def_id: LocalDefId) -> hir::MaybeOwner<'tcx> { - feedable - desc { "getting child of lowered delayed AST owner `{}`", tcx.def_path_str(def_id) } - } - /// All items in the crate. query hir_crate_items(_: ()) -> &'tcx rustc_middle::hir::ModuleItems { arena_cache @@ -2072,12 +2060,6 @@ rustc_queries! { desc { "getting delegation user-specified args" } } - query delegations_resolutions(_: ()) -> &'tcx FxIndexMap> { - arena_cache - eval_always - desc { "getting delegations resolutions" } - } - /// Does lifetime resolution on items. Importantly, we can't resolve /// lifetimes directly on things like trait methods, because of trait params. /// See `rustc_resolve::late::lifetimes` for details. diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 239451262ac42..a5fb77ced7656 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -147,6 +147,10 @@ impl Erasable for (&'_ T0, &'_ T1) { type Storage = [u8; size_of::<(&'_ (), &'_ ())>()]; } +impl Erasable for (&'_ T0, &'_ T1, &'_ T2) { + type Storage = [u8; size_of::<(&'_ (), &'_ (), &'_ ())>()]; +} + impl Erasable for (&'_ [T0], &'_ [T1]) { type Storage = [u8; size_of::<(&'_ [()], &'_ [()])>()]; } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 920b8aac07f92..8676a95e38914 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -35,7 +35,7 @@ use rustc_hir::definitions::{DefPathData, Definitions, PerParentDisambiguatorSta use rustc_hir::intravisit::VisitorExt; use rustc_hir::lang_items::LangItem; use rustc_hir::limit::Limit; -use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, MaybeOwner, Node, TraitCandidate, find_attr}; +use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, Node, TraitCandidate, find_attr}; use rustc_index::IndexVec; use rustc_macros::Diagnostic; use rustc_session::Session; @@ -605,12 +605,6 @@ impl<'tcx> TyCtxt<'tcx> { TyCtxtFeed { tcx: self, key }.type_of(value) } - /// Feeds the HIR delayed owner during AST -> HIR delayed lowering. - pub fn feed_delayed_owner(self, key: LocalDefId, owner: MaybeOwner<'tcx>) { - self.dep_graph.assert_ignored(); - TyCtxtFeed { tcx: self, key }.hir_delayed_owner(owner); - } - // Trait impl item visibility is inherited from its trait when not specified // explicitly. In that case we cannot determine it in early resolve, // but instead are feeding it in late resolve, where we don't have access to the @@ -2728,10 +2722,9 @@ impl<'tcx> TyCtxt<'tcx> { self.resolutions(()).extern_crate_map.get(&def_id).copied() } - pub fn resolver_for_lowering( - self, - ) -> &'tcx (ty::ResolverAstLowering<'tcx>, Steal>) { - self.resolver_for_lowering_raw(()).0 + pub fn resolver_for_lowering(self) -> (&'tcx ty::ResolverAstLowering<'tcx>, &'tcx ast::Crate) { + let (resolver, krate, _) = self.resolver_for_lowering_raw(()); + (resolver, krate) } pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode { diff --git a/compiler/rustc_passes/src/debugger_visualizer.rs b/compiler/rustc_passes/src/debugger_visualizer.rs index 00b1637be335c..24b26f1b0a16a 100644 --- a/compiler/rustc_passes/src/debugger_visualizer.rs +++ b/compiler/rustc_passes/src/debugger_visualizer.rs @@ -68,7 +68,7 @@ impl<'ast> rustc_ast::visit::Visitor<'ast> for DebuggerVisualizerCollector<'_> { /// Traverses and collects the debugger visualizers for a specific crate. fn debugger_visualizers(tcx: TyCtxt<'_>, _: LocalCrate) -> Vec { - let krate = &*tcx.resolver_for_lowering().1.borrow(); + let krate = &tcx.resolver_for_lowering().1; let mut visitor = DebuggerVisualizerCollector { sess: tcx.sess, visualizers: Vec::new() }; rustc_ast::visit::Visitor::visit_crate(&mut visitor, krate); diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index 48ddaafd88eb9..e2d651a5dd5e5 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -247,7 +247,6 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> { /// Traverses and collects all the lang items in all crates. fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems { let (resolver, krate) = tcx.resolver_for_lowering(); - let krate = &*krate.borrow(); // Initialize the collector. let mut collector = LanguageItemCollector::new(tcx, resolver); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index fccfa3f57e930..5f68fe14ddb99 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -348,7 +348,7 @@ pub(crate) fn run_global_ctxt( let expanded_macros = { // We need for these variables to be removed to ensure that the `Crate` won't be "stolen" // anymore. - let krate = &*tcx.resolver_for_lowering().1.borrow(); + let (_, krate) = tcx.resolver_for_lowering(); source_macro_expansion(&krate, &render_options, output_format, tcx.sess.source_map()) }; diff --git a/tests/ui/delegation/unused-target-expr-in-glob-or-list.stderr b/tests/ui/delegation/unused-target-expr-in-glob-or-list.stderr index 65091ac8b5d49..6244806e8af37 100644 --- a/tests/ui/delegation/unused-target-expr-in-glob-or-list.stderr +++ b/tests/ui/delegation/unused-target-expr-in-glob-or-list.stderr @@ -4,6 +4,28 @@ error[E0433]: cannot find type `UnresolvedTrait` in this scope LL | reuse UnresolvedTrait::* { self.0 } | ^^^^^^^^^^^^^^^ use of undeclared type `UnresolvedTrait` +error: delegation's target expression is specified for function with no params + --> $DIR/unused-target-expr-in-glob-or-list.rs:107:49 + | +LL | reuse ::static_self { self.0 } + | ^^^^^^^^^^ +... +LL | delegation!(); + | ------------- in this macro invocation + | + = note: this error originates in the macro `delegation` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: delegation's target expression is specified for function with no params + --> $DIR/unused-target-expr-in-glob-or-list.rs:127:45 + | +LL | reuse ::static_self { self.0 } + | ^^^^^^^^^^ +... +LL | delegation2!(); + | -------------- in this macro invocation + | + = note: this error originates in the macro `delegation2` (in Nightly builds, run with -Z macro-backtrace for more info) + error: delegation's target expression is specified for function with no params --> $DIR/unused-target-expr-in-glob-or-list.rs:154:45 | @@ -54,28 +76,6 @@ LL | reuse to_reuse::{value, mut_ref, r#ref} { 1 + 1 } | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: delegation's target expression is specified for function with no params - --> $DIR/unused-target-expr-in-glob-or-list.rs:107:49 - | -LL | reuse ::static_self { self.0 } - | ^^^^^^^^^^ -... -LL | delegation!(); - | ------------- in this macro invocation - | - = note: this error originates in the macro `delegation` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: delegation's target expression is specified for function with no params - --> $DIR/unused-target-expr-in-glob-or-list.rs:127:45 - | -LL | reuse ::static_self { self.0 } - | ^^^^^^^^^^ -... -LL | delegation2!(); - | -------------- in this macro invocation - | - = note: this error originates in the macro `delegation2` (in Nightly builds, run with -Z macro-backtrace for more info) - error: unused target expression is specified for glob or list delegation --> $DIR/unused-target-expr-in-glob-or-list.rs:18:25 | 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 c03ef9c70528f..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,7 +1,7 @@ error: internal compiler error: query cycle when printing cycle detected | = note: ...when getting owner for `Default` - = note: ...which requires getting the crate HIR... + = 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 +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 getting the crate HIR... + = 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/pin-ergonomics/pin_v2-attr.stderr b/tests/ui/pin-ergonomics/pin_v2-attr.stderr index 5c8a455114c42..8f8a9f3b3a19a 100644 --- a/tests/ui/pin-ergonomics/pin_v2-attr.stderr +++ b/tests/ui/pin-ergonomics/pin_v2-attr.stderr @@ -116,6 +116,14 @@ LL | #[pin_v2] | = help: `#[pin_v2]` can only be applied to data types +error: `#[pin_v2]` attribute cannot be used on delegations + --> $DIR/pin_v2-attr.rs:58:5 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can only be applied to data types + error: `#[pin_v2]` attribute cannot be used on inherent methods --> $DIR/pin_v2-attr.rs:61:5 | @@ -300,13 +308,5 @@ LL | #[pin_v2] | = help: `#[pin_v2]` can only be applied to data types -error: `#[pin_v2]` attribute cannot be used on delegations - --> $DIR/pin_v2-attr.rs:58:5 - | -LL | #[pin_v2] - | ^^^^^^^^^ - | - = help: `#[pin_v2]` can only be applied to data types - error: aborting due to 39 previous errors 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 c03ef9c70528f..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,7 +1,7 @@ error: internal compiler error: query cycle when printing cycle detected | = note: ...when getting owner for `Default` - = note: ...which requires getting the crate HIR... + = 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 +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 getting the crate HIR... + = 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 c03ef9c70528f..f224cd8f1063e 100644 --- a/tests/ui/resolve/query-cycle-issue-124901.stderr +++ b/tests/ui/resolve/query-cycle-issue-124901.stderr @@ -1,7 +1,7 @@ error: internal compiler error: query cycle when printing cycle detected | = note: ...when getting owner for `Default` - = note: ...which requires getting the crate HIR... + = 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 +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 getting the crate HIR... + = 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 0b8a18a902d187c62d1a698cd45c3c7d3e006b3d Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 22 Jun 2025 15:50:17 +0000 Subject: [PATCH 3/8] Precompute hash for OwnerInfo too. --- compiler/rustc_ast_lowering/src/lib.rs | 19 ++++++++++++++-- compiler/rustc_hir/src/hir.rs | 16 ++++++++------ compiler/rustc_hir/src/stable_hash_impls.rs | 22 ++++++++++++------- compiler/rustc_middle/src/hir/mod.rs | 6 ++--- .../src/coverage/hir_info.rs | 2 +- 5 files changed, 44 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 3e331e66d9e4d..3d8db90c11482 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -44,6 +44,7 @@ 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; @@ -765,14 +766,28 @@ impl<'hir> LoweringContext<'hir> { let bodies = SortedMap::from_presorted_elements(bodies); // Don't hash unless necessary, because it's expensive. - let rustc_middle::hir::Hashes { opt_hash_including_bodies, attrs_hash } = + let rustc_middle::hir::Hashes { bodies_hash, attrs_hash } = self.tcx.hash_owner_nodes(node, &bodies, &attrs, define_opaque); let num_nodes = self.item_local_id_counter.as_usize(); let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes); - let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies }; + 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 e28f0103f6de7..db46b42000891 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1663,9 +1663,9 @@ impl<'tcx> AttributeMap<'tcx> { /// These nodes are mapped by `ItemLocalId` alongside the index of their parent node. /// The HIR tree, including bodies, is pre-hashed. pub struct OwnerNodes<'tcx> { - /// Pre-computed hash of the full HIR. Used in the crate hash. Only present - /// when incr. comp. is enabled. - pub opt_hash_including_bodies: Option, + /// Pre-computed hash of the full HIR, including bodies. Used in the crate hash. + /// Only present when incr. comp. is enabled. + pub opt_hash: Option, /// Full HIR for the current owner. // The zeroth node's parent should never be accessed: the owner's parent is computed by the // hir_owner_parent query. It is set to `ItemLocalId::INVALID` to force an ICE if accidentally @@ -1686,7 +1686,7 @@ impl<'tcx> OwnerNodes<'tcx> { OwnerNodes { // There is no reason to bother computing a hash for a synthetic body. // Just use a constant value. - opt_hash_including_bodies: Some(Fingerprint::ZERO), + opt_hash: Some(Fingerprint::ZERO), nodes: IndexVec::from_elem_n( ParentedNode { parent: ItemLocalId::INVALID, node: OwnerNode::Synthetic.into() }, 1, @@ -1712,13 +1712,13 @@ impl fmt::Debug for OwnerNodes<'_> { }), ) .field("bodies", &self.bodies) - .field("opt_hash_including_bodies", &self.opt_hash_including_bodies) + .field("opt_hash", &self.opt_hash) .finish() } } /// Full information resulting from lowering an AST node. -#[derive(Debug, StableHash)] +#[derive(Debug)] pub struct OwnerInfo<'hir> { /// Contents of the HIR. pub nodes: OwnerNodes<'hir>, @@ -1737,8 +1737,10 @@ 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. - #[stable_hash(ignore)] pub delayed_lints: Steal, + + // Only present when the crate hash is needed. + pub opt_hash: Option, } impl<'tcx> OwnerInfo<'tcx> { diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index a8f97ba7f001d..3eadf0744df33 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, OwnerNodes}; +use crate::hir::{AttributeMap, OwnerInfo, OwnerNodes}; // The following implementations of StableHash for `ItemId`, `TraitItemId`, and // `ImplItemId` deserve special attention. Normally we do not hash `NodeId`s within @@ -12,13 +12,10 @@ use crate::hir::{AttributeMap, OwnerNodes}; impl<'tcx> StableHash for OwnerNodes<'tcx> { fn stable_hash(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { - // We ignore the `nodes` and `bodies` fields since these refer to information included in - // `hash` which is hashed in the collector and used for the crate hash. - // `local_id_to_def_id` is also ignored because is dependent on the body, then just hashing - // the body satisfies the condition of two nodes being different have different - // `stable_hash` results. - let OwnerNodes { opt_hash_including_bodies, nodes: _, bodies: _ } = *self; - opt_hash_including_bodies.unwrap().stable_hash(hcx, hasher); + // 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 OwnerNodes { opt_hash, .. } = *self; + opt_hash.unwrap().stable_hash(hcx, hasher); } } @@ -31,6 +28,15 @@ 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 */ diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 4125b9c14eb4b..a074ff3340275 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -176,7 +176,7 @@ impl<'tcx> TyCtxt<'tcx> { define_opaque: Option<&[(Span, LocalDefId)]>, ) -> Hashes { if !self.needs_hir_hash() { - return Hashes { opt_hash_including_bodies: None, attrs_hash: None }; + return Hashes { bodies_hash: None, attrs_hash: None }; } self.with_stable_hashing_context(|mut hcx| { @@ -194,7 +194,7 @@ impl<'tcx> TyCtxt<'tcx> { let h2 = stable_hasher.finish(); - Hashes { opt_hash_including_bodies: Some(h1), attrs_hash: Some(h2) } + Hashes { bodies_hash: Some(h1), attrs_hash: Some(h2) } }) } @@ -385,7 +385,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Hashes computed by [`TyCtxt::hash_owner_nodes`] if necessary. #[derive(Clone, Copy, Debug)] pub struct Hashes { - pub opt_hash_including_bodies: Option, + pub bodies_hash: Option, pub attrs_hash: Option, } diff --git a/compiler/rustc_mir_transform/src/coverage/hir_info.rs b/compiler/rustc_mir_transform/src/coverage/hir_info.rs index 85cf1970c12cc..ab66bf1a733ef 100644 --- a/compiler/rustc_mir_transform/src/coverage/hir_info.rs +++ b/compiler/rustc_mir_transform/src/coverage/hir_info.rs @@ -76,7 +76,7 @@ pub(crate) fn extract_hir_info<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> E fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx hir::Body<'tcx>) -> u64 { let owner = hir_body.id().hir_id.owner; tcx.hir_owner_nodes(owner) - .opt_hash_including_bodies + .opt_hash .expect("hash should be present when coverage instrumentation is enabled") .to_smaller_hash() .as_u64() From 5464994cddc0c5dfda3b6ffb0e925ffa32162ff6 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 2 Jul 2025 16:49:49 +0000 Subject: [PATCH 4/8] Split-up the AST to index it. --- Cargo.lock | 1 - compiler/rustc_ast/src/ast.rs | 12 +- compiler/rustc_ast/src/mut_visit.rs | 5 +- compiler/rustc_ast_lowering/Cargo.toml | 1 - compiler/rustc_ast_lowering/src/block.rs | 16 +- compiler/rustc_ast_lowering/src/expr.rs | 12 +- compiler/rustc_ast_lowering/src/item.rs | 27 +-- compiler/rustc_ast_lowering/src/lib.rs | 163 ++++++++++++++---- compiler/rustc_driver_impl/src/pretty.rs | 4 +- compiler/rustc_interface/src/passes.rs | 9 +- compiler/rustc_middle/src/arena.rs | 12 +- compiler/rustc_middle/src/queries.rs | 5 +- compiler/rustc_middle/src/ty/context.rs | 4 +- .../rustc_passes/src/debugger_visualizer.rs | 2 +- compiler/rustc_passes/src/lang_items.rs | 1 + src/librustdoc/core.rs | 2 +- ..._legacy_const_generics-issue-123077.stderr | 7 +- 17 files changed, 183 insertions(+), 100 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7092e498e937e..b9c8e1dd4f14b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3640,7 +3640,6 @@ version = "0.0.0" dependencies = [ "rustc_abi", "rustc_ast", - "rustc_ast_pretty", "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 7ee6ab7d8d867..8e601dd7f2fbb 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -4363,14 +4363,14 @@ impl TryFrom for ForeignItemKind { pub type ForeignItem = Item; #[derive(Debug)] -pub enum AstOwner<'a> { +pub enum AstOwner { NonOwner, Synthetic(rustc_span::def_id::LocalDefId), - Crate(&'a Crate), - Item(&'a Item), - TraitItem(&'a AssocItem), - ImplItem(&'a AssocItem), - ForeignItem(&'a ForeignItem), + Crate(Box), + Item(Box), + TraitItem(Box), + ImplItem(Box), + ForeignItem(Box), } // Some nodes are used a lot. Make sure they don't unintentionally get bigger. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 881b6ff107b56..0b81ad5ff952e 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -361,7 +361,10 @@ pub fn walk_flat_map_stmt( stmts } -fn walk_flat_map_stmt_kind(vis: &mut T, kind: StmtKind) -> SmallVec<[StmtKind; 1]> { +pub fn walk_flat_map_stmt_kind( + vis: &mut T, + kind: StmtKind, +) -> SmallVec<[StmtKind; 1]> { match kind { StmtKind::Let(mut local) => smallvec![StmtKind::Let({ vis.visit_local(&mut local); diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index 42befe958633b..f9c08de02512f 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -10,7 +10,6 @@ doctest = false # tidy-alphabetical-start rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } -rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs index 870b8897844aa..5396587005f66 100644 --- a/compiler/rustc_ast_lowering/src/block.rs +++ b/compiler/rustc_ast_lowering/src/block.rs @@ -44,17 +44,11 @@ impl<'hir> LoweringContext<'hir> { stmts.push(hir::Stmt { hir_id, kind, span }); } StmtKind::Item(it) => { - stmts.extend(self.lower_item_ref(it).into_iter().enumerate().map( - |(i, item_id)| { - let hir_id = match i { - 0 => self.lower_node_id(s.id), - _ => self.next_id(), - }; - let kind = hir::StmtKind::Item(item_id); - let span = self.lower_span(s.span); - hir::Stmt { hir_id, kind, span } - }, - )); + let item_id = self.lower_item_ref(it); + let hir_id = self.lower_node_id(s.id); + let kind = hir::StmtKind::Item(item_id); + let span = self.lower_span(s.span); + stmts.push(hir::Stmt { hir_id, kind, span }); } StmtKind::Expr(e) => { let e = self.lower_expr(e); diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index c2a570728a1a0..cee7ea3b1bc3f 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -4,7 +4,6 @@ use std::sync::Arc; use rustc_ast::node_id::NodeMap; use rustc_ast::*; -use rustc_ast_pretty::pprust::expr_to_string; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::msg; use rustc_hir as hir; @@ -557,13 +556,16 @@ impl<'hir> LoweringContext<'hir> { let mut invalid_expr_error = |tcx: TyCtxt<'_>, span| { // Avoid emitting the error multiple times. if error.is_none() { + let sm = tcx.sess.source_map(); let mut const_args = vec![]; let mut other_args = vec![]; for (idx, arg) in args.iter().enumerate() { - if legacy_args_idx.contains(&idx) { - const_args.push(format!("{{ {} }}", expr_to_string(arg))); - } else { - other_args.push(expr_to_string(arg)); + if let Ok(arg) = sm.span_to_snippet(arg.span) { + if legacy_args_idx.contains(&idx) { + const_args.push(format!("{{ {} }}", arg)); + } else { + other_args.push(arg); + } } } let suggestion = UseConstGenericArg { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 05732921c406e..49b1a4b378742 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -14,7 +14,7 @@ use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym}; -use smallvec::{SmallVec, smallvec}; +use smallvec::SmallVec; use thin_vec::ThinVec; use tracing::instrument; @@ -31,6 +31,7 @@ use crate::diagnostics::ConstComptimeFn; pub(super) struct ItemLowerer<'hir> { pub(super) tcx: TyCtxt<'hir>, pub(super) resolver: &'hir ResolverAstLowering<'hir>, + pub(super) next_node_id: NodeId, } /// When we have a ty alias we *may* have two where clauses. To give the best diagnostics, we set the span @@ -58,7 +59,7 @@ impl<'hir> ItemLowerer<'hir> { owner: NodeId, f: impl FnOnce(&mut LoweringContext<'hir>) -> hir::OwnerNode<'hir>, ) -> hir::MaybeOwner<'hir> { - let mut lctx = LoweringContext::new(self.tcx, self.resolver, owner); + let mut lctx = LoweringContext::new(self.tcx, self.resolver, owner, self.next_node_id); let item = f(&mut lctx); debug_assert_eq!(lctx.current_hir_id_owner, item.def_id()); @@ -107,28 +108,12 @@ impl<'hir> LoweringContext<'hir> { inner_span: self.lower_span(spans.inner_span), inject_use_span: self.lower_span(spans.inject_use_span), }, - item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_ref(x))), + item_ids: self.arena.alloc_from_iter(items.iter().map(|x| self.lower_item_ref(x))), }) } - pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> { - let mut node_ids = smallvec![hir::ItemId { owner_id: self.owner_id(i.id) }]; - if let ItemKind::Use(use_tree) = &i.kind { - self.lower_item_id_use_tree(use_tree, &mut node_ids); - } - node_ids - } - - fn lower_item_id_use_tree(&mut self, tree: &UseTree, vec: &mut SmallVec<[hir::ItemId; 1]>) { - match &tree.kind { - UseTreeKind::Nested { items, .. } => { - for &(ref nested, id) in items { - vec.push(hir::ItemId { owner_id: self.owner_id(id) }); - self.lower_item_id_use_tree(nested, vec); - } - } - UseTreeKind::Simple(..) | UseTreeKind::Glob(_) => {} - } + pub(super) fn lower_item_ref(&mut self, i: &Item) -> hir::ItemId { + hir::ItemId { owner_id: self.owner_id(i.id) } } fn lower_eii_decl( diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 3d8db90c11482..292baef70325d 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -38,6 +38,7 @@ use std::mem; use std::sync::Arc; +use rustc_ast::mut_visit::{self, MutVisitor}; use rustc_ast::node_id::NodeMap; use rustc_ast::visit::{self, Visitor}; use rustc_ast::{self as ast, *}; @@ -66,7 +67,7 @@ use rustc_middle::ty::{PerOwnerResolverData, ResolverAstLowering, TyCtxt}; use rustc_session::errors::add_feature_diagnostics; use rustc_span::symbol::{Ident, Symbol, kw, sym}; use rustc_span::{DUMMY_SP, DesugaringKind, Span}; -use smallvec::SmallVec; +use smallvec::{SmallVec, smallvec}; use thin_vec::ThinVec; use tracing::{debug, instrument, trace}; @@ -174,7 +175,12 @@ struct LoweringContext<'hir> { } impl<'hir> LoweringContext<'hir> { - fn new(tcx: TyCtxt<'hir>, resolver: &'hir ResolverAstLowering<'hir>, owner: NodeId) -> Self { + fn new( + tcx: TyCtxt<'hir>, + resolver: &'hir ResolverAstLowering<'hir>, + owner: NodeId, + next_node_id: NodeId, + ) -> Self { let current_ast_owner = &resolver.owners[&owner]; let current_hir_id_owner = hir::OwnerId { def_id: current_ast_owner.def_id }; let current_disambiguator = resolver @@ -204,7 +210,7 @@ impl<'hir> LoweringContext<'hir> { #[cfg(debug_assertions)] node_id_to_local_id: Default::default(), trait_map: Default::default(), - next_node_id: resolver.next_node_id, + next_node_id, node_id_to_def_id: NodeMap::default(), partial_res_overrides: NodeMap::default(), @@ -453,68 +459,153 @@ enum TryBlockScope { Heterogeneous(HirId), } -fn index_ast<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx IndexVec> { +fn index_ast<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> (IndexVec>, NodeId) { + // Queries that borrow `resolver_for_lowering`. + tcx.ensure_done().output_filenames(()); + tcx.ensure_done().early_lint_checks(()); + tcx.ensure_done().get_lang_items(()); + tcx.ensure_done().debugger_visualizers(LOCAL_CRATE); + let (resolver, krate) = tcx.resolver_for_lowering(); + let mut krate = krate.steal(); - let mut indexer = Indexer { owners: &resolver.owners, index: IndexVec::new() }; - indexer.visit_crate(&krate); - indexer.insert(CRATE_NODE_ID, AstOwner::Crate(&*krate)); - return tcx.arena.alloc(indexer.index); + let mut indexer = Indexer { + owners: &resolver.owners, + index: IndexVec::new(), + next_node_id: resolver.next_node_id, + }; + indexer.visit_crate(&mut krate); + indexer.insert(CRATE_NODE_ID, AstOwner::Crate(Box::new(krate))); + return (indexer.index, indexer.next_node_id); struct Indexer<'s, 'ast> { owners: &'s NodeMap>, - index: IndexVec>, + index: IndexVec>, + next_node_id: NodeId, } - impl<'ast> Indexer<'_, 'ast> { - fn insert(&mut self, id: NodeId, node: AstOwner<'ast>) { + impl Indexer<'_, '_> { + fn insert(&mut self, id: NodeId, node: AstOwner) { let def_id = self.owners[&id].def_id; - self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner); - self.index[def_id] = node; + self.index.ensure_contains_elem(def_id, || Steal::new(AstOwner::NonOwner)); + self.index[def_id] = Steal::new(node); + } + + fn make_dummy( + &mut self, + id: NodeId, + span: Span, + dummy: impl FnOnce(Box) -> K, + ) -> Box> { + use rustc_ast::token::Delimiter; + use rustc_ast::tokenstream::{DelimSpan, TokenStream}; + use thin_vec::thin_vec; + + Box::new(Item { + attrs: AttrVec::default(), + id, + span, + vis: Visibility { kind: VisibilityKind::Public, span, tokens: None }, + // Lacking a better choice, we replace the contents with a macro call. + // Unexpanded macros should never reach lowering, so this is not confusing. + kind: dummy(Box::new(MacCall { + path: Path { span, segments: thin_vec![], tokens: None }, + args: Box::new(DelimArgs { + dspan: DelimSpan::from_single(span), + delim: Delimiter::Parenthesis, + tokens: TokenStream::new(Vec::new()), + }), + })), + tokens: None, + }) } - fn visit_item_id_use_tree(&mut self, tree: &UseTree, parent: LocalDefId) { + fn replace_with_dummy( + &mut self, + item: &mut ast::Item, + dummy: impl FnOnce(Box) -> K, + node: impl FnOnce(Box>) -> AstOwner, + ) { + let dummy = self.make_dummy(item.id, item.span, dummy); + let item = std::mem::replace(item, *dummy); + self.insert(item.id, node(Box::new(item))); + } + + #[tracing::instrument(level = "trace", skip(self))] + fn visit_item_id_use_tree( + &mut self, + tree: &UseTree, + parent: LocalDefId, + items: &mut SmallVec<[Box; 1]>, + ) { match tree.kind { UseTreeKind::Glob(_) | UseTreeKind::Simple(_) => {} - UseTreeKind::Nested { items: ref nested_vec, span: _ } => { + UseTreeKind::Nested { items: ref nested_vec, span } => { for &(ref nested, id) in nested_vec { self.insert(id, AstOwner::Synthetic(parent)); + items.push(self.make_dummy(id, span, ItemKind::MacCall)); let def_id = self.owners[&id].def_id; - self.visit_item_id_use_tree(nested, def_id); + self.visit_item_id_use_tree(nested, def_id, items); } } } } } - impl<'ast> visit::Visitor<'ast> for Indexer<'_, 'ast> { - fn visit_attribute(&mut self, _: &'ast Attribute) { + impl MutVisitor for Indexer<'_, '_> { + fn visit_attribute(&mut self, _: &mut Attribute) { // We do not want to lower expressions that appear in attributes, // as they are not accessible to the rest of the HIR. } - fn visit_item(&mut self, item: &'ast Item) { + fn flat_map_item(&mut self, mut item: Box) -> SmallVec<[Box; 1]> { let def_id = self.owners[&item.id].def_id; + mut_visit::walk_item(self, &mut *item); + let dummy = self.make_dummy(item.id, item.span, ItemKind::MacCall); + let mut items = smallvec![dummy]; if let ItemKind::Use(ref use_tree) = item.kind { - self.visit_item_id_use_tree(use_tree, def_id); + self.visit_item_id_use_tree(use_tree, def_id, &mut items); } - visit::walk_item(self, item); self.insert(item.id, AstOwner::Item(item)); + items } - fn visit_assoc_item(&mut self, item: &'ast AssocItem, ctxt: visit::AssocCtxt) { - visit::walk_assoc_item(self, item, ctxt); - let owner_ref = match ctxt { - visit::AssocCtxt::Trait => AstOwner::TraitItem(item), - visit::AssocCtxt::Impl { .. } => AstOwner::ImplItem(item), - }; - self.insert(item.id, owner_ref); + fn flat_map_stmt(&mut self, stmt: Stmt) -> SmallVec<[Stmt; 1]> { + let Stmt { id, span, kind } = stmt; + let mut id = Some(id); + mut_visit::walk_flat_map_stmt_kind(self, kind) + .into_iter() + .map(|kind| { + // Expanding the current statement is a nested `use` item, + // it is expanded into several flat `use` items. + // Create new NodeIds for the corresponding statements + // as two statements cannot have the same. + let id = id.take().unwrap_or_else(|| { + let next = self.next_node_id; + self.next_node_id.increment_by(1); + next + }); + Stmt { id, kind, span } + }) + .collect() } - fn visit_foreign_item(&mut self, item: &'ast ForeignItem) { - visit::walk_item(self, item); - self.insert(item.id, AstOwner::ForeignItem(item)); + fn visit_assoc_item(&mut self, item: &mut AssocItem, ctxt: visit::AssocCtxt) { + mut_visit::walk_assoc_item(self, item, ctxt); + match ctxt { + visit::AssocCtxt::Trait => { + self.replace_with_dummy(item, AssocItemKind::MacCall, AstOwner::TraitItem) + } + visit::AssocCtxt::Impl { .. } => { + self.replace_with_dummy(item, AssocItemKind::MacCall, AstOwner::ImplItem) + } + } + } + + fn visit_foreign_item(&mut self, item: &mut ForeignItem) { + mut_visit::walk_item(self, item); + self.replace_with_dummy(item, ForeignItemKind::MacCall, AstOwner::ForeignItem); } } } @@ -527,13 +618,13 @@ fn lower_to_hir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::MaybeOwner<'_> { tcx.ensure_done().debugger_visualizers(LOCAL_CRATE); tcx.ensure_done().get_lang_items(()); let (resolver, _) = tcx.resolver_for_lowering(); - let ast_index = tcx.index_ast(()); - let node = ast_index.get(def_id); + let (ast_index, next_node_id) = tcx.index_ast(()); + let node = ast_index.get(def_id).map(Steal::steal); - let mut item_lowerer = item::ItemLowerer { tcx, resolver }; + let mut item_lowerer = item::ItemLowerer { tcx, resolver, next_node_id: *next_node_id }; // The item existed in the AST. - let parent_id = match node { + let parent_id = match node.as_ref() { Some(AstOwner::Crate(c)) => return item_lowerer.lower_crate(&c), Some(AstOwner::Item(item)) => return item_lowerer.lower_item(&item), Some(AstOwner::TraitItem(item)) => { @@ -547,6 +638,8 @@ fn lower_to_hir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::MaybeOwner<'_> { Some(AstOwner::NonOwner) | None => tcx.local_parent(def_id), }; + tcx.sess.time("drop_ast", || std::mem::drop(node)); + // The item did not exist in the AST, it was created by its parent. let mut parent_info = tcx.lower_to_hir(parent_id); if let hir::MaybeOwner::NonOwner(hir_id) = parent_info { diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 79a70844585a1..3a0a6687dd812 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -214,7 +214,7 @@ impl<'tcx> PrintExtra<'tcx> { { match self { PrintExtra::AfterParsing { krate, .. } => f(krate), - PrintExtra::NeedsAstMap { tcx } => f(&tcx.resolver_for_lowering().1), + PrintExtra::NeedsAstMap { tcx } => f(&tcx.resolver_for_lowering().1.borrow()), } } @@ -263,7 +263,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { } AstTreeExpanded => { debug!("pretty-printing expanded AST"); - format!("{:#?}", &ex.tcx().resolver_for_lowering().1) + format!("{:#?}", ex.tcx().resolver_for_lowering().1.borrow()) } Hir(s) => { debug!("pretty printing HIR {:?}", s); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 3f260207c2e5e..9adc353825fc2 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -400,6 +400,7 @@ fn print_macro_stats(ecx: &ExtCtxt<'_>) { fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { let sess = tcx.sess; let (resolver, krate) = tcx.resolver_for_lowering(); + let krate = &*krate.borrow(); let mut lint_buffer = resolver.lint_buffer.steal(); if sess.opts.unstable_opts.input_stats { @@ -478,7 +479,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { tcx.registered_tools(()), Some(lint_buffer), rustc_lint::BuiltinCombinedEarlyLintPass::new(), - (krate, &*krate.attrs), + (&*krate, &*krate.attrs), ) } @@ -786,7 +787,7 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P fn resolver_for_lowering_raw<'tcx>( tcx: TyCtxt<'tcx>, (): (), -) -> (&'tcx ty::ResolverAstLowering<'tcx>, &'tcx ast::Crate, &'tcx ty::ResolverGlobalCtxt) { +) -> (&'tcx ty::ResolverAstLowering<'tcx>, &'tcx Steal, &'tcx ty::ResolverGlobalCtxt) { let arenas = Resolver::arenas(); let _ = tcx.registered_tools(()); // Uses `crate_for_resolver`. let (krate, pre_configured_attrs) = tcx.crate_for_resolver(()).steal(); @@ -809,7 +810,7 @@ fn resolver_for_lowering_raw<'tcx>( ( tcx.arena.alloc(untracked_resolver_for_lowering), - tcx.arena.alloc(krate), + tcx.arena.alloc(Steal::new(krate)), tcx.arena.alloc(untracked_resolutions), ) } @@ -872,7 +873,7 @@ pub fn write_interface<'tcx>(tcx: TyCtxt<'tcx>) { let (_, krate) = tcx.resolver_for_lowering(); let krate = rustc_ast_pretty::pprust::print_crate_as_interface( - krate, + &*krate.borrow(), tcx.sess.psess.edition, &tcx.sess.psess.attr_id_generator, ); diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 1dc36196d8cdb..135a38021114e 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -31,11 +31,13 @@ macro_rules! arena_types { rustc_middle::ty::DefinitionSiteHiddenType<'tcx>, >, [] resolver: rustc_middle::ty::ResolverAstLowering<'tcx>, - [] index_ast: rustc_index::IndexVec< - rustc_span::def_id::LocalDefId, - rustc_ast::AstOwner<'tcx> - >, - [] crate_alone: rustc_ast::Crate, + [] index_ast: ( + rustc_index::IndexVec + >, + rustc_ast::NodeId, + ), + [] crate_alone: rustc_data_structures::steal::Steal, [] crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>, [] resolutions: rustc_middle::ty::ResolverGlobalCtxt, [] const_allocs: rustc_middle::mir::interpret::Allocation, diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index a88ab20db9466..3cab32406e17c 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -181,7 +181,7 @@ rustc_queries! { query resolver_for_lowering_raw(_: ()) -> ( &'tcx ty::ResolverAstLowering<'tcx>, - &'tcx ast::Crate, + &'tcx Steal, &'tcx ty::ResolverGlobalCtxt, ) { eval_always @@ -189,7 +189,8 @@ rustc_queries! { desc { "getting the resolver for lowering" } } - query index_ast(_: ()) -> &'tcx IndexVec> { + query index_ast(_: ()) -> &'tcx (IndexVec>, ast::NodeId) { + arena_cache eval_always no_hash desc { "getting the AST for lowering" } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 8676a95e38914..36fdac0de6ab3 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2722,7 +2722,9 @@ impl<'tcx> TyCtxt<'tcx> { self.resolutions(()).extern_crate_map.get(&def_id).copied() } - pub fn resolver_for_lowering(self) -> (&'tcx ty::ResolverAstLowering<'tcx>, &'tcx ast::Crate) { + pub fn resolver_for_lowering( + self, + ) -> (&'tcx ty::ResolverAstLowering<'tcx>, &'tcx Steal) { let (resolver, krate, _) = self.resolver_for_lowering_raw(()); (resolver, krate) } diff --git a/compiler/rustc_passes/src/debugger_visualizer.rs b/compiler/rustc_passes/src/debugger_visualizer.rs index 24b26f1b0a16a..493abd74cbfb8 100644 --- a/compiler/rustc_passes/src/debugger_visualizer.rs +++ b/compiler/rustc_passes/src/debugger_visualizer.rs @@ -71,7 +71,7 @@ fn debugger_visualizers(tcx: TyCtxt<'_>, _: LocalCrate) -> Vec LanguageItemCollector<'ast, 'tcx> { /// Traverses and collects all the lang items in all crates. fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems { let (resolver, krate) = tcx.resolver_for_lowering(); + let krate = &*krate.borrow(); // Initialize the collector. let mut collector = LanguageItemCollector::new(tcx, resolver); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 5f68fe14ddb99..fccfa3f57e930 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -348,7 +348,7 @@ pub(crate) fn run_global_ctxt( let expanded_macros = { // We need for these variables to be removed to ensure that the `Crate` won't be "stolen" // anymore. - let (_, krate) = tcx.resolver_for_lowering(); + let krate = &*tcx.resolver_for_lowering().1.borrow(); source_macro_expansion(&krate, &render_options, output_format, tcx.sess.source_map()) }; diff --git a/tests/ui/const-generics/invalid-rustc_legacy_const_generics-issue-123077.stderr b/tests/ui/const-generics/invalid-rustc_legacy_const_generics-issue-123077.stderr index 6f5d719006d8f..111d6d524e5fb 100644 --- a/tests/ui/const-generics/invalid-rustc_legacy_const_generics-issue-123077.stderr +++ b/tests/ui/const-generics/invalid-rustc_legacy_const_generics-issue-123077.stderr @@ -67,9 +67,10 @@ LL | struct F(); help: try using a const generic argument instead | LL ~ std::arch::x86_64::_mm_blend_ps::<{ { -LL + struct F(); -LL + 1 -LL ~ } }>(loop {}, loop {}); +LL + struct F(); +LL + +LL + 1 +LL ~ } }>(loop {}, loop {}); | error: invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items From 0e9f9312c3d07f9daca7753b3bb521dad309996a Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sun, 26 Apr 2026 01:04:32 +0000 Subject: [PATCH 5/8] Steal ResolverAstLowering when indexing AST. --- compiler/rustc_ast_lowering/src/asm.rs | 2 +- compiler/rustc_ast_lowering/src/block.rs | 2 +- compiler/rustc_ast_lowering/src/contract.rs | 2 +- compiler/rustc_ast_lowering/src/delegation.rs | 10 +- .../src/delegation/generics.rs | 6 +- compiler/rustc_ast_lowering/src/expr.rs | 4 +- .../rustc_ast_lowering/src/expr/closure.rs | 2 +- compiler/rustc_ast_lowering/src/format.rs | 6 +- compiler/rustc_ast_lowering/src/item.rs | 17 ++- compiler/rustc_ast_lowering/src/lib.rs | 111 ++++++++++-------- compiler/rustc_ast_lowering/src/pat.rs | 2 +- compiler/rustc_ast_lowering/src/path.rs | 2 +- compiler/rustc_interface/src/passes.rs | 9 +- compiler/rustc_middle/src/arena.rs | 15 +-- compiler/rustc_middle/src/queries.rs | 7 +- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_passes/src/lang_items.rs | 1 + 17 files changed, 108 insertions(+), 92 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index eff38fe124fe3..5628dffd51358 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -21,7 +21,7 @@ use crate::{ AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode, }; -impl<'hir> LoweringContext<'hir> { +impl<'hir> LoweringContext<'_, 'hir> { pub(crate) fn lower_inline_asm( &mut self, sp: Span, diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs index 5396587005f66..b52af8fd3715a 100644 --- a/compiler/rustc_ast_lowering/src/block.rs +++ b/compiler/rustc_ast_lowering/src/block.rs @@ -6,7 +6,7 @@ use smallvec::SmallVec; use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext}; -impl<'hir> LoweringContext<'hir> { +impl<'hir> LoweringContext<'_, 'hir> { pub(super) fn lower_block( &mut self, b: &Block, diff --git a/compiler/rustc_ast_lowering/src/contract.rs b/compiler/rustc_ast_lowering/src/contract.rs index 6cd36142176cd..4b2ee21ca5980 100644 --- a/compiler/rustc_ast_lowering/src/contract.rs +++ b/compiler/rustc_ast_lowering/src/contract.rs @@ -4,7 +4,7 @@ use thin_vec::thin_vec; use crate::LoweringContext; -impl<'hir> LoweringContext<'hir> { +impl<'hir> LoweringContext<'_, 'hir> { /// Lowered contracts are guarded with the `contract_checks` compiler flag, /// i.e. the flag turns into a boolean guard in the lowered HIR. The reason /// for not eliminating the contract code entirely when the `contract_checks` diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 511e9ee5f3ebf..3ead3b86cb591 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -120,7 +120,7 @@ static ATTRS_ADDITIONS: &[AttrAdditionInfo] = &[ }, ]; -impl<'hir> LoweringContext<'hir> { +impl<'hir> LoweringContext<'_, 'hir> { fn is_method(&self, def_id: DefId, span: Span) -> bool { match self.tcx.def_kind(def_id) { DefKind::Fn => false, @@ -748,13 +748,13 @@ impl<'hir> LoweringContext<'hir> { } } -struct SelfResolver<'a, 'hir> { - ctxt: &'a mut LoweringContext<'hir>, +struct SelfResolver<'a, 'b, 'hir> { + ctxt: &'a mut LoweringContext<'b, 'hir>, path_id: NodeId, self_param_id: NodeId, } -impl SelfResolver<'_, '_> { +impl SelfResolver<'_, '_, '_> { fn try_replace_id(&mut self, id: NodeId) { if let Some(res) = self.ctxt.get_partial_res(id) && let Some(Res::Local(sig_id)) = res.full_res() @@ -765,7 +765,7 @@ impl SelfResolver<'_, '_> { } } -impl<'ast> Visitor<'ast> for SelfResolver<'_, '_> { +impl<'ast> Visitor<'ast> for SelfResolver<'_, '_, '_> { fn visit_id(&mut self, id: NodeId) { self.try_replace_id(id); } diff --git a/compiler/rustc_ast_lowering/src/delegation/generics.rs b/compiler/rustc_ast_lowering/src/delegation/generics.rs index f5e4a7164d40f..f8e3528750035 100644 --- a/compiler/rustc_ast_lowering/src/delegation/generics.rs +++ b/compiler/rustc_ast_lowering/src/delegation/generics.rs @@ -114,7 +114,7 @@ impl DelegationGenericsKind { impl<'hir> HirOrTyGenerics<'hir> { pub(super) fn into_hir_generics( &mut self, - ctx: &mut LoweringContext<'hir>, + ctx: &mut LoweringContext<'_, 'hir>, span: Span, ) -> &mut HirOrTyGenerics<'hir> { if let HirOrTyGenerics::Ty(ty) = self { @@ -140,7 +140,7 @@ impl<'hir> HirOrTyGenerics<'hir> { pub(super) fn into_generic_args( &self, - ctx: &mut LoweringContext<'hir>, + ctx: &mut LoweringContext<'_, 'hir>, span: Span, ) -> &'hir hir::GenericArgs<'hir> { match self { @@ -203,7 +203,7 @@ impl<'hir> GenericsGenerationResults<'hir> { } } -impl<'hir> LoweringContext<'hir> { +impl<'hir> LoweringContext<'_, 'hir> { pub(super) fn uplift_delegation_generics( &mut self, delegation: &Delegation, diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index cee7ea3b1bc3f..f66d1ac16c907 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -115,7 +115,7 @@ impl<'v> rustc_ast::visit::Visitor<'v> for WillCreateDefIdsVisitor { } } -impl<'hir> LoweringContext<'hir> { +impl<'hir> LoweringContext<'_, 'hir> { fn with_move_expr_bindings( &mut self, state: Option>, @@ -1171,7 +1171,7 @@ impl<'hir> LoweringContext<'hir> { whole_span: Span, ) -> hir::ExprKind<'hir> { // Return early in case of an ordinary assignment. - fn is_ordinary(lower_ctx: &mut LoweringContext<'_>, lhs: &Expr) -> bool { + fn is_ordinary(lower_ctx: &mut LoweringContext<'_, '_>, lhs: &Expr) -> bool { match &lhs.kind { ExprKind::Array(..) | ExprKind::Struct(..) diff --git a/compiler/rustc_ast_lowering/src/expr/closure.rs b/compiler/rustc_ast_lowering/src/expr/closure.rs index 930eb0b475475..cc2c6ae2879c1 100644 --- a/compiler/rustc_ast_lowering/src/expr/closure.rs +++ b/compiler/rustc_ast_lowering/src/expr/closure.rs @@ -9,7 +9,7 @@ use super::{LoweringContext, MoveExprInitializerFinder, MoveExprState}; use crate::FnDeclKind; use crate::diagnostics::{ClosureCannotBeStatic, CoroutineTooManyParameters}; -impl<'hir> LoweringContext<'hir> { +impl<'hir> LoweringContext<'_, 'hir> { // Entry point for `ExprKind::Closure`. Plain closures go through // `lower_expr_plain_closure_with_move_exprs`, which can wrap the lowered // closure in `let` initializers for `move(...)`. Coroutine closures keep the diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index 2332af6b1bccf..602635af1324e 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -8,7 +8,7 @@ use rustc_span::{ByteSymbol, DesugaringKind, Ident, Span, Symbol, sym}; use super::LoweringContext; -impl<'hir> LoweringContext<'hir> { +impl<'hir> LoweringContext<'_, 'hir> { pub(crate) fn lower_format_args(&mut self, sp: Span, fmt: &FormatArgs) -> hir::ExprKind<'hir> { // Never call the const constructor of `fmt::Arguments` if the // format_args!() had any arguments _before_ flattening/inlining. @@ -230,7 +230,7 @@ enum ArgumentType { /// ::new_…(arg) /// ``` fn make_argument<'hir>( - ctx: &mut LoweringContext<'hir>, + ctx: &mut LoweringContext<'_, 'hir>, sp: Span, arg: &'hir hir::Expr<'hir>, ty: ArgumentType, @@ -277,7 +277,7 @@ fn make_count( } fn expand_format_args<'hir>( - ctx: &mut LoweringContext<'hir>, + ctx: &mut LoweringContext<'_, 'hir>, macsp: Span, fmt: &FormatArgs, allow_const: bool, diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 49b1a4b378742..6340d125cb72c 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -28,10 +28,9 @@ use super::{ }; use crate::diagnostics::ConstComptimeFn; -pub(super) struct ItemLowerer<'hir> { +pub(super) struct ItemLowerer<'a, 'hir> { pub(super) tcx: TyCtxt<'hir>, - pub(super) resolver: &'hir ResolverAstLowering<'hir>, - pub(super) next_node_id: NodeId, + pub(super) resolver: &'a ResolverAstLowering<'hir>, } /// When we have a ty alias we *may* have two where clauses. To give the best diagnostics, we set the span @@ -53,13 +52,13 @@ fn add_ty_alias_where_clause( if before.0 || !after.0 { before } else { after }; } -impl<'hir> ItemLowerer<'hir> { +impl<'hir> ItemLowerer<'_, 'hir> { fn with_lctx( &mut self, owner: NodeId, - f: impl FnOnce(&mut LoweringContext<'hir>) -> hir::OwnerNode<'hir>, + f: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::OwnerNode<'hir>, ) -> hir::MaybeOwner<'hir> { - let mut lctx = LoweringContext::new(self.tcx, self.resolver, owner, self.next_node_id); + let mut lctx = LoweringContext::new(self.tcx, self.resolver, owner); let item = f(&mut lctx); debug_assert_eq!(lctx.current_hir_id_owner, item.def_id()); @@ -97,7 +96,7 @@ impl<'hir> ItemLowerer<'hir> { } } -impl<'hir> LoweringContext<'hir> { +impl<'hir> LoweringContext<'_, 'hir> { pub(super) fn lower_mod( &mut self, items: &[Box], @@ -1475,7 +1474,7 @@ impl<'hir> LoweringContext<'hir> { pub(crate) fn lower_coroutine_body_with_moved_arguments( &mut self, decl: &FnDecl, - lower_body: impl FnOnce(&mut LoweringContext<'hir>) -> hir::Expr<'hir>, + lower_body: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::Expr<'hir>, fn_decl_span: Span, body_span: Span, coroutine_kind: CoroutineKind, @@ -1612,7 +1611,7 @@ impl<'hir> LoweringContext<'hir> { parameters.push(new_parameter); } - let mkbody = |this: &mut LoweringContext<'hir>| { + let mkbody = |this: &mut LoweringContext<'_, 'hir>| { // Create a block from the user's function body: let user_body = lower_body(this); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 292baef70325d..3f7d6b72a179e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -97,9 +97,9 @@ pub fn provide(providers: &mut Providers) { providers.lower_to_hir = lower_to_hir; } -struct LoweringContext<'hir> { +struct LoweringContext<'a, 'hir> { tcx: TyCtxt<'hir>, - resolver: &'hir ResolverAstLowering<'hir>, + resolver: &'a ResolverAstLowering<'hir>, current_disambiguator: PerParentDisambiguatorState, /// Used to allocate HIR nodes. @@ -132,7 +132,7 @@ struct LoweringContext<'hir> { is_in_dyn_type: bool, current_hir_id_owner: hir::OwnerId, - owner: &'hir PerOwnerResolverData<'hir>, + owner: &'a PerOwnerResolverData<'hir>, item_local_id_counter: hir::ItemLocalId, trait_map: ItemLocalMap<&'hir [TraitCandidate<'hir>]>, @@ -174,13 +174,8 @@ struct LoweringContext<'hir> { attribute_parser: AttributeParser<'hir>, } -impl<'hir> LoweringContext<'hir> { - fn new( - tcx: TyCtxt<'hir>, - resolver: &'hir ResolverAstLowering<'hir>, - owner: NodeId, - next_node_id: NodeId, - ) -> Self { +impl<'a, 'hir> LoweringContext<'a, 'hir> { + fn new(tcx: TyCtxt<'hir>, resolver: &'a ResolverAstLowering<'hir>, owner: NodeId) -> Self { let current_ast_owner = &resolver.owners[&owner]; let current_hir_id_owner = hir::OwnerId { def_id: current_ast_owner.def_id }; let current_disambiguator = resolver @@ -210,7 +205,7 @@ impl<'hir> LoweringContext<'hir> { #[cfg(debug_assertions)] node_id_to_local_id: Default::default(), trait_map: Default::default(), - next_node_id, + next_node_id: resolver.next_node_id, node_id_to_def_id: NodeMap::default(), partial_res_overrides: NodeMap::default(), @@ -459,7 +454,10 @@ enum TryBlockScope { Heterogeneous(HirId), } -fn index_ast<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> (IndexVec>, NodeId) { +fn index_ast<'tcx>( + tcx: TyCtxt<'tcx>, + (): (), +) -> IndexVec>, AstOwner)>> { // Queries that borrow `resolver_for_lowering`. tcx.ensure_done().output_filenames(()); tcx.ensure_done().early_lint_checks(()); @@ -467,6 +465,7 @@ fn index_ast<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> (IndexVec(tcx: TyCtxt<'tcx>, (): ()) -> (IndexVec { - owners: &'s NodeMap>, - index: IndexVec>, + let index = indexer.index; + let resolver = Arc::new(resolver); + let index = index.into_iter().map(|owner| Steal::new((Arc::clone(&resolver), owner))).collect(); + return index; + + struct Indexer<'s, 'hir> { + owners: &'s NodeMap>, + index: IndexVec, next_node_id: NodeId, } impl Indexer<'_, '_> { fn insert(&mut self, id: NodeId, node: AstOwner) { let def_id = self.owners[&id].def_id; - self.index.ensure_contains_elem(def_id, || Steal::new(AstOwner::NonOwner)); - self.index[def_id] = Steal::new(node); + self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner); + self.index[def_id] = node; } fn make_dummy( @@ -617,43 +621,46 @@ fn lower_to_hir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::MaybeOwner<'_> { tcx.ensure_done().early_lint_checks(()); tcx.ensure_done().debugger_visualizers(LOCAL_CRATE); tcx.ensure_done().get_lang_items(()); - let (resolver, _) = tcx.resolver_for_lowering(); - let (ast_index, next_node_id) = tcx.index_ast(()); - let node = ast_index.get(def_id).map(Steal::steal); - - let mut item_lowerer = item::ItemLowerer { tcx, resolver, next_node_id: *next_node_id }; - - // The item existed in the AST. - let parent_id = match node.as_ref() { - Some(AstOwner::Crate(c)) => return item_lowerer.lower_crate(&c), - Some(AstOwner::Item(item)) => return item_lowerer.lower_item(&item), - Some(AstOwner::TraitItem(item)) => { - return item_lowerer.lower_trait_item(&item); - } - Some(AstOwner::ImplItem(item)) => { - return item_lowerer.lower_impl_item(&item); + let ast_index = tcx.index_ast(()); + let resolver_and_node = ast_index.get(def_id).map(Steal::steal); + + let fallback_to_parent = |parent_id| { + // The item did not exist in the AST, it was created by its parent. + let mut parent_info = tcx.lower_to_hir(parent_id); + if let hir::MaybeOwner::NonOwner(hir_id) = parent_info { + parent_info = tcx.lower_to_hir(hir_id.owner); } - Some(AstOwner::ForeignItem(item)) => return item_lowerer.lower_foreign_item(&item), - Some(AstOwner::Synthetic(parent_id)) => *parent_id, - Some(AstOwner::NonOwner) | None => tcx.local_parent(def_id), + + 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() + ) + }) }; - tcx.sess.time("drop_ast", || std::mem::drop(node)); + let Some((resolver, node)) = resolver_and_node else { + return fallback_to_parent(tcx.local_parent(def_id)); + }; - // The item did not exist in the AST, it was created by its parent. - let mut parent_info = tcx.lower_to_hir(parent_id); - if let hir::MaybeOwner::NonOwner(hir_id) = parent_info { - parent_info = tcx.lower_to_hir(hir_id.owner); - } + let mut item_lowerer = item::ItemLowerer { tcx, resolver: &*resolver }; + + 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::Synthetic(parent_id) => fallback_to_parent(*parent_id), + AstOwner::NonOwner => fallback_to_parent(tcx.local_parent(def_id)), + }; - 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() - ) - }) + tcx.sess.time("drop_ast", || std::mem::drop(node)); + + item } #[derive(Copy, Clone, PartialEq, Debug)] @@ -683,7 +690,7 @@ enum GenericArgsMode { Silence, } -impl<'hir> LoweringContext<'hir> { +impl<'hir> LoweringContext<'_, 'hir> { fn create_def( &mut self, node_id: NodeId, @@ -3138,7 +3145,7 @@ impl<'hir> GenericArgsCtor<'hir> { && self.parenthesized == hir::GenericArgsParentheses::No } - fn into_generic_args(self, this: &LoweringContext<'hir>) -> &'hir hir::GenericArgs<'hir> { + fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> { let ga = hir::GenericArgs { args: this.arena.alloc_from_iter(self.args), constraints: self.constraints, diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 5f0005242a504..8780b70fadfa4 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -14,7 +14,7 @@ use crate::{ AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode, }; -impl<'hir> LoweringContext<'hir> { +impl<'hir> LoweringContext<'_, 'hir> { pub(crate) fn lower_pat(&mut self, pattern: &Pat) -> &'hir hir::Pat<'hir> { self.arena.alloc(self.lower_pat_mut(pattern)) } diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 13ceae4647df0..42c4af5add12d 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -20,7 +20,7 @@ use crate::{ LifetimeRes, LoweringContext, ParamMode, }; -impl<'hir> LoweringContext<'hir> { +impl<'hir> LoweringContext<'_, 'hir> { #[instrument(level = "trace", skip(self))] pub(crate) fn lower_qpath( &mut self, diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 9adc353825fc2..b230fe3be68e3 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -400,6 +400,7 @@ fn print_macro_stats(ecx: &ExtCtxt<'_>) { fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { let sess = tcx.sess; let (resolver, krate) = tcx.resolver_for_lowering(); + let resolver = &*resolver.borrow(); let krate = &*krate.borrow(); let mut lint_buffer = resolver.lint_buffer.steal(); @@ -787,7 +788,11 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P fn resolver_for_lowering_raw<'tcx>( tcx: TyCtxt<'tcx>, (): (), -) -> (&'tcx ty::ResolverAstLowering<'tcx>, &'tcx Steal, &'tcx ty::ResolverGlobalCtxt) { +) -> ( + &'tcx Steal>, + &'tcx Steal, + &'tcx ty::ResolverGlobalCtxt, +) { let arenas = Resolver::arenas(); let _ = tcx.registered_tools(()); // Uses `crate_for_resolver`. let (krate, pre_configured_attrs) = tcx.crate_for_resolver(()).steal(); @@ -809,7 +814,7 @@ fn resolver_for_lowering_raw<'tcx>( } = resolver.into_outputs(); ( - tcx.arena.alloc(untracked_resolver_for_lowering), + tcx.arena.alloc(Steal::new(untracked_resolver_for_lowering)), tcx.arena.alloc(Steal::new(krate)), tcx.arena.alloc(untracked_resolutions), ) diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 135a38021114e..87e19fafc0e22 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -30,13 +30,14 @@ macro_rules! arena_types { rustc_hir::def_id::LocalDefId, rustc_middle::ty::DefinitionSiteHiddenType<'tcx>, >, - [] resolver: rustc_middle::ty::ResolverAstLowering<'tcx>, - [] index_ast: ( - rustc_index::IndexVec - >, - rustc_ast::NodeId, - ), + [] resolver: rustc_data_structures::steal::Steal>, + [] index_ast: rustc_index::IndexVec< + rustc_span::def_id::LocalDefId, + rustc_data_structures::steal::Steal<( + std::sync::Arc>, + rustc_ast::AstOwner + )> + >, [] crate_alone: rustc_data_structures::steal::Steal, [] crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>, [] resolutions: rustc_middle::ty::ResolverGlobalCtxt, diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 3cab32406e17c..0ccc577263ba1 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -180,7 +180,7 @@ rustc_queries! { } query resolver_for_lowering_raw(_: ()) -> ( - &'tcx ty::ResolverAstLowering<'tcx>, + &'tcx Steal>, &'tcx Steal, &'tcx ty::ResolverGlobalCtxt, ) { @@ -189,7 +189,10 @@ rustc_queries! { desc { "getting the resolver for lowering" } } - query index_ast(_: ()) -> &'tcx (IndexVec>, ast::NodeId) { + query index_ast(_: ()) -> &'tcx IndexVec>, + ast::AstOwner, + )>> { arena_cache eval_always no_hash diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 36fdac0de6ab3..c6fa3801fb1bc 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2724,7 +2724,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn resolver_for_lowering( self, - ) -> (&'tcx ty::ResolverAstLowering<'tcx>, &'tcx Steal) { + ) -> (&'tcx Steal>, &'tcx Steal) { let (resolver, krate, _) = self.resolver_for_lowering_raw(()); (resolver, krate) } diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index 48ddaafd88eb9..53fb6888ddcd8 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -247,6 +247,7 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> { /// Traverses and collects all the lang items in all crates. fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems { let (resolver, krate) = tcx.resolver_for_lowering(); + let resolver = &*resolver.borrow(); let krate = &*krate.borrow(); // Initialize the collector. From 8e922788499cb1b3cd2c3bb522d0960be133f8dc Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 6 Jun 2026 07:47:58 +0000 Subject: [PATCH 6/8] Document AstOwner. --- compiler/rustc_ast/src/ast.rs | 9 ++++++++- compiler/rustc_ast_lowering/src/lib.rs | 24 ++++++++++++++++++------ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 8e601dd7f2fbb..11a531353eba0 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -30,6 +30,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::tagged_ptr::Tag; use rustc_macros::{Decodable, Encodable, StableHash, Walkable}; pub use rustc_span::AttrId; +use rustc_span::def_id::LocalDefId; use rustc_span::{ ByteSymbol, DUMMY_SP, ErrorGuaranteed, Ident, LocalExpnId, Span, Spanned, Symbol, kw, respan, sym, @@ -4362,10 +4363,16 @@ impl TryFrom for ForeignItemKind { pub type ForeignItem = Item; +/// Fragment of the AST according to "HIR owner" semantics. +/// +/// This is used to map each `LocalDefId` to its content's AST. #[derive(Debug)] pub enum AstOwner { + /// This definition does not correspond to a HIR owner. NonOwner, - Synthetic(rustc_span::def_id::LocalDefId), + /// This definition corresponds to a nested `use` tree. + /// The `LocalDefId` points to its HIR owner. + NestedUseTree(LocalDefId), Crate(Box), Item(Box), TraitItem(Box), diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 3f7d6b72a179e..cb325021b8911 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -546,7 +546,7 @@ fn index_ast<'tcx>( UseTreeKind::Glob(_) | UseTreeKind::Simple(_) => {} UseTreeKind::Nested { items: ref nested_vec, span } => { for &(ref nested, id) in nested_vec { - self.insert(id, AstOwner::Synthetic(parent)); + self.insert(id, AstOwner::NestedUseTree(parent)); items.push(self.make_dummy(id, span, ItemKind::MacCall)); let def_id = self.owners[&id].def_id; @@ -624,10 +624,17 @@ fn lower_to_hir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::MaybeOwner<'_> { let ast_index = tcx.index_ast(()); let resolver_and_node = ast_index.get(def_id).map(Steal::steal); - let fallback_to_parent = |parent_id| { - // The item did not exist in the AST, it was created by its parent. + let fallback_to_ancestor = |parent_id| { + // 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 { + // `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); } @@ -642,7 +649,10 @@ fn lower_to_hir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::MaybeOwner<'_> { }; let Some((resolver, node)) = resolver_and_node else { - return fallback_to_parent(tcx.local_parent(def_id)); + // `ast_index` does not contain all definitions, only up-to the highest + // `LocalDefId` which has a non-trivial `AstOwner`. Gracefully handle + // other definitions, in particular those nested inside this highest definition. + return fallback_to_ancestor(tcx.local_parent(def_id)); }; let mut item_lowerer = item::ItemLowerer { tcx, resolver: &*resolver }; @@ -654,8 +664,10 @@ fn lower_to_hir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::MaybeOwner<'_> { 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::Synthetic(parent_id) => fallback_to_parent(*parent_id), - AstOwner::NonOwner => fallback_to_parent(tcx.local_parent(def_id)), + 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 => fallback_to_ancestor(tcx.local_parent(def_id)), }; tcx.sess.time("drop_ast", || std::mem::drop(node)); From 24c18c41eabc9b50206ea2d313d4de0563dec21d Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 6 Jun 2026 07:56:05 +0000 Subject: [PATCH 7/8] Document HIR queries. --- compiler/rustc_middle/src/queries.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 0ccc577263ba1..c01ff3d5d0561 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -180,6 +180,8 @@ rustc_queries! { } query resolver_for_lowering_raw(_: ()) -> ( + // Those two fields are consumed by `index_ast`. + // We want them to be eventually dropped after lowering. &'tcx Steal>, &'tcx Steal, &'tcx ty::ResolverGlobalCtxt, @@ -190,6 +192,9 @@ rustc_queries! { } query index_ast(_: ()) -> &'tcx IndexVec>, ast::AstOwner, )>> { @@ -210,9 +215,9 @@ rustc_queries! { desc { "getting the source span" } } - query lower_to_hir(key: LocalDefId) -> hir::MaybeOwner<'tcx> { + query lower_to_hir(def_id: LocalDefId) -> hir::MaybeOwner<'tcx> { eval_always - desc { "lowering HIR for `{}`", tcx.def_path_str(key.to_def_id()) } + desc { "lowering HIR for `{}`", tcx.def_path_str(def_id) } } query hir_owner(def_id: LocalDefId) -> rustc_middle::hir::ProjectedMaybeOwner<'tcx> { From 2a30bc09169bd5cdff04c55888dc6fc4d063dc36 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Wed, 10 Jun 2026 12:00:07 +0000 Subject: [PATCH 8/8] std::mem is already imported. --- compiler/rustc_ast_lowering/src/lib.rs | 45 +++++++++++++------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index cb325021b8911..b8d708d42ff10 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -531,7 +531,7 @@ fn index_ast<'tcx>( node: impl FnOnce(Box>) -> AstOwner, ) { let dummy = self.make_dummy(item.id, item.span, dummy); - let item = std::mem::replace(item, *dummy); + let item = mem::replace(item, *dummy); self.insert(item.id, node(Box::new(item))); } @@ -670,7 +670,7 @@ fn lower_to_hir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::MaybeOwner<'_> { AstOwner::NonOwner => fallback_to_ancestor(tcx.local_parent(def_id)), }; - tcx.sess.time("drop_ast", || std::mem::drop(node)); + tcx.sess.time("drop_ast", || mem::drop(node)); item } @@ -797,24 +797,23 @@ impl<'hir> LoweringContext<'_, 'hir> { .map(|s| s.steal()) .unwrap_or_else(|| PerParentDisambiguatorState::new(def_id)); - let disambiguator = std::mem::replace(&mut self.current_disambiguator, new_disambig); - let current_ast_owner = std::mem::replace(&mut self.owner, &self.resolver.owners[&owner]); - let current_attrs = std::mem::take(&mut self.attrs); - let current_bodies = std::mem::take(&mut self.bodies); - let current_define_opaque = std::mem::take(&mut self.define_opaque); - let current_ident_and_label_to_local_id = - std::mem::take(&mut self.ident_and_label_to_local_id); + let disambiguator = mem::replace(&mut self.current_disambiguator, new_disambig); + let current_ast_owner = mem::replace(&mut self.owner, &self.resolver.owners[&owner]); + let current_attrs = mem::take(&mut self.attrs); + let current_bodies = mem::take(&mut self.bodies); + let current_define_opaque = mem::take(&mut self.define_opaque); + let current_ident_and_label_to_local_id = mem::take(&mut self.ident_and_label_to_local_id); #[cfg(debug_assertions)] - let current_node_id_to_local_id = std::mem::take(&mut self.node_id_to_local_id); - let current_trait_map = std::mem::take(&mut self.trait_map); - let current_owner = std::mem::replace(&mut self.current_hir_id_owner, owner_id); + let current_node_id_to_local_id = mem::take(&mut self.node_id_to_local_id); + let current_trait_map = mem::take(&mut self.trait_map); + let current_owner = mem::replace(&mut self.current_hir_id_owner, owner_id); let current_local_counter = - std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1)); - let current_impl_trait_defs = std::mem::take(&mut self.impl_trait_defs); - let current_impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds); - let current_delayed_lints = std::mem::take(&mut self.delayed_lints); - let current_children = std::mem::take(&mut self.children); + mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1)); + let current_impl_trait_defs = mem::take(&mut self.impl_trait_defs); + let current_impl_trait_bounds = mem::take(&mut self.impl_trait_bounds); + let current_delayed_lints = mem::take(&mut self.delayed_lints); + let current_children = mem::take(&mut self.children); // Do not reset `next_node_id` and `node_id_to_def_id`: // we want `f` to be able to refer to the `LocalDefId`s that the caller created. @@ -859,12 +858,12 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> { - let attrs = std::mem::take(&mut self.attrs); - let mut bodies = std::mem::take(&mut self.bodies); - let define_opaque = std::mem::take(&mut self.define_opaque); - let trait_map = std::mem::take(&mut self.trait_map); - let delayed_lints = Steal::new(std::mem::take(&mut self.delayed_lints).into_boxed_slice()); - let children = std::mem::take(&mut self.children); + let attrs = mem::take(&mut self.attrs); + let mut bodies = mem::take(&mut self.bodies); + let define_opaque = mem::take(&mut self.define_opaque); + let trait_map = mem::take(&mut self.trait_map); + let delayed_lints = Steal::new(mem::take(&mut self.delayed_lints).into_boxed_slice()); + let children = mem::take(&mut self.children); #[cfg(debug_assertions)] for (id, attrs) in attrs.iter() {