From 1e213e8322f08a4799ad2842a8d2f1df8af4fba3 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Fri, 17 Apr 2026 20:05:28 +0000 Subject: [PATCH 1/8] Do not modify resolver outputs during lowering Co-authored-by: Camille Gillot --- compiler/rustc_ast_lowering/src/asm.rs | 7 +- compiler/rustc_ast_lowering/src/block.rs | 4 +- compiler/rustc_ast_lowering/src/contract.rs | 4 +- compiler/rustc_ast_lowering/src/delegation.rs | 18 +- .../src/delegation/generics.rs | 12 +- compiler/rustc_ast_lowering/src/expr.rs | 11 +- compiler/rustc_ast_lowering/src/format.rs | 7 +- compiler/rustc_ast_lowering/src/item.rs | 25 ++- compiler/rustc_ast_lowering/src/lib.rs | 199 +++++------------- compiler/rustc_ast_lowering/src/pat.rs | 9 +- compiler/rustc_ast_lowering/src/path.rs | 5 +- 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 +- 21 files changed, 132 insertions(+), 219 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 3a27962feca39..520377e7c7af7 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -18,11 +18,9 @@ use super::errors::{ InvalidRegisterClass, RegisterClassOnlyClobber, RegisterClassOnlyClobberStable, RegisterConflict, }; -use crate::{ - AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, ParamMode, ResolverAstLoweringExt, -}; +use crate::{AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, ParamMode}; -impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { +impl<'hir> LoweringContext<'hir> { pub(crate) fn lower_inline_asm( &mut self, sp: Span, @@ -203,7 +201,6 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { }, InlineAsmOperand::Sym { sym } => { let static_def_id = self - .resolver .get_partial_res(sym.id) .and_then(|res| res.full_res()) .and_then(|res| match res { diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs index 94839485c6036..870b8897844aa 100644 --- a/compiler/rustc_ast_lowering/src/block.rs +++ b/compiler/rustc_ast_lowering/src/block.rs @@ -4,9 +4,9 @@ use rustc_hir::Target; use rustc_span::sym; use smallvec::SmallVec; -use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext, ResolverAstLoweringExt}; +use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext}; -impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { +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 fd05ed0c78e43..6cd36142176cd 100644 --- a/compiler/rustc_ast_lowering/src/contract.rs +++ b/compiler/rustc_ast_lowering/src/contract.rs @@ -2,9 +2,9 @@ use std::sync::Arc; use thin_vec::thin_vec; -use crate::{LoweringContext, ResolverAstLoweringExt}; +use crate::LoweringContext; -impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { +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 01382a69f2ec0..37ecd10b11e63 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -105,7 +105,7 @@ static ATTRS_ADDITIONS: &[AttrAdditionInfo] = &[ }, ]; -impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { +impl<'hir> LoweringContext<'hir> { fn is_method(&self, def_id: DefId, span: Span) -> bool { match self.tcx.def_kind(def_id) { DefKind::Fn => false, @@ -265,7 +265,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { } fn get_resolution_id(&self, node_id: NodeId) -> Option { - self.resolver.get_partial_res(node_id).and_then(|r| r.expect_full_res().opt_def_id()) + self.get_partial_res(node_id).and_then(|r| r.expect_full_res().opt_def_id()) } // Function parameter count, including C variadic `...` if present. @@ -414,7 +414,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { && idx == 0 { let mut self_resolver = SelfResolver { - resolver: this.resolver, + ctxt: this, path_id: delegation.id, self_param_id: pat_node_id, }; @@ -661,25 +661,25 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { } } -struct SelfResolver<'a, R> { - resolver: &'a mut R, +struct SelfResolver<'a, 'hir> { + ctxt: &'a mut LoweringContext<'hir>, path_id: NodeId, self_param_id: NodeId, } -impl<'tcx, R: ResolverAstLoweringExt<'tcx>> SelfResolver<'_, R> { +impl SelfResolver<'_, '_> { fn try_replace_id(&mut self, id: NodeId) { - if let Some(res) = self.resolver.get_partial_res(id) + if let Some(res) = self.ctxt.get_partial_res(id) && let Some(Res::Local(sig_id)) = res.full_res() && sig_id == self.path_id { let new_res = PartialRes::new(Res::Local(self.self_param_id)); - self.resolver.insert_partial_res(id, new_res); + self.ctxt.partial_res_overrides.insert(id, new_res); } } } -impl<'ast, 'tcx, R: ResolverAstLoweringExt<'tcx>> Visitor<'ast> for SelfResolver<'_, R> { +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 01b17438bc7f1..b8855dcc15e2a 100644 --- a/compiler/rustc_ast_lowering/src/delegation/generics.rs +++ b/compiler/rustc_ast_lowering/src/delegation/generics.rs @@ -8,7 +8,7 @@ use rustc_middle::{bug, ty}; use rustc_span::symbol::kw; use rustc_span::{Ident, Span}; -use crate::{LoweringContext, ResolverAstLoweringExt}; +use crate::LoweringContext; #[derive(Clone, Copy)] pub(super) enum DelegationGenericsKind { @@ -97,7 +97,7 @@ impl DelegationGenericsKind { impl<'hir> HirOrTyGenerics<'hir> { pub(super) fn into_hir_generics( &mut self, - ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, + ctx: &mut LoweringContext<'hir>, span: Span, ) -> &mut HirOrTyGenerics<'hir> { if let HirOrTyGenerics::Ty(ty) = self { @@ -117,7 +117,7 @@ impl<'hir> HirOrTyGenerics<'hir> { pub(super) fn into_generic_args( &self, - ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, + ctx: &mut LoweringContext<'hir>, add_lifetimes: bool, span: Span, ) -> &'hir hir::GenericArgs<'hir> { @@ -151,7 +151,7 @@ impl<'hir> GenericsGenerationResults<'hir> { pub(super) fn all_params( &mut self, span: Span, - ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, + ctx: &mut LoweringContext<'hir>, ) -> impl Iterator> { // Now we always call `into_hir_generics` both on child and parent, // however in future we would not do that, when scenarios like @@ -185,7 +185,7 @@ impl<'hir> GenericsGenerationResults<'hir> { pub(super) fn all_predicates( &mut self, span: Span, - ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, + ctx: &mut LoweringContext<'hir>, ) -> impl Iterator> { // Now we always call `into_hir_generics` both on child and parent, // however in future we would not do that, when scenarios like @@ -203,7 +203,7 @@ impl<'hir> GenericsGenerationResults<'hir> { } } -impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { +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 aad838e9a1728..987c36b95ec26 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -51,7 +51,7 @@ impl<'v> rustc_ast::visit::Visitor<'v> for WillCreateDefIdsVisitor { } } -impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { +impl<'hir> LoweringContext<'hir> { fn lower_exprs(&mut self, exprs: &[Box]) -> &'hir [hir::Expr<'hir>] { self.arena.alloc_from_iter(exprs.iter().map(|x| self.lower_expr_mut(x))) } @@ -1235,10 +1235,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { whole_span: Span, ) -> hir::ExprKind<'hir> { // Return early in case of an ordinary assignment. - fn is_ordinary<'hir>( - lower_ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, - lhs: &Expr, - ) -> bool { + fn is_ordinary(lower_ctx: &mut LoweringContext<'_>, lhs: &Expr) -> bool { match &lhs.kind { ExprKind::Array(..) | ExprKind::Struct(..) @@ -1293,7 +1290,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { ) -> Option<(&'a Option>, &'a Path)> { if let ExprKind::Path(qself, path) = &expr.kind { // Does the path resolve to something disallowed in a tuple struct/variant pattern? - if let Some(partial_res) = self.resolver.get_partial_res(expr.id) { + if let Some(partial_res) = self.get_partial_res(expr.id) { if let Some(res) = partial_res.full_res() && !res.expected_in_tuple_struct_pat() { @@ -1315,7 +1312,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { ) -> Option<(&'a Option>, &'a Path)> { if let ExprKind::Path(qself, path) = &expr.kind { // Does the path resolve to something disallowed in a unit struct/variant pattern? - if let Some(partial_res) = self.resolver.get_partial_res(expr.id) { + if let Some(partial_res) = self.get_partial_res(expr.id) { if let Some(res) = partial_res.full_res() && !res.expected_in_unit_struct_pat() { diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index 1f1f86f7edfd7..2332af6b1bccf 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -7,9 +7,8 @@ use rustc_session::config::FmtDebug; use rustc_span::{ByteSymbol, DesugaringKind, Ident, Span, Symbol, sym}; use super::LoweringContext; -use crate::ResolverAstLoweringExt; -impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { +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. @@ -231,7 +230,7 @@ enum ArgumentType { /// ::new_…(arg) /// ``` fn make_argument<'hir>( - ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, + ctx: &mut LoweringContext<'hir>, sp: Span, arg: &'hir hir::Expr<'hir>, ty: ArgumentType, @@ -278,7 +277,7 @@ fn make_count( } fn expand_format_args<'hir>( - ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'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 239daecd3d1fb..25753610d469e 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -13,7 +13,7 @@ use rustc_hir::{ }; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::span_bug; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; use rustc_span::def_id::DefId; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym}; @@ -48,9 +48,9 @@ impl<'hir> Owners<'_, 'hir> { } } -pub(super) struct ItemLowerer<'a, 'hir, R> { +pub(super) struct ItemLowerer<'a, 'hir> { pub(super) tcx: TyCtxt<'hir>, - pub(super) resolver: &'a mut R, + pub(super) resolver: &'hir ResolverAstLowering<'hir>, pub(super) ast_index: &'a IndexSlice>, pub(super) owners: Owners<'a, 'hir>, } @@ -74,11 +74,11 @@ fn add_ty_alias_where_clause( if before.0 || !after.0 { before } else { after }; } -impl<'hir, R: ResolverAstLoweringExt<'hir>> ItemLowerer<'_, 'hir, R> { +impl<'hir> ItemLowerer<'_, 'hir> { fn with_lctx( &mut self, owner: NodeId, - f: impl FnOnce(&mut LoweringContext<'_, 'hir, R>) -> 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)); @@ -122,7 +122,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> ItemLowerer<'_, 'hir, R> { } } -impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { +impl<'hir> LoweringContext<'hir> { pub(super) fn lower_mod( &mut self, items: &[Box], @@ -635,7 +635,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { } fn lower_path_simple_eii(&mut self, id: NodeId, path: &Path) -> Option { - let res = self.resolver.get_partial_res(id)?; + let res = self.get_partial_res(id)?; let Some(did) = res.expect_full_res().opt_def_id() else { self.dcx().span_delayed_bug(path.span, "should have errored in resolve"); return None; @@ -1336,7 +1336,6 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { ImplItemImplKind::Trait { defaultness, trait_item_def_id: self - .resolver .get_partial_res(i.id) .and_then(|r| r.expect_full_res().opt_def_id()) .ok_or_else(|| { @@ -1532,7 +1531,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { pub(crate) fn lower_coroutine_body_with_moved_arguments( &mut self, decl: &FnDecl, - lower_body: impl FnOnce(&mut LoweringContext<'_, 'hir, R>) -> hir::Expr<'hir>, + lower_body: impl FnOnce(&mut LoweringContext<'hir>) -> hir::Expr<'hir>, fn_decl_span: Span, body_span: Span, coroutine_kind: CoroutineKind, @@ -1669,7 +1668,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { parameters.push(new_parameter); } - let mkbody = |this: &mut LoweringContext<'_, 'hir, R>| { + let mkbody = |this: &mut LoweringContext<'hir>| { // Create a block from the user's function body: let user_body = lower_body(this); @@ -1854,7 +1853,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { let kind = match &r.kind { RestrictionKind::Unrestricted => hir::RestrictionKind::Unrestricted, RestrictionKind::Restricted { path, id, shorthand: _ } => { - let res = self.resolver.get_partial_res(*id); + let res = self.get_partial_res(*id); if let Some(did) = res.and_then(|res| res.expect_full_res().opt_def_id()) { hir::RestrictionKind::Restricted(self.arena.alloc(hir::Path { res: did, @@ -1920,7 +1919,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { // Introduce extra lifetimes if late resolution tells us to. let extra_lifetimes = self.resolver.extra_lifetime_params(parent_node_id); - params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| { + params.extend(extra_lifetimes.into_iter().filter_map(|&(ident, node_id, res)| { self.lifetime_res_to_generic_param( ident, node_id, @@ -1962,7 +1961,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { return; }; let define_opaque = define_opaque.iter().filter_map(|(id, path)| { - let res = self.resolver.get_partial_res(*id); + let res = self.get_partial_res(*id); let Some(did) = res.and_then(|res| res.expect_full_res().opt_def_id()) else { self.dcx().span_delayed_bug(path.span, "should have errored in resolve"); return None; diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 2ffb9c123b5f8..9b7a1311f4800 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -91,9 +91,9 @@ mod pat; mod path; pub mod stability; -struct LoweringContext<'a, 'hir, R> { +struct LoweringContext<'hir> { tcx: TyCtxt<'hir>, - resolver: &'a mut R, + resolver: &'hir ResolverAstLowering<'hir>, disambiguator: PerParentDisambiguatorState, /// Used to allocate HIR nodes. @@ -138,6 +138,14 @@ struct LoweringContext<'a, 'hir, R> { /// NodeIds that are lowered inside the current HIR owner. Only used for duplicate lowering check. #[cfg(debug_assertions)] node_id_to_local_id: NodeMap, + /// The `NodeId` space is split in two. + /// `0..resolver.next_node_id` are created by the resolver on the AST. + /// The higher part `resolver.next_node_id..next_node_id` are created during lowering. + next_node_id: NodeId, + /// Maps the `NodeId`s created during lowering to `LocalDefId`s. + node_id_to_def_id: NodeMap, + /// Overlay over resolver's `partial_res_map` used by delegation. + partial_res_overrides: NodeMap, allow_contracts: Arc<[Symbol]>, allow_try_trait: Arc<[Symbol]>, @@ -153,8 +161,8 @@ struct LoweringContext<'a, 'hir, R> { attribute_parser: AttributeParser<'hir>, } -impl<'a, 'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'a, 'hir, R> { - fn new(tcx: TyCtxt<'hir>, resolver: &'a mut R) -> Self { +impl<'hir> LoweringContext<'hir> { + fn new(tcx: TyCtxt<'hir>, resolver: &'hir ResolverAstLowering<'hir>) -> Self { let registered_tools = tcx.registered_tools(()).iter().map(|x| x.name).collect(); Self { tcx, @@ -174,6 +182,9 @@ impl<'a, 'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'a, 'hir, R> { #[cfg(debug_assertions)] node_id_to_local_id: Default::default(), trait_map: Default::default(), + next_node_id: resolver.next_node_id, + node_id_to_def_id: NodeMap::default(), + partial_res_overrides: NodeMap::default(), // Lowering state. try_block_scope: TryBlockScope::Function, @@ -237,85 +248,6 @@ impl SpanLowerer { } } -struct ResolverDelayedAstLowering<'a, 'tcx> { - node_id_to_def_id: NodeMap, - partial_res_map: NodeMap, - next_node_id: NodeId, - base: &'a ResolverAstLowering<'tcx>, -} - -// FIXME(fn_delegation): delegate this trait impl to `self.base` -impl<'a, 'tcx> ResolverAstLoweringExt<'tcx> for ResolverDelayedAstLowering<'a, 'tcx> { - fn legacy_const_generic_args(&self, expr: &Expr, tcx: TyCtxt<'tcx>) -> Option> { - self.base.legacy_const_generic_args(expr, tcx) - } - - fn get_partial_res(&self, id: NodeId) -> Option { - self.partial_res_map.get(&id).copied().or_else(|| self.base.get_partial_res(id)) - } - - fn get_import_res(&self, id: NodeId) -> PerNS>> { - self.base.get_import_res(id) - } - - fn get_label_res(&self, id: NodeId) -> Option { - self.base.get_label_res(id) - } - - fn get_lifetime_res(&self, id: NodeId) -> Option { - self.base.get_lifetime_res(id) - } - - fn extra_lifetime_params(&self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> { - self.base.extra_lifetime_params(id) - } - - fn delegation_info(&self, id: LocalDefId) -> Option<&DelegationInfo> { - self.base.delegation_info(id) - } - - fn opt_local_def_id(&self, id: NodeId) -> Option { - self.node_id_to_def_id.get(&id).copied().or_else(|| self.base.opt_local_def_id(id)) - } - - fn local_def_id(&self, id: NodeId) -> LocalDefId { - self.opt_local_def_id(id).expect("must have def_id") - } - - fn lifetime_elision_allowed(&self, id: NodeId) -> bool { - self.base.lifetime_elision_allowed(id) - } - - fn insert_new_def_id(&mut self, node_id: NodeId, def_id: LocalDefId) { - self.node_id_to_def_id.insert(node_id, def_id); - } - - fn insert_partial_res(&mut self, node_id: NodeId, res: PartialRes) { - self.partial_res_map.insert(node_id, res); - } - - fn trait_candidates(&self, node_id: NodeId) -> Option<&'tcx [hir::TraitCandidate<'tcx>]> { - self.base.trait_candidates(node_id) - } - - #[inline] - fn next_node_id(&mut self) -> NodeId { - next_node_id(&mut self.next_node_id) - } - - fn steal_or_create_disambiguator(&self, parent: LocalDefId) -> PerParentDisambiguatorState { - self.base.steal_or_create_disambiguator(parent) - } -} - -fn next_node_id(current_id: &mut NodeId) -> NodeId { - let start = *current_id; - let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds"); - *current_id = ast::NodeId::from_u32(next); - - start -} - #[extension(trait ResolverAstLoweringExt<'tcx>)] impl<'tcx> ResolverAstLowering<'tcx> { fn legacy_const_generic_args(&self, expr: &Expr, tcx: TyCtxt<'tcx>) -> Option> { @@ -329,7 +261,7 @@ impl<'tcx> ResolverAstLowering<'tcx> { return None; } - let def_id = self.get_partial_res(expr.id)?.full_res()?.opt_def_id()?; + let def_id = self.partial_res_map.get(&expr.id)?.full_res()?.opt_def_id()?; // We only support cross-crate argument rewriting. Uses // within the same crate should be updated to use the new @@ -346,10 +278,6 @@ impl<'tcx> ResolverAstLowering<'tcx> { .map(|fn_indexes| fn_indexes.iter().map(|(num, _)| *num).collect()) } - fn get_partial_res(&self, id: NodeId) -> Option { - self.partial_res_map.get(&id).copied() - } - /// Obtains per-namespace resolutions for `use` statement with the given `NodeId`. fn get_import_res(&self, id: NodeId) -> PerNS>> { self.import_res_map.get(&id).copied().unwrap_or_default() @@ -372,8 +300,8 @@ impl<'tcx> ResolverAstLowering<'tcx> { /// /// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring /// should appear at the enclosing `PolyTraitRef`. - fn extra_lifetime_params(&self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> { - self.extra_lifetime_params_map.get(&id).cloned().unwrap_or_default() + fn extra_lifetime_params(&self, id: NodeId) -> &[(Ident, NodeId, LifetimeRes)] { + self.extra_lifetime_params_map.get(&id).map_or(&[], |v| &v[..]) } fn delegation_info(&self, id: LocalDefId) -> Option<&DelegationInfo> { @@ -392,23 +320,6 @@ impl<'tcx> ResolverAstLowering<'tcx> { self.lifetime_elision_allowed.contains(&id) } - fn insert_new_def_id(&mut self, node_id: NodeId, def_id: LocalDefId) { - self.node_id_to_def_id.insert(node_id, def_id); - } - - fn insert_partial_res(&mut self, node_id: NodeId, res: PartialRes) { - self.partial_res_map.insert(node_id, res); - } - - fn trait_candidates(&self, node_id: NodeId) -> Option<&'tcx [hir::TraitCandidate<'tcx>]> { - self.trait_map.get(&node_id).copied() - } - - #[inline] - fn next_node_id(&mut self) -> NodeId { - next_node_id(&mut self.next_node_id) - } - fn steal_or_create_disambiguator(&self, parent: LocalDefId) -> PerParentDisambiguatorState { self.per_parent_disambiguators.get(&parent).map(|s| s.steal()).unwrap_or_default() } @@ -552,7 +463,7 @@ enum TryBlockScope { } fn index_crate<'a, 'b>( - resolver: &'b impl ResolverAstLoweringExt<'a>, + resolver: &'b ResolverAstLowering<'b>, krate: &'a Crate, ) -> IndexVec> { let mut indexer = Indexer { resolver, index: IndexVec::new() }; @@ -562,12 +473,12 @@ fn index_crate<'a, 'b>( return indexer.index; - struct Indexer<'a, 'b, R> { - resolver: &'b R, + struct Indexer<'a, 'b> { + resolver: &'b ResolverAstLowering<'b>, index: IndexVec>, } - impl<'a, 'b, R: ResolverAstLoweringExt<'a>> visit::Visitor<'a> for Indexer<'a, 'b, R> { + impl<'a, 'b> visit::Visitor<'a> for Indexer<'a, 'b> { fn visit_attribute(&mut self, _: &'a Attribute) { // We do not want to lower expressions that appear in attributes, // as they are not accessible to the rest of the HIR. @@ -624,7 +535,8 @@ pub 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 (mut 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( @@ -634,7 +546,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { let mut lowerer = item::ItemLowerer { tcx, - resolver: &mut resolver, + resolver, ast_index: &ast_index, owners: Owners::IndexVec(&mut owners), }; @@ -655,32 +567,26 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { let opt_hir_hash = if tcx.needs_crate_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. pub 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. let ast_index = index_crate(resolver, krate); - let mut resolver = ResolverDelayedAstLowering { - next_node_id: resolver.next_node_id, - partial_res_map: Default::default(), - node_id_to_def_id: Default::default(), - base: resolver, - }; - let mut map = Default::default(); let mut lowerer = item::ItemLowerer { tcx, - resolver: &mut resolver, + resolver: &resolver, ast_index: &ast_index, owners: Owners::Map(&mut map), }; @@ -719,7 +625,7 @@ enum GenericArgsMode { Silence, } -impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { +impl<'hir> LoweringContext<'hir> { fn create_def( &mut self, node_id: ast::NodeId, @@ -744,25 +650,38 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { .def_id(); debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id); - self.resolver.insert_new_def_id(node_id, def_id); + self.node_id_to_def_id.insert(node_id, def_id); def_id } fn next_node_id(&mut self) -> NodeId { - self.resolver.next_node_id() + let start = self.next_node_id; + let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds"); + self.next_node_id = ast::NodeId::from_u32(next); + start } /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name /// resolver (if any). fn opt_local_def_id(&self, node: NodeId) -> Option { - self.resolver.opt_local_def_id(node) + self.node_id_to_def_id + .get(&node) + .or_else(|| self.resolver.node_id_to_def_id.get(&node)) + .copied() } fn local_def_id(&self, node: NodeId) -> LocalDefId { self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`")) } + fn get_partial_res(&self, id: NodeId) -> Option { + self.partial_res_overrides + .get(&id) + .or_else(|| self.resolver.partial_res_map.get(&id)) + .copied() + } + /// Given the id of an owner node in the AST, returns the corresponding `OwnerId`. fn owner_id(&self, node: NodeId) -> hir::OwnerId { hir::OwnerId { def_id: self.local_def_id(node) } @@ -886,8 +805,8 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id))); } - if let Some(traits) = self.resolver.trait_candidates(ast_node_id) { - self.trait_map.insert(hir_id.local_id, traits); + if let Some(traits) = self.resolver.trait_map.get(&ast_node_id) { + self.trait_map.insert(hir_id.local_id, &traits[..]); } // Check whether the same `NodeId` is lowered more than once. @@ -928,7 +847,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { } fn expect_full_res(&mut self, id: NodeId) -> Res { - self.resolver.get_partial_res(id).map_or(Res::Err, |pr| pr.expect_full_res()) + self.get_partial_res(id).map_or(Res::Err, |pr| pr.expect_full_res()) } fn lower_import_res(&mut self, id: NodeId, span: Span) -> PerNS> { @@ -1066,8 +985,8 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { let extra_lifetimes = self.resolver.extra_lifetime_params(binder); debug!(?extra_lifetimes); let extra_lifetimes: Vec<_> = extra_lifetimes - .into_iter() - .filter_map(|(ident, node_id, res)| { + .iter() + .filter_map(|&(ident, node_id, res)| { self.lifetime_res_to_generic_param( ident, node_id, @@ -1393,7 +1312,6 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { // FIXME: Should we be handling `(PATH_TO_CONST)`? TyKind::Path(None, path) => { if let Some(res) = self - .resolver .get_partial_res(ty.id) .and_then(|partial_res| partial_res.full_res()) { @@ -1444,7 +1362,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { // The other cases when a qpath should be opportunistically made a trait object are handled // by `ty_path`. if qself.is_none() - && let Some(partial_res) = self.resolver.get_partial_res(t.id) + && let Some(partial_res) = self.get_partial_res(t.id) && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res() { let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| { @@ -1798,7 +1716,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { let [segment] = path.segments.as_slice() else { panic!(); }; - let res = self.resolver.get_partial_res(*id).map_or(Res::Err, |partial_res| { + let res = self.get_partial_res(*id).map_or(Res::Err, |partial_res| { partial_res.full_res().expect("no partial res expected for precise capture arg") }); hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg { @@ -2327,7 +2245,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { match rbp { RelaxedBoundPolicy::Allowed => return, RelaxedBoundPolicy::AllowedIfOnTyParam(id, params) => { - if let Some(res) = self.resolver.get_partial_res(id).and_then(|r| r.full_res()) + if let Some(res) = self.get_partial_res(id).and_then(|r| r.full_res()) && let Res::Def(DefKind::TyParam, def_id) = res && params.iter().any(|p| def_id == self.local_def_id(p.id).to_def_id()) { @@ -2797,7 +2715,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { }; let maybe_res = - self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res()); + self.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res()); if let ExprKind::Path(qself, path) = &expr.kind && path.is_potential_trivial_const_arg() && matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _))) @@ -3109,10 +3027,7 @@ impl<'hir> GenericArgsCtor<'hir> { && self.parenthesized == hir::GenericArgsParentheses::No } - fn into_generic_args( - self, - this: &LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'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 88f038f11d3c0..408ce5f381ca7 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -10,10 +10,11 @@ use rustc_span::{DesugaringKind, Ident, Span, Spanned, respan}; use super::errors::{ ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding, }; -use super::{ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt}; -use crate::{AllowReturnTypeNotation, ImplTraitPosition}; +use super::{ + AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode, +}; -impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { +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)) } @@ -287,7 +288,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { hir_id: hir::HirId, lower_sub: impl FnOnce(&mut Self) -> Option<&'hir hir::Pat<'hir>>, ) -> hir::PatKind<'hir> { - match self.resolver.get_partial_res(p.id).map(|d| d.expect_full_res()) { + match self.get_partial_res(p.id).map(|d| d.expect_full_res()) { // `None` can occur in body-less function signatures res @ (None | Some(Res::Local(_))) => { let binding_id = match res { diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 139140af3e033..fb888067456b2 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -20,7 +20,7 @@ use super::{ LifetimeRes, LoweringContext, ParamMode, ResolverAstLoweringExt, }; -impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { +impl<'hir> LoweringContext<'hir> { #[instrument(level = "trace", skip(self))] pub(crate) fn lower_qpath( &mut self, @@ -41,8 +41,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { self.lower_ty_alloc(&q.ty, ImplTraitContext::Disallowed(ImplTraitPosition::Path)) }); - let partial_res = - self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err)); + let partial_res = self.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err)); let base_res = partial_res.base_res(); let unresolved_segments = partial_res.unresolved_segments(); diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 79b6fc59978f3..230c56e89a7e3 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -212,7 +212,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()), } } @@ -262,7 +262,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 9c020c35e1429..e17f54df69fb0 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -401,7 +401,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 { @@ -784,7 +785,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(); @@ -806,7 +807,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<'_>) { @@ -863,7 +864,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 de6a105ee2b7b..666b120aa1fb4 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -31,10 +31,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 68357212bebe8..62e2fcc686a32 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -1251,7 +1251,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 7f82b9161fe61..1e878af292b87 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -23,7 +23,7 @@ use rustc_macros::{Decodable, Encodable, HashStable}; use rustc_span::{ErrorGuaranteed, ExpnId, HashStableContext, 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. @@ -37,9 +37,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, } @@ -48,10 +48,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 7c6ab642b2736..d323535492124 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -181,7 +181,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 71b0077b62131..627e25756759f 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2822,7 +2822,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 1f27384d4e7ca..a789aab770ba4 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 b6fb9937dfa45..605e7b5496013 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 21ce508d8560c..6743bb001a84c 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -338,7 +338,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 2ae8413b42dbcdff9031bb44b88ed817fc5e528d Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Tue, 21 Apr 2026 23:33:08 +0000 Subject: [PATCH 2/8] Keep 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 | 10 ++++---- .../src/delegation/generics.rs | 10 ++++---- compiler/rustc_ast_lowering/src/expr.rs | 4 ++-- compiler/rustc_ast_lowering/src/format.rs | 6 ++--- compiler/rustc_ast_lowering/src/item.rs | 10 ++++---- compiler/rustc_ast_lowering/src/lib.rs | 24 +++++++++---------- 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 +- 21 files changed, 58 insertions(+), 66 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 520377e7c7af7..46d7beae8fe58 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -20,7 +20,7 @@ use super::errors::{ }; use crate::{AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, 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 870b8897844aa..c70e7d3872d79 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 37ecd10b11e63..55598e3324ec9 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -105,7 +105,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, @@ -661,13 +661,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() @@ -679,7 +679,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 b8855dcc15e2a..8098b5b4b9684 100644 --- a/compiler/rustc_ast_lowering/src/delegation/generics.rs +++ b/compiler/rustc_ast_lowering/src/delegation/generics.rs @@ -97,7 +97,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 { @@ -117,7 +117,7 @@ impl<'hir> HirOrTyGenerics<'hir> { pub(super) fn into_generic_args( &self, - ctx: &mut LoweringContext<'hir>, + ctx: &mut LoweringContext<'_, 'hir>, add_lifetimes: bool, span: Span, ) -> &'hir hir::GenericArgs<'hir> { @@ -151,7 +151,7 @@ impl<'hir> GenericsGenerationResults<'hir> { pub(super) fn all_params( &mut self, span: Span, - ctx: &mut LoweringContext<'hir>, + ctx: &mut LoweringContext<'_, 'hir>, ) -> impl Iterator> { // Now we always call `into_hir_generics` both on child and parent, // however in future we would not do that, when scenarios like @@ -185,7 +185,7 @@ impl<'hir> GenericsGenerationResults<'hir> { pub(super) fn all_predicates( &mut self, span: Span, - ctx: &mut LoweringContext<'hir>, + ctx: &mut LoweringContext<'_, 'hir>, ) -> impl Iterator> { // Now we always call `into_hir_generics` both on child and parent, // however in future we would not do that, when scenarios like @@ -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 987c36b95ec26..f0b292d3179da 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -51,7 +51,7 @@ impl<'v> rustc_ast::visit::Visitor<'v> for WillCreateDefIdsVisitor { } } -impl<'hir> LoweringContext<'hir> { +impl<'hir> LoweringContext<'_, 'hir> { fn lower_exprs(&mut self, exprs: &[Box]) -> &'hir [hir::Expr<'hir>] { self.arena.alloc_from_iter(exprs.iter().map(|x| self.lower_expr_mut(x))) } @@ -1235,7 +1235,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/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 25753610d469e..d7134e45ce447 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -50,7 +50,7 @@ impl<'hir> Owners<'_, 'hir> { pub(super) struct ItemLowerer<'a, 'hir> { pub(super) tcx: TyCtxt<'hir>, - pub(super) resolver: &'hir ResolverAstLowering<'hir>, + pub(super) resolver: &'a ResolverAstLowering<'hir>, pub(super) ast_index: &'a IndexSlice>, pub(super) owners: Owners<'a, 'hir>, } @@ -78,7 +78,7 @@ impl<'hir> ItemLowerer<'_, 'hir> { fn with_lctx( &mut self, owner: NodeId, - f: impl FnOnce(&mut LoweringContext<'hir>) -> hir::OwnerNode<'hir>, + f: impl for<'a> FnOnce(&mut LoweringContext<'a, 'hir>) -> hir::OwnerNode<'hir>, ) { let mut lctx = LoweringContext::new(self.tcx, self.resolver); lctx.with_hir_id_owner(owner, |lctx| f(lctx)); @@ -122,7 +122,7 @@ impl<'hir> ItemLowerer<'_, 'hir> { } } -impl<'hir> LoweringContext<'hir> { +impl<'hir> LoweringContext<'_, 'hir> { pub(super) fn lower_mod( &mut self, items: &[Box], @@ -1531,7 +1531,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, @@ -1668,7 +1668,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 9b7a1311f4800..f472a9205f0ae 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -91,9 +91,9 @@ mod pat; mod path; pub mod stability; -struct LoweringContext<'hir> { +struct LoweringContext<'a, 'hir> { tcx: TyCtxt<'hir>, - resolver: &'hir ResolverAstLowering<'hir>, + resolver: &'a ResolverAstLowering<'hir>, disambiguator: PerParentDisambiguatorState, /// Used to allocate HIR nodes. @@ -161,8 +161,8 @@ struct LoweringContext<'hir> { attribute_parser: AttributeParser<'hir>, } -impl<'hir> LoweringContext<'hir> { - fn new(tcx: TyCtxt<'hir>, resolver: &'hir ResolverAstLowering<'hir>) -> Self { +impl<'a, 'hir> LoweringContext<'a, 'hir> { + fn new(tcx: TyCtxt<'hir>, resolver: &'a ResolverAstLowering<'hir>) -> Self { let registered_tools = tcx.registered_tools(()).iter().map(|x| x.name).collect(); Self { tcx, @@ -535,8 +535,7 @@ pub 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(); - let krate = krate.steal(); + let (resolver, krate) = tcx.resolver_for_lowering().steal(); let ast_index = index_crate(&resolver, &krate); let mut owners = IndexVec::from_fn_n( @@ -546,7 +545,7 @@ pub 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), }; @@ -567,16 +566,15 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { let opt_hir_hash = if tcx.needs_crate_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) + let delayed_resolver = Steal::new((resolver, krate)); + mid_hir::Crate::new(owners, delayed_ids, delayed_resolver, opt_hir_hash) } /// Lowers an AST owner corresponding to `def_id`, now only delegations are lowered this way. pub 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(); + let (resolver, krate) = &*krate.delayed_resolver.borrow(); // FIXME!!!(fn_delegation): make ast index lifetime same as resolver, // as it is too bad to reindex whole crate on each delegation lowering. @@ -625,7 +623,7 @@ enum GenericArgsMode { Silence, } -impl<'hir> LoweringContext<'hir> { +impl<'hir> LoweringContext<'_, 'hir> { fn create_def( &mut self, node_id: ast::NodeId, @@ -3027,7 +3025,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 408ce5f381ca7..cf0615b8244e5 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -14,7 +14,7 @@ use super::{ 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 fb888067456b2..49c5f060e2a1e 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -20,7 +20,7 @@ use super::{ LifetimeRes, LoweringContext, ParamMode, ResolverAstLoweringExt, }; -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 230c56e89a7e3..79b6fc59978f3 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -212,7 +212,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().borrow().1), } } @@ -262,7 +262,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().borrow().1) } Hir(s) => { debug!("pretty printing HIR {:?}", s); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index e17f54df69fb0..9c020c35e1429 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -401,8 +401,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 (resolver, krate) = &*tcx.resolver_for_lowering().borrow(); let mut lint_buffer = resolver.lint_buffer.steal(); if sess.opts.unstable_opts.input_stats { @@ -785,7 +784,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 Steal<(ty::ResolverAstLowering<'tcx>, Arc)>, &'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(); @@ -807,7 +806,7 @@ fn resolver_for_lowering_raw<'tcx>( } = 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(Steal::new((untracked_resolver_for_lowering, Arc::new(krate)))), resolutions) } pub fn write_dep_info(tcx: TyCtxt<'_>) { @@ -864,8 +863,7 @@ pub fn write_interface<'tcx>(tcx: TyCtxt<'tcx>) { return; } let _timer = tcx.sess.timer("write_interface"); - let (_, krate) = tcx.resolver_for_lowering(); - let krate = &*krate.borrow(); + let (_, krate) = &*tcx.resolver_for_lowering().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 666b120aa1fb4..de6a105ee2b7b 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -31,12 +31,10 @@ macro_rules! arena_types { rustc_hir::def_id::LocalDefId, rustc_middle::ty::DefinitionSiteHiddenType<'tcx>, >, - [] resolver: ( + [] resolver: rustc_data_structures::steal::Steal<( rustc_middle::ty::ResolverAstLowering<'tcx>, - rustc_data_structures::steal::Steal< - std::sync::Arc - > - ), + 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 62e2fcc686a32..68357212bebe8 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -1251,7 +1251,7 @@ fn force_delayed_owners_lowering(tcx: TyCtxt<'_>) { tcx.ensure_done().lower_delayed_owner(id); } - let krate = krate.ast_krate.steal(); + let (_, krate) = krate.delayed_resolver.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 1e878af292b87..7f82b9161fe61 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -23,7 +23,7 @@ use rustc_macros::{Decodable, Encodable, HashStable}; use rustc_span::{ErrorGuaranteed, ExpnId, HashStableContext, Span}; use crate::query::Providers; -use crate::ty::TyCtxt; +use crate::ty::{ResolverAstLowering, TyCtxt}; /// The top-level data structure that stores the entire contents of /// the crate currently being compiled. @@ -37,9 +37,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 AST crate which are set in the end of the `hir_crate` query + // The resolver and 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>, + pub delayed_resolver: Steal<(ResolverAstLowering<'hir>, Arc)>, // Only present when incr. comp. is enabled. pub opt_hir_hash: Option, } @@ -48,10 +48,10 @@ impl<'hir> Crate<'hir> { pub fn new( owners: IndexVec>, delayed_ids: FxIndexSet, - ast_krate: Steal>, + delayed_resolver: Steal<(ResolverAstLowering<'hir>, Arc)>, opt_hir_hash: Option, ) -> Crate<'hir> { - Crate { owners, delayed_ids, ast_krate, opt_hir_hash } + Crate { owners, delayed_ids, delayed_resolver, 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 d323535492124..7c6ab642b2736 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -181,10 +181,7 @@ rustc_queries! { desc { "getting the resolver outputs" } } - query resolver_for_lowering_raw(_: ()) -> ( - &'tcx (ty::ResolverAstLowering<'tcx>, Steal>), - &'tcx ty::ResolverGlobalCtxt, - ) { + query resolver_for_lowering_raw(_: ()) -> (&'tcx Steal<(ty::ResolverAstLowering<'tcx>, Arc)>, &'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 627e25756759f..71b0077b62131 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2822,7 +2822,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn resolver_for_lowering( self, - ) -> &'tcx (ty::ResolverAstLowering<'tcx>, Steal>) { + ) -> &'tcx Steal<(ty::ResolverAstLowering<'tcx>, Arc)> { 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 a789aab770ba4..1f27384d4e7ca 100644 --- a/compiler/rustc_passes/src/debugger_visualizer.rs +++ b/compiler/rustc_passes/src/debugger_visualizer.rs @@ -68,7 +68,8 @@ 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 resolver_and_krate = tcx.resolver_for_lowering().borrow(); + let krate = &*resolver_and_krate.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 605e7b5496013..b6fb9937dfa45 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, krate) = tcx.resolver_for_lowering(); - let krate = &*krate.borrow(); + let resolver = tcx.resolver_for_lowering().borrow(); + let (resolver, krate) = &*resolver; // Initialize the collector. let mut collector = LanguageItemCollector::new(tcx, resolver); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 6743bb001a84c..21ce508d8560c 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -338,7 +338,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 (_resolver, krate) = &*tcx.resolver_for_lowering().borrow(); source_macro_expansion(&krate, &render_options, output_format, tcx.sess.source_map()) }; From 09b47c9cdf8ee47a7376d347ed97d7496874f5f0 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Tue, 21 Apr 2026 23:39:20 +0000 Subject: [PATCH 3/8] Use imported NodeId. --- compiler/rustc_ast_lowering/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index f472a9205f0ae..187802f3b716a 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -626,7 +626,7 @@ enum GenericArgsMode { impl<'hir> LoweringContext<'_, 'hir> { fn create_def( &mut self, - node_id: ast::NodeId, + node_id: NodeId, name: Option, def_kind: DefKind, span: Span, @@ -656,7 +656,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn next_node_id(&mut self) -> NodeId { let start = self.next_node_id; let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds"); - self.next_node_id = ast::NodeId::from_u32(next); + self.next_node_id = NodeId::from_u32(next); start } From a9cee38387a361b3d3d02aeb31c0074bdfd11c32 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Tue, 21 Apr 2026 23:46:17 +0000 Subject: [PATCH 4/8] Lighten and document partial_res_overrides. --- compiler/rustc_ast_lowering/src/delegation.rs | 5 ++--- compiler/rustc_ast_lowering/src/lib.rs | 15 ++++++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 55598e3324ec9..a2f211457cda7 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -39,7 +39,7 @@ use std::iter; use ast::visit::Visitor; -use hir::def::{DefKind, PartialRes, Res}; +use hir::def::{DefKind, Res}; use hir::{BodyId, HirId}; use rustc_abi::ExternAbi; use rustc_ast as ast; @@ -673,8 +673,7 @@ impl SelfResolver<'_, '_, '_> { && let Some(Res::Local(sig_id)) = res.full_res() && sig_id == self.path_id { - let new_res = PartialRes::new(Res::Local(self.self_param_id)); - self.ctxt.partial_res_overrides.insert(id, new_res); + self.ctxt.partial_res_overrides.insert(id, self.self_param_id); } } } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 187802f3b716a..c9b2b0fd2102e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -145,7 +145,9 @@ struct LoweringContext<'a, 'hir> { /// Maps the `NodeId`s created during lowering to `LocalDefId`s. node_id_to_def_id: NodeMap, /// Overlay over resolver's `partial_res_map` used by delegation. - partial_res_overrides: NodeMap, + /// This only contains `PartialRes::new(Res::Local(self_param_id))`, + /// so we only store `self_param_id`. + partial_res_overrides: NodeMap, allow_contracts: Arc<[Symbol]>, allow_try_trait: Arc<[Symbol]>, @@ -261,6 +263,9 @@ impl<'tcx> ResolverAstLowering<'tcx> { return None; } + // We do not need to look at `partial_res_overrides`. That map only contains overrides for + // `self_param` locals. And here we are looking for the function definition that `expr` + // resolves to. let def_id = self.partial_res_map.get(&expr.id)?.full_res()?.opt_def_id()?; // We only support cross-crate argument rewriting. Uses @@ -674,10 +679,10 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn get_partial_res(&self, id: NodeId) -> Option { - self.partial_res_overrides - .get(&id) - .or_else(|| self.resolver.partial_res_map.get(&id)) - .copied() + match self.partial_res_overrides.get(&id) { + Some(self_param_id) => Some(PartialRes::new(Res::Local(*self_param_id))), + None => self.resolver.partial_res_map.get(&id).copied(), + } } /// Given the id of an owner node in the AST, returns the corresponding `OwnerId`. From 5bbca1fa9dbb80cd54f0544c8808d304ad7dd483 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Tue, 21 Apr 2026 23:53:45 +0000 Subject: [PATCH 5/8] Revert "Keep stealing ResolverAstLowering." This reverts commit 2ae8413b42dbcdff9031bb44b88ed817fc5e528d. --- 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 | 10 ++++---- compiler/rustc_ast_lowering/src/expr.rs | 4 ++-- compiler/rustc_ast_lowering/src/format.rs | 6 ++--- compiler/rustc_ast_lowering/src/item.rs | 10 ++++---- compiler/rustc_ast_lowering/src/lib.rs | 24 ++++++++++--------- 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 +- 21 files changed, 66 insertions(+), 58 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 46d7beae8fe58..520377e7c7af7 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -20,7 +20,7 @@ use super::errors::{ }; use crate::{AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, 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 a2f211457cda7..a2f02f2813a48 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -105,7 +105,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, @@ -661,13 +661,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() @@ -678,7 +678,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 8098b5b4b9684..b8855dcc15e2a 100644 --- a/compiler/rustc_ast_lowering/src/delegation/generics.rs +++ b/compiler/rustc_ast_lowering/src/delegation/generics.rs @@ -97,7 +97,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 { @@ -117,7 +117,7 @@ impl<'hir> HirOrTyGenerics<'hir> { pub(super) fn into_generic_args( &self, - ctx: &mut LoweringContext<'_, 'hir>, + ctx: &mut LoweringContext<'hir>, add_lifetimes: bool, span: Span, ) -> &'hir hir::GenericArgs<'hir> { @@ -151,7 +151,7 @@ impl<'hir> GenericsGenerationResults<'hir> { pub(super) fn all_params( &mut self, span: Span, - ctx: &mut LoweringContext<'_, 'hir>, + ctx: &mut LoweringContext<'hir>, ) -> impl Iterator> { // Now we always call `into_hir_generics` both on child and parent, // however in future we would not do that, when scenarios like @@ -185,7 +185,7 @@ impl<'hir> GenericsGenerationResults<'hir> { pub(super) fn all_predicates( &mut self, span: Span, - ctx: &mut LoweringContext<'_, 'hir>, + ctx: &mut LoweringContext<'hir>, ) -> impl Iterator> { // Now we always call `into_hir_generics` both on child and parent, // however in future we would not do that, when scenarios like @@ -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 f0b292d3179da..987c36b95ec26 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -51,7 +51,7 @@ impl<'v> rustc_ast::visit::Visitor<'v> for WillCreateDefIdsVisitor { } } -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir> LoweringContext<'hir> { fn lower_exprs(&mut self, exprs: &[Box]) -> &'hir [hir::Expr<'hir>] { self.arena.alloc_from_iter(exprs.iter().map(|x| self.lower_expr_mut(x))) } @@ -1235,7 +1235,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/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 d7134e45ce447..25753610d469e 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -50,7 +50,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>, } @@ -78,7 +78,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)); @@ -122,7 +122,7 @@ impl<'hir> ItemLowerer<'_, 'hir> { } } -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir> LoweringContext<'hir> { pub(super) fn lower_mod( &mut self, items: &[Box], @@ -1531,7 +1531,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, @@ -1668,7 +1668,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 c9b2b0fd2102e..275f101710d5c 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -91,9 +91,9 @@ mod pat; mod path; pub mod stability; -struct LoweringContext<'a, 'hir> { +struct LoweringContext<'hir> { tcx: TyCtxt<'hir>, - resolver: &'a ResolverAstLowering<'hir>, + resolver: &'hir ResolverAstLowering<'hir>, disambiguator: PerParentDisambiguatorState, /// Used to allocate HIR nodes. @@ -163,8 +163,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 { let registered_tools = tcx.registered_tools(()).iter().map(|x| x.name).collect(); Self { tcx, @@ -540,7 +540,8 @@ pub 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( @@ -550,7 +551,7 @@ pub 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 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { let opt_hir_hash = if tcx.needs_crate_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. pub 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. @@ -628,7 +630,7 @@ enum GenericArgsMode { Silence, } -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir> LoweringContext<'hir> { fn create_def( &mut self, node_id: NodeId, @@ -3030,7 +3032,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 cf0615b8244e5..408ce5f381ca7 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -14,7 +14,7 @@ use super::{ 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 49c5f060e2a1e..fb888067456b2 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -20,7 +20,7 @@ use super::{ LifetimeRes, LoweringContext, ParamMode, ResolverAstLoweringExt, }; -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 79b6fc59978f3..230c56e89a7e3 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -212,7 +212,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()), } } @@ -262,7 +262,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 9c020c35e1429..e17f54df69fb0 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -401,7 +401,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 { @@ -784,7 +785,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(); @@ -806,7 +807,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<'_>) { @@ -863,7 +864,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 de6a105ee2b7b..666b120aa1fb4 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -31,10 +31,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 68357212bebe8..62e2fcc686a32 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -1251,7 +1251,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 7f82b9161fe61..1e878af292b87 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -23,7 +23,7 @@ use rustc_macros::{Decodable, Encodable, HashStable}; use rustc_span::{ErrorGuaranteed, ExpnId, HashStableContext, 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. @@ -37,9 +37,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, } @@ -48,10 +48,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 7c6ab642b2736..d323535492124 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -181,7 +181,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 71b0077b62131..627e25756759f 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2822,7 +2822,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 1f27384d4e7ca..a789aab770ba4 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 b6fb9937dfa45..605e7b5496013 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 21ce508d8560c..6743bb001a84c 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -338,7 +338,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 d0742986bdf01906569f970fe71b4f41ce7126e6 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Fri, 17 Apr 2026 20:44:00 +0000 Subject: [PATCH 6/8] Make lowering incremental. Co-authored-by: Camille Gillot --- compiler/rustc_ast/src/ast.rs | 11 + compiler/rustc_ast_lowering/src/item.rs | 146 ++++------ compiler/rustc_ast_lowering/src/lib.rs | 251 ++++++++---------- compiler/rustc_driver_impl/src/pretty.rs | 4 +- compiler/rustc_hir/src/hir.rs | 9 +- compiler/rustc_interface/src/passes.rs | 26 +- compiler/rustc_middle/src/arena.rs | 12 +- compiler/rustc_middle/src/hir/map.rs | 32 +-- compiler/rustc_middle/src/hir/mod.rs | 87 +----- compiler/rustc_middle/src/queries.rs | 32 +-- 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 +- ...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 +- 19 files changed, 252 insertions(+), 410 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index b2c573c23f891..5c2b381388f1c 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -4308,6 +4308,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/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 25753610d469e..9014f870e5c15 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -3,15 +3,13 @@ use std::mem; 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::def_id::CRATE_DEF_ID; use rustc_hir::{ self as hir, HirId, ImplItemImplKind, LifetimeSource, PredicateOrigin, Target, find_attr, }; -use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::span_bug; use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; use rustc_span::def_id::DefId; @@ -24,35 +22,13 @@ use tracing::instrument; use super::errors::{InvalidAbi, InvalidAbiSuggestion, TupleStructWithDefault, UnionWithDefault}; 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, }; -/// 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 @@ -74,51 +50,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.local_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> { + debug_assert_eq!(self.resolver.node_id_to_def_id[&CRATE_NODE_ID], CRATE_DEF_ID); + self.with_lctx(CRATE_NODE_ID, |lctx| { + 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), @@ -779,21 +752,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 { @@ -973,14 +934,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(box ConstItem { @@ -1202,16 +1163,17 @@ impl<'hir> LoweringContext<'hir> { }) } - 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, @@ -1329,7 +1291,7 @@ impl<'hir> LoweringContext<'hir> { let span = self.lower_span(i.span); let item = hir::ImplItem { - owner_id: hir_id.expect_owner(), + owner_id, ident: self.lower_ident(ident), generics, impl_kind: if is_in_trait_impl { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 275f101710d5c..b0f3c97a80daf 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -39,27 +39,23 @@ 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, EmitAttribute, Late, OmitDoc}; -use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::sorted_map::SortedMap; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::steal::Steal; use rustc_data_structures::tagged_ptr::TaggedRef; +use rustc_data_structures::unord::ExtendUnord; use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle}; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; -use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId}; +use rustc_hir::def_id::{LOCAL_CRATE, LocalDefId, LocalDefIdMap}; use rustc_hir::definitions::PerParentDisambiguatorState; use rustc_hir::lints::{AttributeLint, DelayedLint, DynAttribute}; use rustc_hir::{ self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource, LifetimeSyntax, 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::span_bug; use rustc_middle::ty::{DelegationInfo, ResolverAstLowering, TyCtxt}; use rustc_session::parse::add_feature_diagnostics; @@ -70,7 +66,6 @@ use thin_vec::ThinVec; use tracing::{debug, instrument, trace}; use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait}; -use crate::item::Owners; macro_rules! arena_vec { ($this:expr; $($x:expr),*) => ( @@ -106,7 +101,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)>, @@ -164,25 +159,27 @@ 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 registered_tools = tcx.registered_tools(()).iter().map(|x| x.name).collect(); + let current_hir_id_owner = hir::OwnerId { def_id: resolver.node_id_to_def_id[&owner] }; + let disambiguator = resolver.steal_or_create_disambiguator(current_hir_id_owner.def_id); Self { tcx, resolver, - disambiguator: Default::default(), + disambiguator, 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, + 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(), + node_id_to_local_id: [(owner, hir::ItemLocalId::ZERO)].into_iter().collect(), trait_map: Default::default(), next_node_id: resolver.next_node_id, node_id_to_def_id: NodeMap::default(), @@ -313,14 +310,6 @@ impl<'tcx> ResolverAstLowering<'tcx> { self.delegation_infos.get(&id) } - fn opt_local_def_id(&self, id: NodeId) -> Option { - self.node_id_to_def_id.get(&id).copied() - } - - fn local_def_id(&self, id: NodeId) -> LocalDefId { - self.opt_local_def_id(id).expect("must have def_id") - } - fn lifetime_elision_allowed(&self, id: NodeId) -> bool { self.lifetime_elision_allowed.contains(&id) } @@ -446,15 +435,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), -} - #[derive(Copy, Clone, Debug)] enum TryBlockScope { /// There isn't a `try` block, so a `?` will use `return`. @@ -467,140 +447,115 @@ 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); +pub fn index_ast<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx IndexVec> { + let (resolver, krate) = tcx.resolver_for_lowering(); - return indexer.index; + let mut indexer = + Indexer { node_id_to_def_id: &resolver.node_id_to_def_id, index: IndexVec::new() }; + indexer.visit_crate(&krate); + indexer.insert(CRATE_NODE_ID, AstOwner::Crate(&*krate)); + return tcx.arena.alloc(indexer.index); - struct Indexer<'a, 'b> { - resolver: &'b ResolverAstLowering<'b>, - index: IndexVec>, + struct Indexer<'s, 'ast> { + node_id_to_def_id: &'s NodeMap, + index: IndexVec>, } - impl<'a, 'b> visit::Visitor<'a> for Indexer<'a, 'b> { - fn visit_attribute(&mut self, _: &'a Attribute) { + impl<'ast> Indexer<'_, 'ast> { + fn insert(&mut self, id: NodeId, node: AstOwner<'ast>) { + let def_id = self.node_id_to_def_id[&id]; + self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner); + self.index[def_id] = node; + } + + 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.node_id_to_def_id[&id]; + self.visit_item_id_use_tree(nested, def_id); + } + } + } + } + } + + 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.local_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.node_id_to_def_id[&item.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.local_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.local_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.hash_stable(&mut hcx, &mut stable_hasher); - stable_hasher.finish() - }) -} - -pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { +#[instrument(level = "trace", skip(tcx))] +pub 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().def_index_count(), - ); - - let mut lowerer = item::ItemLowerer { - tcx, - resolver, - ast_index: &ast_index, - owners: Owners::IndexVec(&mut owners), - }; - - let mut delayed_ids: FxIndexSet = Default::default(); - - for def_id in ast_index.indices() { - match &ast_index[def_id] { - AstOwner::Item(Item { kind: ItemKind::Delegation { .. }, .. }) - | AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation { .. }, .. }, _) => { - delayed_ids.insert(def_id); - } - _ => lowerer.lower_node(def_id), - }; - } - - // Don't hash unless necessary, because it's expensive. - let opt_hir_hash = - if tcx.needs_crate_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. -pub 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 ast_index = tcx.index_ast(()); + let node = ast_index.get(def_id); - let mut map = Default::default(); + let mut item_lowerer = item::ItemLowerer { tcx, resolver }; - let mut lowerer = item::ItemLowerer { - tcx, - resolver: &resolver, - ast_index: &ast_index, - owners: Owners::Map(&mut map), + // 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); + } + 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)] @@ -669,6 +624,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) @@ -722,6 +678,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. @@ -757,9 +714,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> { @@ -768,6 +727,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 = 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() { @@ -788,7 +748,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`. @@ -807,7 +774,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.resolver.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 230c56e89a7e3..daca2a711acc4 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -212,7 +212,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), } } @@ -262,7 +262,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 d8149b4e30a59..6a5ab856d6ad6 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -19,6 +19,7 @@ pub use rustc_ast::{ use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::sorted_map::SortedMap; 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, HashStable_Generic}; @@ -1636,6 +1637,8 @@ pub struct OwnerInfo<'hir> { /// should only be accessed in `eval_always` queries. #[stable_hasher(ignore)] pub delayed_lints: DelayedLints, + /// Owners generated as side-effect by lowering. + pub children: UnordMap>, } impl<'tcx> OwnerInfo<'tcx> { @@ -1649,18 +1652,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 e17f54df69fb0..bab13e843b755 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -23,7 +23,7 @@ use rustc_hir::def_id::{LOCAL_CRATE, StableCrateId, StableCrateIdMap}; use rustc_hir::definitions::Definitions; use rustc_hir::limit::Limit; use rustc_hir::lints::DelayedLint; -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, DecorateAttrLint, EarlyCheckNode, LintStore, unerased_lint_store, @@ -402,7 +402,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 { @@ -478,7 +477,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { tcx.registered_tools(()), Some(lint_buffer), rustc_lint::BuiltinCombinedEarlyLintPass::new(), - (&**krate, &*krate.attrs), + (krate, &*krate.attrs), ) } @@ -785,7 +784,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(); @@ -806,8 +805,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<'_>) { @@ -865,7 +867,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, @@ -882,14 +883,11 @@ 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; - providers.queries.hir_crate = rustc_ast_lowering::lower_to_hir; - providers.queries.lower_delayed_owner = rustc_ast_lowering::lower_delayed_owner; - // `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.delayed_owner = |_, _| MaybeOwner::Phantom; + providers.queries.index_ast = rustc_ast_lowering::index_ast; + providers.queries.lower_to_hir = rustc_ast_lowering::lower_to_hir; 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; limits::provide(&mut providers.queries); @@ -1062,6 +1060,8 @@ pub fn emit_delayed_lints(tcx: TyCtxt<'_>) { /// Runs all analyses that we guarantee to run, even if errors were reported in earlier analyses. /// This function never fails. fn run_required_analyses(tcx: TyCtxt<'_>) { + tcx.ensure_done().early_lint_checks(()); + if tcx.sess.opts.unstable_opts.input_stats { rustc_passes::input_stats::print_hir_stats(tcx); } diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 666b120aa1fb4..12ed41aaf5ae8 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -31,12 +31,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 62e2fcc686a32..af447a30ced68 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -7,7 +7,7 @@ use rustc_ast::visit::{VisitorResult, walk_list}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; 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}; @@ -1124,11 +1124,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 @@ -1163,7 +1160,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.hash_stable(&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.hash_stable(&mut hcx, &mut stable_hasher); + } + } upstream_crates.hash_stable(&mut hcx, &mut stable_hasher); source_file_names.hash_stable(&mut hcx, &mut stable_hasher); debugger_visualizers.hash_stable(&mut hcx, &mut stable_hasher); @@ -1245,25 +1247,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 1e878af292b87..49459a11088e8 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -6,83 +6,19 @@ 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_hasher::{HashStable, 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, LocalModDefId}; use rustc_hir::*; -use rustc_index::IndexVec; use rustc_macros::{Decodable, Encodable, HashStable}; -use rustc_span::{ErrorGuaranteed, ExpnId, HashStableContext, Span}; +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.delayed_owner(def_id) - } -} - -impl HashStable for Crate<'_> { - fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { - let Crate { opt_hir_hash, .. } = self; - opt_hir_hash.unwrap().hash_stable(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, HashStable, Encodable, Decodable)] @@ -422,8 +358,7 @@ impl<'tcx> TyCtxt<'tcx> { HirId { owner: parent_owner_id, local_id: self - .hir_crate(()) - .owner(self, parent_owner_id.def_id) + .lower_to_hir(parent_owner_id.def_id) .unwrap() .parenting .get(&owner_id.def_id) @@ -456,19 +391,16 @@ 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.local_def_id_to_hir_id = |tcx, def_id| match tcx.hir_crate(()).owner(tcx, def_id) { + providers.local_def_id_to_hir_id = |tcx, def_id| match tcx.lower_to_hir(def_id) { MaybeOwner::Owner(_) => HirId::make_owner(def_id), MaybeOwner::NonOwner(hir_id) => hir_id, - MaybeOwner::Phantom => bug!("No HirId for {:?}", def_id), }; - providers.opt_hir_owner_nodes = - |tcx, id| tcx.hir_crate(()).owner(tcx, id).as_owner().map(|i| &i.nodes); + providers.opt_hir_owner_nodes = |tcx, id| tcx.lower_to_hir(id).as_owner().map(|i| &i.nodes); providers.hir_owner_parent_q = |tcx, owner_id| tcx.hir_owner_parent_impl(owner_id); - 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_attr_map = + |tcx, id| tcx.lower_to_hir(id.def_id).as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs); providers.opt_ast_lowering_delayed_lints = - |tcx, id| tcx.hir_crate(()).owner(tcx, id.def_id).as_owner().map(|o| &o.delayed_lints); + |tcx, id| tcx.lower_to_hir(id.def_id).as_owner().map(|o| &o.delayed_lints); 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| { let hir_id = tcx.local_def_id_to_hir_id(def_id); @@ -508,7 +440,6 @@ pub fn provide(providers: &mut Providers) { |tcx, trait_id| tcx.resolutions(()).trait_impls.get(&trait_id).map_or(&[], |xs| &xs[..]); providers.expn_that_defined = |tcx, id| tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root()); - providers.in_scope_traits_map = |tcx, id| { - tcx.hir_crate(()).owner(tcx, id.def_id).as_owner().map(|owner_info| &owner_info.trait_map) - }; + providers.in_scope_traits_map = + |tcx, id| tcx.lower_to_hir(id.def_id).as_owner().map(|owner_info| &owner_info.trait_map); } diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index d323535492124..e583c5505cef8 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -82,7 +82,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; @@ -182,7 +181,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 @@ -190,6 +190,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. @@ -201,27 +207,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) } - } - - query delayed_owner(def_id: LocalDefId) -> hir::MaybeOwner<'tcx> { - feedable - desc { "getting child of lowered delayed AST owner `{}`", tcx.def_path_str(def_id) } + desc { "lower HIR for `{}`", tcx.def_path_str(key.to_def_id()) } } /// All items in the crate. diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index a6ff238ad6f0b..125cf50c6f926 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::<(&'_ (), &'_ (), &'_ ())>()]; +} + macro_rules! impl_erasable_for_types_with_no_type_params { ($($ty:ty),+ $(,)?) => { $( diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 627e25756759f..d4b3259cb0ef3 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -36,7 +36,7 @@ use rustc_hir::definitions::{DefPathData, Definitions, Disambiguator}; 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; @@ -697,12 +697,6 @@ impl<'tcx> TyCtxt<'tcx> { debug_assert_eq!(self.def_kind(key), DefKind::AnonConst); 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 }.delayed_owner(owner); - } } impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> { @@ -2820,10 +2814,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 a789aab770ba4..5b14ba6a434f9 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 605e7b5496013..d8c832e098381 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 6743bb001a84c..5088c930e2cd0 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -338,7 +338,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/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr b/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr index d81b7d142c92f..d529d9c0f2b21 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 HIR ID of `Default` - = note: ...which requires getting the crate HIR... + = note: ...which requires lower 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 HIR ID of `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 HIR ID of `Default`... - = note: ...which requires getting the crate HIR... + = note: ...which requires lower 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: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information 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 d81b7d142c92f..d529d9c0f2b21 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 HIR ID of `Default` - = note: ...which requires getting the crate HIR... + = note: ...which requires lower 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 HIR ID of `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 HIR ID of `Default`... - = note: ...which requires getting the crate HIR... + = note: ...which requires lower 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: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information diff --git a/tests/ui/resolve/query-cycle-issue-124901.stderr b/tests/ui/resolve/query-cycle-issue-124901.stderr index d81b7d142c92f..d529d9c0f2b21 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 HIR ID of `Default` - = note: ...which requires getting the crate HIR... + = note: ...which requires lower 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 HIR ID of `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 HIR ID of `Default`... - = note: ...which requires getting the crate HIR... + = note: ...which requires lower 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: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information From c99e9cb9177a6418ed25d62c4f24e34ec89eddc1 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 22 Jun 2025 15:50:17 +0000 Subject: [PATCH 7/8] Precompute hash for OwnerInfo too. --- compiler/rustc_ast_lowering/src/lib.rs | 21 ++++++++++++++-- compiler/rustc_hir/src/hir.rs | 9 ++++--- compiler/rustc_hir/src/stable_hash_impls.rs | 25 +++++++++++++------ compiler/rustc_middle/src/hir/mod.rs | 6 ++--- compiler/rustc_middle/src/ty/context.rs | 4 +-- .../src/coverage/hir_info.rs | 2 +- 6 files changed, 47 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b0f3c97a80daf..99b2f82be5fe1 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -43,6 +43,7 @@ use rustc_ast::visit::{self, Visitor}; use rustc_ast::{self as ast, *}; use rustc_attr_parsing::{AttributeParser, EmitAttribute, Late, OmitDoc}; use rustc_data_structures::sorted_map::SortedMap; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::tagged_ptr::TaggedRef; use rustc_data_structures::unord::ExtendUnord; use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle}; @@ -741,14 +742,30 @@ 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 = if self.tcx.needs_crate_hash() { + Some(self.tcx.with_stable_hashing_context(|mut hcx| { + let mut stable_hasher = StableHasher::new(); + bodies_hash.unwrap().hash_stable(&mut hcx, &mut stable_hasher); + attrs_hash.unwrap().hash_stable(&mut hcx, &mut stable_hasher); + // Do not hash delayed_lints. + parenting.hash_stable(&mut hcx, &mut stable_hasher); + trait_map.hash_stable(&mut hcx, &mut stable_hasher); + children.hash_stable(&mut hcx, &mut stable_hasher); + stable_hasher.finish() + })) + } else { + None + }; + 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 6a5ab856d6ad6..f374be9144aeb 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1579,7 +1579,7 @@ impl<'tcx> AttributeMap<'tcx> { 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, + 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 @@ -1612,13 +1612,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, HashStable_Generic)] +#[derive(Debug)] pub struct OwnerInfo<'hir> { /// Contents of the HIR. pub nodes: OwnerNodes<'hir>, @@ -1635,10 +1635,11 @@ 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_hasher(ignore)] pub delayed_lints: DelayedLints, /// Owners generated as side-effect by lowering. pub children: UnordMap>, + // 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 3a10f790cd5cc..4a721a5d29fdb 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -4,7 +4,7 @@ use rustc_span::def_id::DefPathHash; use crate::HashIgnoredAttrId; use crate::hir::{ - AttributeMap, BodyId, ForeignItemId, ImplItemId, ItemId, OwnerNodes, TraitItemId, + AttributeMap, BodyId, ForeignItemId, ImplItemId, ItemId, OwnerInfo, OwnerNodes, TraitItemId, }; use crate::hir_id::ItemLocalId; @@ -62,18 +62,17 @@ impl ToStableHashKey for ForeignItemId { // in "DefPath Mode". impl<'tcx, Hcx: HashStableContext> HashStable for OwnerNodes<'tcx> { + #[inline] fn hash_stable(&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 - // `hash_stable` results. - let OwnerNodes { opt_hash_including_bodies, nodes: _, bodies: _ } = *self; - opt_hash_including_bodies.unwrap().hash_stable(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().hash_stable(hcx, hasher); } } impl<'tcx, Hcx: HashStableContext> HashStable for AttributeMap<'tcx> { + #[inline] fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { // We ignore the `map` since it refers to information included in `opt_hash` which is // hashed in the collector and used for the crate hash. @@ -82,6 +81,16 @@ impl<'tcx, Hcx: HashStableContext> HashStable for AttributeMap<'tcx> { } } +impl<'tcx, Hcx: HashStableContext> HashStable for OwnerInfo<'tcx> { + #[inline] + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + // We ignore the rest since it refers 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().hash_stable(hcx, hasher); + } +} + impl HashStable for HashIgnoredAttrId { fn hash_stable(&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 49459a11088e8..acce393dcca54 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -174,7 +174,7 @@ impl<'tcx> TyCtxt<'tcx> { define_opaque: Option<&[(Span, LocalDefId)]>, ) -> Hashes { if !self.needs_crate_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| { @@ -192,7 +192,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) } }) } @@ -383,7 +383,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_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index d4b3259cb0ef3..c93168dfbda25 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -742,11 +742,11 @@ impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> { let bodies = Default::default(); let attrs = hir::AttributeMap::EMPTY; - let rustc_middle::hir::Hashes { opt_hash_including_bodies, .. } = + let rustc_middle::hir::Hashes { bodies_hash, .. } = self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, attrs.define_opaque); let node = node.into(); self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes { - opt_hash_including_bodies, + opt_hash: bodies_hash, nodes: IndexVec::from_elem_n( hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node }, 1, diff --git a/compiler/rustc_mir_transform/src/coverage/hir_info.rs b/compiler/rustc_mir_transform/src/coverage/hir_info.rs index 28fdc52b06cb9..b217c33734068 100644 --- a/compiler/rustc_mir_transform/src/coverage/hir_info.rs +++ b/compiler/rustc_mir_transform/src/coverage/hir_info.rs @@ -69,7 +69,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 b7db8e58bf8d20d06607c885c19a947ce930fa4e Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 2 Jul 2025 16:49:49 +0000 Subject: [PATCH 8/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 | 166 ++++++++++++++---- 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, 184 insertions(+), 102 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ac10d7d4fb53..33a24c3b535d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3526,7 +3526,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 5c2b381388f1c..7479e2c4d336b 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -4309,14 +4309,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 987c36b95ec26..44a971a9a0bf3 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -3,7 +3,6 @@ use std::ops::ControlFlow; use std::sync::Arc; 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; @@ -445,13 +444,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 9014f870e5c15..65f7eb849b5e3 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; use rustc_span::def_id::DefId; 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; @@ -29,6 +29,7 @@ use super::{ 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 @@ -56,7 +57,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()); @@ -105,28 +106,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 99b2f82be5fe1..10ce00d783d26 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -38,12 +38,14 @@ 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, *}; use rustc_attr_parsing::{AttributeParser, EmitAttribute, Late, OmitDoc}; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::steal::Steal; use rustc_data_structures::tagged_ptr::TaggedRef; use rustc_data_structures::unord::ExtendUnord; use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle}; @@ -62,7 +64,7 @@ use rustc_middle::ty::{DelegationInfo, ResolverAstLowering, TyCtxt}; use rustc_session::parse::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}; @@ -160,7 +162,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 registered_tools = tcx.registered_tools(()).iter().map(|x| x.name).collect(); let current_hir_id_owner = hir::OwnerId { def_id: resolver.node_id_to_def_id[&owner] }; let disambiguator = resolver.steal_or_create_disambiguator(current_hir_id_owner.def_id); @@ -182,7 +189,7 @@ impl<'hir> LoweringContext<'hir> { #[cfg(debug_assertions)] node_id_to_local_id: [(owner, hir::ItemLocalId::ZERO)].into_iter().collect(), 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(), @@ -448,69 +455,152 @@ enum TryBlockScope { Heterogeneous(HirId), } -pub fn index_ast<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx IndexVec> { +pub 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 { node_id_to_def_id: &resolver.node_id_to_def_id, 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 { + node_id_to_def_id: &resolver.node_id_to_def_id, + 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> { + struct Indexer<'s> { node_id_to_def_id: &'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.node_id_to_def_id[&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.node_id_to_def_id[&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.node_id_to_def_id[&item.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| { + 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); } } } @@ -523,13 +613,13 @@ pub 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)) => { @@ -543,6 +633,8 @@ pub 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 daca2a711acc4..230c56e89a7e3 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -212,7 +212,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()), } } @@ -262,7 +262,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 bab13e843b755..2fc47293e351c 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -402,6 +402,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 { @@ -477,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), ) } @@ -784,7 +785,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(); @@ -807,7 +808,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), ) } @@ -869,7 +870,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 12ed41aaf5ae8..90a3554d74e74 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -32,11 +32,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 e583c5505cef8..4fee466e34660 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -182,7 +182,7 @@ rustc_queries! { query resolver_for_lowering_raw(_: ()) -> ( &'tcx ty::ResolverAstLowering<'tcx>, - &'tcx ast::Crate, + &'tcx Steal, &'tcx ty::ResolverGlobalCtxt, ) { eval_always @@ -190,7 +190,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 c93168dfbda25..8b531b54bfea3 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2814,7 +2814,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 5b14ba6a434f9..3a7b68692ee37 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 5088c930e2cd0..6743bb001a84c 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -338,7 +338,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