From 14a40e2bda26d3ad8b9737afb1aac0eb2d2c99e5 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 1 Jul 2024 10:27:01 +0000 Subject: [PATCH 1/4] Do not modify resolver outputs during lowering Co-authored-by: Camille Gillot --- compiler/rustc_ast_lowering/src/asm.rs | 5 +- compiler/rustc_ast_lowering/src/block.rs | 2 +- compiler/rustc_ast_lowering/src/contract.rs | 2 +- compiler/rustc_ast_lowering/src/delegation.rs | 27 ++++--- compiler/rustc_ast_lowering/src/expr.rs | 8 +- compiler/rustc_ast_lowering/src/format.rs | 10 +-- compiler/rustc_ast_lowering/src/item.rs | 15 ++-- compiler/rustc_ast_lowering/src/lib.rs | 81 +++++++++++-------- 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_hir/src/hir.rs | 3 +- compiler/rustc_interface/src/passes.rs | 10 ++- compiler/rustc_middle/src/arena.rs | 8 +- compiler/rustc_middle/src/query/mod.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 +- 19 files changed, 109 insertions(+), 96 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index d44faad017ee5..4fbd91fd6fbc8 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -20,10 +20,10 @@ use super::errors::{ }; use crate::{ AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, ParamMode, - ResolverAstLoweringExt, fluent_generated as fluent, + fluent_generated as fluent, }; -impl<'a, 'hir> LoweringContext<'a, 'hir> { +impl<'hir> LoweringContext<'hir> { pub(crate) fn lower_inline_asm( &mut self, sp: Span, @@ -201,7 +201,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }, 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 f1e810a8b9ea9..9e74b7c7e2960 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<'a, 'hir> LoweringContext<'a, '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 2f1c3d66d4e70..8610e6f40c884 100644 --- a/compiler/rustc_ast_lowering/src/contract.rs +++ b/compiler/rustc_ast_lowering/src/contract.rs @@ -2,7 +2,7 @@ use thin_vec::thin_vec; use crate::LoweringContext; -impl<'a, 'hir> LoweringContext<'a, '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 9bfcd232221ba..575c2ff4b38a6 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -46,13 +46,15 @@ use rustc_ast::*; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; use rustc_middle::span_bug; -use rustc_middle::ty::{Asyncness, ResolverAstLowering}; +use rustc_middle::ty::Asyncness; use rustc_span::symbol::kw; use rustc_span::{Ident, Span, Symbol}; use {rustc_ast as ast, rustc_hir as hir}; -use super::{GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode}; -use crate::{AllowReturnTypeNotation, ImplTraitPosition, ResolverAstLoweringExt}; +use super::{ + AllowReturnTypeNotation, GenericArgsMode, ImplTraitContext, ImplTraitPosition, LoweringContext, + ParamMode, +}; pub(crate) struct DelegationResults<'hir> { pub body_id: hir::BodyId, @@ -61,7 +63,7 @@ pub(crate) struct DelegationResults<'hir> { pub generics: &'hir hir::Generics<'hir>, } -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, @@ -112,8 +114,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn get_resolution_id(&self, node_id: NodeId, span: Span) -> Result { - let def_id = - self.resolver.get_partial_res(node_id).and_then(|r| r.expect_full_res().opt_def_id()); + let def_id = self.get_partial_res(node_id).and_then(|r| r.expect_full_res().opt_def_id()); def_id.ok_or_else(|| { self.tcx.dcx().span_delayed_bug( span, @@ -292,7 +293,7 @@ impl<'hir> LoweringContext<'_, 'hir> { && idx == 0 { let mut self_resolver = SelfResolver { - resolver: this.resolver, + ctxt: this, path_id: delegation.id, self_param_id: pat_node_id, }; @@ -438,25 +439,25 @@ impl<'hir> LoweringContext<'_, 'hir> { } } -struct SelfResolver<'a> { - resolver: &'a mut ResolverAstLowering, +struct SelfResolver<'r, 'hir> { + ctxt: &'r mut LoweringContext<'hir>, path_id: NodeId, self_param_id: NodeId, } -impl<'a> SelfResolver<'a> { +impl SelfResolver<'_, '_> { fn try_replace_id(&mut self, id: NodeId) { - if let Some(res) = self.resolver.partial_res_map.get(&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.partial_res_map.insert(id, new_res); + self.ctxt.partial_res_overrides.insert(id, new_res); } } } -impl<'ast, 'a> Visitor<'ast> for SelfResolver<'a> { +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/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index c443b1e3a03c5..0abda20361963 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -52,7 +52,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))) } @@ -1205,7 +1205,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(..) @@ -1265,7 +1265,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> 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() { @@ -1287,7 +1287,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> 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 2871430030c45..f572b2c47ffb1 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -8,7 +8,7 @@ use rustc_span::{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. @@ -236,7 +236,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, @@ -285,7 +285,7 @@ fn make_argument<'hir>( /// ::Implied /// ``` fn make_count<'hir>( - ctx: &mut LoweringContext<'_, 'hir>, + ctx: &mut LoweringContext<'hir>, sp: Span, count: &Option, argmap: &mut FxIndexMap<(usize, ArgumentType), Option>, @@ -336,7 +336,7 @@ fn make_count<'hir>( /// } /// ``` fn make_format_spec<'hir>( - ctx: &mut LoweringContext<'_, 'hir>, + ctx: &mut LoweringContext<'hir>, sp: Span, placeholder: &FormatPlaceholder, argmap: &mut FxIndexMap<(usize, ArgumentType), Option>, @@ -397,7 +397,7 @@ fn make_format_spec<'hir>( } 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 8527108f70419..83f399be6e5d6 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -26,7 +26,7 @@ use super::{ pub(super) struct ItemLowerer<'a, 'hir> { pub(super) tcx: TyCtxt<'hir>, - pub(super) resolver: &'a mut ResolverAstLowering, + pub(super) resolver: &'hir ResolverAstLowering, pub(super) ast_index: &'a IndexSlice>, pub(super) owners: &'a mut IndexVec>, } @@ -54,7 +54,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { fn with_lctx( &mut self, owner: NodeId, - f: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::OwnerNode<'hir>, + f: impl FnOnce(&mut LoweringContext<'hir>) -> hir::OwnerNode<'hir>, ) { let mut lctx = LoweringContext::new(self.tcx, self.resolver); lctx.with_hir_id_owner(owner, |lctx| f(lctx)); @@ -98,7 +98,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { } } -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir> LoweringContext<'hir> { pub(super) fn lower_mod( &mut self, items: &[Box], @@ -1133,7 +1133,6 @@ impl<'hir> LoweringContext<'_, 'hir> { 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(|| { @@ -1321,7 +1320,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, @@ -1458,7 +1457,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); @@ -1677,7 +1676,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // 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, @@ -1719,7 +1718,7 @@ impl<'hir> LoweringContext<'_, 'hir> { 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 be9db9257356c..92197995c8503 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -91,9 +91,9 @@ pub mod stability; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } -struct LoweringContext<'a, 'hir> { +struct LoweringContext<'hir> { tcx: TyCtxt<'hir>, - resolver: &'a mut ResolverAstLowering, + resolver: &'hir ResolverAstLowering, disambiguator: DisambiguatorState, /// Used to allocate HIR nodes. @@ -127,7 +127,7 @@ struct LoweringContext<'a, 'hir> { current_hir_id_owner: hir::OwnerId, item_local_id_counter: hir::ItemLocalId, - trait_map: ItemLocalMap>, + trait_map: ItemLocalMap<&'hir [TraitCandidate]>, impl_trait_defs: Vec>, impl_trait_bounds: Vec>, @@ -137,6 +137,14 @@ struct LoweringContext<'a, 'hir> { /// 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_try_trait: Arc<[Symbol]>, allow_gen_future: Arc<[Symbol]>, @@ -150,8 +158,8 @@ struct LoweringContext<'a, 'hir> { attribute_parser: AttributeParser<'hir>, } -impl<'a, 'hir> LoweringContext<'a, 'hir> { - fn new(tcx: TyCtxt<'hir>, resolver: &'a mut ResolverAstLowering) -> Self { +impl<'hir> LoweringContext<'hir> { + fn new(tcx: TyCtxt<'hir>, resolver: &'hir ResolverAstLowering) -> Self { let registered_tools = tcx.registered_tools(()).iter().map(|x| x.name).collect(); Self { // Pseudo-globals. @@ -172,6 +180,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { #[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. catch_scope: None, @@ -254,10 +265,6 @@ impl ResolverAstLowering { None } - 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() @@ -280,8 +287,8 @@ impl ResolverAstLowering { /// /// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring /// should appear at the enclosing `PolyTraitRef`. - fn extra_lifetime_params(&mut 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[..]) } } @@ -483,7 +490,8 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> 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.node_id_to_def_id, &krate); let mut owners = IndexVec::from_fn_n( @@ -491,12 +499,8 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> { tcx.definitions_untracked().def_index_count(), ); - let mut lowerer = item::ItemLowerer { - tcx, - resolver: &mut resolver, - ast_index: &ast_index, - owners: &mut owners, - }; + let mut lowerer = + item::ItemLowerer { tcx, resolver, ast_index: &ast_index, owners: &mut owners }; for def_id in ast_index.indices() { lowerer.lower_node(def_id); } @@ -543,7 +547,7 @@ enum GenericArgsMode { Silence, } -impl<'a, 'hir> LoweringContext<'a, 'hir> { +impl<'hir> LoweringContext<'hir> { fn create_def( &mut self, node_id: ast::NodeId, @@ -569,28 +573,38 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .def_id(); debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id); - self.resolver.node_id_to_def_id.insert(node_id, def_id); + self.node_id_to_def_id.insert(node_id, def_id); def_id } fn next_node_id(&mut self) -> NodeId { - let start = 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.resolver.next_node_id = ast::NodeId::from_u32(next); + 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.node_id_to_def_id.get(&node).copied() + 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) } @@ -713,8 +727,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id))); } - if let Some(traits) = self.resolver.trait_map.remove(&ast_node_id) { - self.trait_map.insert(hir_id.local_id, traits.into_boxed_slice()); + 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. @@ -755,7 +769,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } 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> { @@ -894,8 +908,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { 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, @@ -1195,7 +1209,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // 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()) { @@ -1242,7 +1255,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // 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| { @@ -1590,7 +1603,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { 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 { @@ -2104,7 +2117,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { 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()) { @@ -2347,7 +2360,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &anon.value }; 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(tcx.features().min_generic_const_args()) && (tcx.features().min_generic_const_args() @@ -2652,7 +2665,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 815338c84fa6c..f72d99416eda3 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -12,10 +12,11 @@ use rustc_span::{DesugaringKind, Ident, Span}; 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<'a, 'hir> LoweringContext<'a, '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)) } @@ -286,7 +287,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { 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 3322e0fb66b44..4ba3fb168081e 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -19,7 +19,7 @@ use super::{ LifetimeRes, LoweringContext, ParamMode, ResolverAstLoweringExt, }; -impl<'a, 'hir> LoweringContext<'a, 'hir> { +impl<'hir> LoweringContext<'hir> { #[instrument(level = "trace", skip(self))] pub(crate) fn lower_qpath( &mut self, @@ -38,8 +38,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Reject cases like `::Assoc` and `::Assoc`. .map(|q| self.lower_ty(&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 1604b704033bd..37b9cfffff3b3 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -211,7 +211,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()), } } @@ -261,7 +261,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_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 90bf82f15f819..ab530d479ba19 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1555,8 +1555,7 @@ pub struct OwnerInfo<'hir> { pub attrs: AttributeMap<'hir>, /// Map indicating what traits are in scope for places where this /// is relevant; generated by resolve. - pub trait_map: ItemLocalMap>, - + pub trait_map: ItemLocalMap<&'hir [TraitCandidate]>, /// Lints delayed during ast lowering to be emitted /// after hir has completely built pub delayed_lints: DelayedLints, diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index a41d6b858795c..d4bc2b1dcaf51 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -400,7 +400,8 @@ fn print_macro_stats(ecx: &ExtCtxt<'_>) { fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { let sess = tcx.sess; - let (resolver, krate) = &*tcx.resolver_for_lowering().borrow(); + let (resolver, krate) = tcx.resolver_for_lowering(); + let krate = &*krate.borrow(); let mut lint_buffer = resolver.lint_buffer.steal(); if sess.opts.unstable_opts.input_stats { @@ -786,7 +787,7 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P fn resolver_for_lowering_raw<'tcx>( tcx: TyCtxt<'tcx>, (): (), -) -> (&'tcx Steal<(ty::ResolverAstLowering, Arc)>, &'tcx ty::ResolverGlobalCtxt) { +) -> (&'tcx (ty::ResolverAstLowering, Steal>), &'tcx ty::ResolverGlobalCtxt) { let arenas = Resolver::arenas(); let _ = tcx.registered_tools(()); // Uses `crate_for_resolver`. let (krate, pre_configured_attrs) = tcx.crate_for_resolver(()).steal(); @@ -808,7 +809,7 @@ fn resolver_for_lowering_raw<'tcx>( } = resolver.into_outputs(); let resolutions = tcx.arena.alloc(untracked_resolutions); - (tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, Arc::new(krate)))), resolutions) + (tcx.arena.alloc((untracked_resolver_for_lowering, Steal::new(Arc::new(krate)))), resolutions) } pub fn write_dep_info(tcx: TyCtxt<'_>) { @@ -865,7 +866,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 feaad5bb96eb9..f40ad79c9c4cd 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -28,10 +28,12 @@ macro_rules! arena_types { >, [decode] typeck_results: rustc_middle::ty::TypeckResults<'tcx>, [decode] borrowck_result: rustc_middle::mir::DefinitionSiteHiddenTypes<'tcx>, - [] resolver: rustc_data_structures::steal::Steal<( + [] resolver: ( rustc_middle::ty::ResolverAstLowering, - 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/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 588ff68ba572d..f8fb5766e34ae 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -197,7 +197,7 @@ rustc_queries! { desc { "getting the resolver outputs" } } - query resolver_for_lowering_raw(_: ()) -> (&'tcx Steal<(ty::ResolverAstLowering, Arc)>, &'tcx ty::ResolverGlobalCtxt) { + query resolver_for_lowering_raw(_: ()) -> (&'tcx (ty::ResolverAstLowering, Steal>), &'tcx ty::ResolverGlobalCtxt) { eval_always no_hash desc { "getting the resolver for lowering" } @@ -1875,8 +1875,7 @@ rustc_queries! { query specializes(_: (DefId, DefId)) -> bool { desc { "computing whether impls specialize one another" } } - query in_scope_traits_map(_: hir::OwnerId) - -> Option<&'tcx ItemLocalMap>> { + query in_scope_traits_map(_: hir::OwnerId) -> Option<&'tcx ItemLocalMap<&'tcx [TraitCandidate]>> { desc { "getting traits in scope at a block" } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1a3eb09491161..9fe17d08464ca 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -3520,7 +3520,7 @@ impl<'tcx> TyCtxt<'tcx> { self.resolutions(()).extern_crate_map.get(&def_id).copied() } - pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc)> { + pub fn resolver_for_lowering(self) -> &'tcx (ty::ResolverAstLowering, 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 7211f3cf85b31..f621dab5b4642 100644 --- a/compiler/rustc_passes/src/debugger_visualizer.rs +++ b/compiler/rustc_passes/src/debugger_visualizer.rs @@ -81,8 +81,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 141a60a8ec3f9..5a10e9cbf5c18 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -247,8 +247,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 44bac8197539b..7a9e9af435ca0 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 d31a6562976454a440020c2aa7ef9eac77bb7410 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 1 Jul 2024 15:46:24 +0000 Subject: [PATCH 2/4] Make lowering incremental. Co-authored-by: Camille Gillot --- compiler/rustc_ast/src/ast.rs | 11 + compiler/rustc_ast_lowering/src/item.rs | 125 +++++------ compiler/rustc_ast_lowering/src/lib.rs | 207 +++++++++--------- compiler/rustc_driver_impl/src/pretty.rs | 4 +- compiler/rustc_hir/src/hir.rs | 22 +- compiler/rustc_hir/src/stable_hash_impls.rs | 9 +- compiler/rustc_interface/src/passes.rs | 13 +- compiler/rustc_middle/src/arena.rs | 8 +- compiler/rustc_middle/src/hir/map.rs | 12 +- compiler/rustc_middle/src/hir/mod.rs | 21 +- compiler/rustc_middle/src/query/mod.rs | 22 +- compiler/rustc_middle/src/ty/context.rs | 2 +- .../rustc_passes/src/debugger_visualizer.rs | 2 +- compiler/rustc_passes/src/lang_items.rs | 1 - src/librustdoc/core.rs | 2 +- tests/ui/attributes/malformed-attrs.stderr | 18 +- 16 files changed, 233 insertions(+), 246 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 94c15094f5251..07f8dd96a2985 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -4027,6 +4027,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 83f399be6e5d6..57d2440ce25f3 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -4,15 +4,14 @@ use rustc_ast::*; use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err}; use rustc_hir::attrs::AttributeKind; 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::edit_distance::find_best_match_for_name; -use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym}; +use rustc_span::{DesugaringKind, Ident, Span, Symbol, kw, sym}; use smallvec::{SmallVec, smallvec}; use thin_vec::ThinVec; use tracing::instrument; @@ -20,15 +19,13 @@ use tracing::instrument; use super::errors::{InvalidAbi, InvalidAbiSuggestion, TupleStructWithDefault, UnionWithDefault}; use super::stability::{enabled_names, gate_unstable_abi}; use super::{ - AstOwner, FnDeclKind, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode, + FnDeclKind, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode, RelaxedBoundForbiddenReason, RelaxedBoundPolicy, ResolverAstLoweringExt, }; -pub(super) struct ItemLowerer<'a, 'hir> { +pub(super) struct ItemLowerer<'hir> { pub(super) tcx: TyCtxt<'hir>, pub(super) resolver: &'hir ResolverAstLowering, - pub(super) ast_index: &'a IndexSlice>, - pub(super) owners: &'a mut IndexVec>, } /// When we have a ty alias we *may* have two where clauses. To give the best diagnostics, we set the span @@ -50,51 +47,47 @@ fn add_ty_alias_where_clause( if before.0 || !after.0 { before } else { after }; } -impl<'a, 'hir> ItemLowerer<'a, '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.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom); - 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.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom); - if let hir::MaybeOwner::Phantom = owner { - let node = self.ast_index[def_id]; - match node { - AstOwner::NonOwner => {} - AstOwner::Crate(c) => { - 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); - // 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))) } } @@ -134,12 +127,13 @@ 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 attrs = self.lower_attrs(hir_id, &i.attrs, i.span, Target::from_ast_item(i)); 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), @@ -606,21 +600,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 { @@ -792,14 +774,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_default) = match &i.kind { AssocItemKind::Const(box ConstItem { @@ -1003,15 +985,16 @@ 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); - let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id); let attrs = self.lower_attrs( hir_id, &i.attrs, @@ -1126,7 +1109,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 92197995c8503..2a065e5b92ae7 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -41,23 +41,22 @@ use std::sync::Arc; use rustc_ast::node_id::NodeMap; +use rustc_ast::visit::{self, Visitor}; use rustc_ast::{self as ast, *}; use rustc_attr_parsing::{AttributeParser, Late, OmitDoc}; -use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::sorted_map::SortedMap; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::sync::spawn; 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::{DefPathData, DisambiguatorState}; use rustc_hir::lints::DelayedLint; use rustc_hir::{ self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource, LifetimeSyntax, ParamName, Target, TraitCandidate, }; -use rustc_index::{Idx, IndexSlice, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_macros::extension; use rustc_middle::span_bug; use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; @@ -106,7 +105,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)>, @@ -159,8 +158,9 @@ struct LoweringContext<'hir> { } impl<'hir> LoweringContext<'hir> { - fn new(tcx: TyCtxt<'hir>, resolver: &'hir ResolverAstLowering) -> Self { + fn new(tcx: TyCtxt<'hir>, resolver: &'hir ResolverAstLowering, 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] }; Self { // Pseudo-globals. tcx, @@ -172,13 +172,13 @@ impl<'hir> LoweringContext<'hir> { 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(), @@ -408,116 +408,115 @@ 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), -} +pub fn index_ast<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx IndexVec> { + let (resolver, krate) = tcx.resolver_for_lowering(); + + 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); -fn index_crate<'a>( - node_id_to_def_id: &NodeMap, - krate: &'a Crate, -) -> IndexVec> { - let mut indexer = Indexer { node_id_to_def_id, index: IndexVec::new() }; - *indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner) = - AstOwner::Crate(krate); - visit::walk_crate(&mut indexer, krate); - return indexer.index; - - struct Indexer<'s, 'a> { + struct Indexer<'s, 'ast> { node_id_to_def_id: &'s NodeMap, - index: IndexVec>, + index: IndexVec>, } - impl<'a> visit::Visitor<'a> for Indexer<'_, 'a> { - 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) { + fn visit_item(&mut self, item: &'ast Item) { let def_id = self.node_id_to_def_id[&item.id]; - *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::Item(item); - visit::walk_item(self, item) + 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.node_id_to_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.node_id_to_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<'_>, (): ()) -> hir::Crate<'_> { - let sess = tcx.sess; +#[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.node_id_to_def_id, &krate); - let mut owners = IndexVec::from_fn_n( - |_| hir::MaybeOwner::Phantom, - tcx.definitions_untracked().def_index_count(), - ); + let (resolver, _) = tcx.resolver_for_lowering(); + let ast_index = tcx.index_ast(()); + let node = ast_index.get(def_id); + + let mut item_lowerer = item::ItemLowerer { tcx, resolver }; + + // 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), + }; - let mut lowerer = - item::ItemLowerer { tcx, resolver, ast_index: &ast_index, owners: &mut owners }; - for def_id in ast_index.indices() { - lowerer.lower_node(def_id); + // The item did not exist in the AST, it was created by its parent. + let mut parent_info = tcx.lower_to_hir(parent_id); + if let hir::MaybeOwner::NonOwner(hir_id) = parent_info { + parent_info = tcx.lower_to_hir(hir_id.owner); } - drop(ast_index); - - // Drop AST to free memory. It can be expensive so try to drop it on a separate thread. - let prof = sess.prof.clone(); - spawn(move || { - let _timer = prof.verbose_generic_activity("drop_ast"); - drop(krate); - }); - - // 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 }; - hir::Crate { owners, opt_hir_hash } + 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)] @@ -587,6 +586,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) @@ -638,6 +638,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. @@ -672,9 +673,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> { @@ -683,6 +686,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() { @@ -705,7 +709,14 @@ impl<'hir> LoweringContext<'hir> { let delayed_lints = hir::lints::DelayedLints { lints: delayed_lints, opt_hash: delayed_lints_hash }; - 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`. @@ -724,7 +735,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 37b9cfffff3b3..6b9124334eceb 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -211,7 +211,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), } } @@ -261,7 +261,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 ab530d479ba19..f4d354ec6b354 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -18,6 +18,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}; @@ -1559,6 +1560,8 @@ pub struct OwnerInfo<'hir> { /// Lints delayed during ast lowering to be emitted /// after hir has completely built pub delayed_lints: DelayedLints, + /// Owners generated as side-effect by lowering. + pub children: UnordMap>, } impl<'tcx> OwnerInfo<'tcx> { @@ -1572,36 +1575,23 @@ 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")) } } -/// 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> { - pub owners: IndexVec>, - // Only present when incr. comp. is enabled. - pub opt_hir_hash: Option, -} - #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Closure<'hir> { pub def_id: LocalDefId, diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index 16e8bac3d8a4d..0d8fbc7011ea0 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -3,7 +3,7 @@ use rustc_span::def_id::DefPathHash; use crate::HashIgnoredAttrId; use crate::hir::{ - AttributeMap, BodyId, Crate, ForeignItemId, ImplItemId, ItemId, OwnerNodes, TraitItemId, + AttributeMap, BodyId, ForeignItemId, ImplItemId, ItemId, OwnerNodes, TraitItemId, }; use crate::hir_id::ItemLocalId; use crate::lints::DelayedLints; @@ -96,13 +96,6 @@ impl<'tcx, HirCtx: crate::HashStableContext> HashStable for AttributeMap } } -impl HashStable for Crate<'_> { - fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { - let Crate { owners: _, opt_hir_hash } = self; - opt_hir_hash.unwrap().hash_stable(hcx, hasher) - } -} - impl HashStable for HashIgnoredAttrId { fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { hcx.hash_attr_id(self, hasher) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index d4bc2b1dcaf51..e6fd0ce2580b6 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -401,7 +401,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 { @@ -477,7 +476,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { tcx.registered_tools(()), Some(lint_buffer), rustc_lint::BuiltinCombinedEarlyLintPass::new(), - (&**krate, &*krate.attrs), + (krate, &*krate.attrs), ) } @@ -787,7 +786,7 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P fn resolver_for_lowering_raw<'tcx>( tcx: TyCtxt<'tcx>, (): (), -) -> (&'tcx (ty::ResolverAstLowering, Steal>), &'tcx ty::ResolverGlobalCtxt) { +) -> (&'tcx (ty::ResolverAstLowering, 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(); @@ -809,7 +808,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((untracked_resolver_for_lowering, krate)), resolutions) } pub fn write_dep_info(tcx: TyCtxt<'_>) { @@ -867,7 +866,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, @@ -884,7 +882,8 @@ pub fn write_interface<'tcx>(tcx: TyCtxt<'tcx>) { pub static DEFAULT_QUERY_PROVIDERS: LazyLock = LazyLock::new(|| { let providers = &mut Providers::default(); providers.analysis = analysis; - providers.hir_crate = rustc_ast_lowering::lower_to_hir; + providers.index_ast = rustc_ast_lowering::index_ast; + providers.lower_to_hir = rustc_ast_lowering::lower_to_hir; providers.resolver_for_lowering_raw = resolver_for_lowering_raw; providers.stripped_cfg_items = |tcx, _| &tcx.resolutions(()).stripped_cfg_items[..]; providers.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).1; @@ -1037,6 +1036,8 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( /// 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 f40ad79c9c4cd..286fd01c843a7 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -30,10 +30,12 @@ macro_rules! arena_types { [decode] borrowck_result: rustc_middle::mir::DefinitionSiteHiddenTypes<'tcx>, [] resolver: ( rustc_middle::ty::ResolverAstLowering, - rustc_data_structures::steal::Steal< - std::sync::Arc - > + rustc_ast::Crate ), + [] index_ast: rustc_index::IndexVec< + rustc_span::def_id::LocalDefId, + rustc_ast::AstOwner<'tcx> + >, [] 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 430cd329408f5..2125272d90df4 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -1122,11 +1122,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 @@ -1161,7 +1158,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); diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 9e3162785f4b5..1d279f015943d 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -217,19 +217,18 @@ 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(()).owners[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(()).owners.get(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 = |tcx, owner_id| { tcx.opt_local_parent(owner_id.def_id).map_or(CRATE_HIR_ID, |parent_def_id| { let parent_owner_id = tcx.local_def_id_to_hir_id(parent_def_id).owner; HirId { owner: parent_owner_id, - local_id: tcx.hir_crate(()).owners[parent_owner_id.def_id] + local_id: tcx + .lower_to_hir(parent_owner_id) .unwrap() .parenting .get(&owner_id.def_id) @@ -238,11 +237,10 @@ pub fn provide(providers: &mut Providers) { } }) }; - providers.hir_attr_map = |tcx, id| { - tcx.hir_crate(()).owners[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(()).owners[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); @@ -282,7 +280,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(()).owners[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/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index f8fb5766e34ae..fc8657f7e010c 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -82,7 +82,7 @@ use rustc_hir::def_id::{ CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap, LocalDefIdSet, LocalModDefId, }; use rustc_hir::lang_items::{LangItem, LanguageItems}; -use rustc_hir::{Crate, ItemLocalId, ItemLocalMap, PreciseCapturingArgKind, TraitCandidate}; +use rustc_hir::{ItemLocalId, ItemLocalMap, PreciseCapturingArgKind, TraitCandidate}; use rustc_index::IndexVec; use rustc_lint_defs::LintId; use rustc_macros::rustc_queries; @@ -197,12 +197,18 @@ rustc_queries! { desc { "getting the resolver outputs" } } - query resolver_for_lowering_raw(_: ()) -> (&'tcx (ty::ResolverAstLowering, Steal>), &'tcx ty::ResolverGlobalCtxt) { + query resolver_for_lowering_raw(_: ()) -> (&'tcx (ty::ResolverAstLowering, ast::Crate), &'tcx ty::ResolverGlobalCtxt) { eval_always no_hash 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. @@ -214,17 +220,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 + query lower_to_hir(key: LocalDefId) -> hir::MaybeOwner<'tcx> { eval_always - desc { "getting the crate HIR" } + desc { |tcx| "lower HIR for `{}`", tcx.def_path_str(key.to_def_id()) } } /// All items in the crate. diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 9fe17d08464ca..67a1a8d892b46 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -3520,7 +3520,7 @@ impl<'tcx> TyCtxt<'tcx> { self.resolutions(()).extern_crate_map.get(&def_id).copied() } - pub fn resolver_for_lowering(self) -> &'tcx (ty::ResolverAstLowering, Steal>) { + pub fn resolver_for_lowering(self) -> &'tcx (ty::ResolverAstLowering, ast::Crate) { 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 f621dab5b4642..acc0d286fbb2c 100644 --- a/compiler/rustc_passes/src/debugger_visualizer.rs +++ b/compiler/rustc_passes/src/debugger_visualizer.rs @@ -81,7 +81,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 5a10e9cbf5c18..43fb7e8483b69 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -248,7 +248,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 7a9e9af435ca0..13e29097ce423 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/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 5627cb452a815..b21b514f02390 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -601,6 +601,15 @@ LL | #[rustc_layout_scalar_valid_range_end] | expected this to be a list | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]` +error[E0565]: malformed `type_const` attribute input + --> $DIR/malformed-attrs.rs:149:5 + | +LL | #[type_const = 1] + | ^^^^^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[type_const]` + error[E0565]: malformed `marker` attribute input --> $DIR/malformed-attrs.rs:161:1 | @@ -716,15 +725,6 @@ LL | #[allow_internal_unsafe = 1] | | didn't expect any arguments here | help: must be of the form: `#[allow_internal_unsafe]` -error[E0565]: malformed `type_const` attribute input - --> $DIR/malformed-attrs.rs:149:5 - | -LL | #[type_const = 1] - | ^^^^^^^^^^^^^---^ - | | | - | | didn't expect any arguments here - | help: must be of the form: `#[type_const]` - error: attribute should be applied to `const fn` --> $DIR/malformed-attrs.rs:31:1 | From c29ccfb39bf7170f07de42cf5227d64fc9c6fc20 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 22 Jun 2025 15:50:17 +0000 Subject: [PATCH 3/4] Precompute hash for OwnerInfo too. --- compiler/rustc_ast_lowering/src/lib.rs | 21 +++++++++++++-- compiler/rustc_hir/src/hir.rs | 8 +++--- compiler/rustc_hir/src/stable_hash_impls.rs | 26 +++++++++++++------ compiler/rustc_middle/src/hir/mod.rs | 14 +++------- compiler/rustc_middle/src/ty/context.rs | 4 +-- .../src/coverage/hir_info.rs | 2 +- 6 files changed, 48 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 2a065e5b92ae7..bb605771d6066 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -45,6 +45,7 @@ use rustc_ast::visit::{self, Visitor}; use rustc_ast::{self as ast, *}; use rustc_attr_parsing::{AttributeParser, 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}; @@ -700,16 +701,32 @@ 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, delayed_lints_hash } = + let rustc_middle::hir::Hashes { bodies_hash, attrs_hash, delayed_lints_hash } = self.tcx.hash_owner_nodes(node, &bodies, &attrs, &delayed_lints, 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 delayed_lints = hir::lints::DelayedLints { lints: delayed_lints, opt_hash: delayed_lints_hash }; + 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); + delayed_lints_hash.unwrap().hash_stable(&mut hcx, &mut stable_hasher); + 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 f4d354ec6b354..40a7d7e61bf05 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1507,7 +1507,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 @@ -1540,13 +1540,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>, @@ -1562,6 +1562,8 @@ pub struct OwnerInfo<'hir> { 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 0d8fbc7011ea0..f8027451f4c0e 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -3,7 +3,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; use crate::lints::DelayedLints; @@ -69,18 +69,17 @@ impl ToStableHashKey for ForeignItemId // in "DefPath Mode". impl<'tcx, HirCtx: crate::HashStableContext> HashStable for OwnerNodes<'tcx> { + #[inline] fn hash_stable(&self, hcx: &mut HirCtx, 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 HashStable for DelayedLints { + #[inline] fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { let DelayedLints { opt_hash, .. } = *self; opt_hash.unwrap().hash_stable(hcx, hasher); @@ -88,6 +87,7 @@ impl HashStable for DelayedLints { } impl<'tcx, HirCtx: crate::HashStableContext> HashStable for AttributeMap<'tcx> { + #[inline] fn hash_stable(&self, hcx: &mut HirCtx, 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. @@ -96,6 +96,16 @@ impl<'tcx, HirCtx: crate::HashStableContext> HashStable for AttributeMap } } +impl<'tcx, HirCtx: crate::HashStableContext> HashStable for OwnerInfo<'tcx> { + #[inline] + fn hash_stable(&self, hcx: &mut HirCtx, 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 HirCtx, hasher: &mut StableHasher) { hcx.hash_attr_id(self, hasher) diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 1d279f015943d..ecc368fc34907 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -169,11 +169,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, - delayed_lints_hash: None, - }; + return Hashes { bodies_hash: None, attrs_hash: None, delayed_lints_hash: None }; } self.with_stable_hashing_context(|mut hcx| { @@ -196,11 +192,7 @@ impl<'tcx> TyCtxt<'tcx> { delayed_lints.hash_stable(&mut hcx, &mut stable_hasher); let h3 = stable_hasher.finish(); - Hashes { - opt_hash_including_bodies: Some(h1), - attrs_hash: Some(h2), - delayed_lints_hash: Some(h3), - } + Hashes { bodies_hash: Some(h1), attrs_hash: Some(h2), delayed_lints_hash: Some(h3) } }) } } @@ -208,7 +200,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, pub delayed_lints_hash: Option, } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 67a1a8d892b46..03183b1a1aec9 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1493,11 +1493,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 081e2435c051387888ac61dca79165624ad2980d Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 2 Jul 2025 16:49:49 +0000 Subject: [PATCH 4/4] 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 | 167 ++++++++++++++---- 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/query/mod.rs | 5 +- compiler/rustc_middle/src/ty/context.rs | 2 +- .../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, 182 insertions(+), 103 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2320e33bc4bf1..76e67161337e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3399,7 +3399,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 07f8dd96a2985..5059bf0046202 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -4028,14 +4028,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 be8e1d22c9dbf..6858771df862a 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -362,7 +362,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 6ac258155fe94..8a39e420e8056 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 9e74b7c7e2960..b314b34de3fbb 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 0abda20361963..21a867173101a 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -2,7 +2,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_hir as hir; use rustc_hir::attrs::AttributeKind; @@ -436,13 +435,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 57d2440ce25f3..442c0de5fcddd 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -12,7 +12,7 @@ use rustc_middle::span_bug; use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::{DesugaringKind, Ident, Span, Symbol, kw, sym}; -use smallvec::{SmallVec, smallvec}; +use smallvec::SmallVec; use thin_vec::ThinVec; use tracing::instrument; @@ -26,6 +26,7 @@ use super::{ pub(super) struct ItemLowerer<'hir> { pub(super) tcx: TyCtxt<'hir>, pub(super) resolver: &'hir ResolverAstLowering, + 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 @@ -53,7 +54,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()); @@ -102,28 +103,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_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index bb605771d6066..1c777c86f52ad 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -40,12 +40,13 @@ 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, 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}; @@ -64,7 +65,7 @@ use rustc_middle::ty::{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}; @@ -159,7 +160,12 @@ struct LoweringContext<'hir> { } impl<'hir> LoweringContext<'hir> { - fn new(tcx: TyCtxt<'hir>, resolver: &'hir ResolverAstLowering, owner: NodeId) -> Self { + fn new( + tcx: TyCtxt<'hir>, + resolver: &'hir ResolverAstLowering, + 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] }; Self { @@ -181,7 +187,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(), @@ -409,69 +415,152 @@ enum FnDeclKind { Impl, } -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); } } } @@ -484,13 +573,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)) => { @@ -504,6 +593,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 6b9124334eceb..37b9cfffff3b3 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -211,7 +211,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()), } } @@ -261,7 +261,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 e6fd0ce2580b6..f32cc341f2f5b 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -401,6 +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 mut lint_buffer = resolver.lint_buffer.steal(); if sess.opts.unstable_opts.input_stats { @@ -476,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), ) } @@ -786,7 +787,7 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P fn resolver_for_lowering_raw<'tcx>( tcx: TyCtxt<'tcx>, (): (), -) -> (&'tcx (ty::ResolverAstLowering, ast::Crate), &'tcx ty::ResolverGlobalCtxt) { +) -> (&'tcx (ty::ResolverAstLowering, Steal), &'tcx ty::ResolverGlobalCtxt) { let arenas = Resolver::arenas(); let _ = tcx.registered_tools(()); // Uses `crate_for_resolver`. let (krate, pre_configured_attrs) = tcx.crate_for_resolver(()).steal(); @@ -808,7 +809,7 @@ fn resolver_for_lowering_raw<'tcx>( } = resolver.into_outputs(); let resolutions = tcx.arena.alloc(untracked_resolutions); - (tcx.arena.alloc((untracked_resolver_for_lowering, krate)), resolutions) + (tcx.arena.alloc((untracked_resolver_for_lowering, Steal::new(krate))), resolutions) } pub fn write_dep_info(tcx: TyCtxt<'_>) { @@ -868,7 +869,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 286fd01c843a7..659c4c63fc943 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -30,12 +30,14 @@ macro_rules! arena_types { [decode] borrowck_result: rustc_middle::mir::DefinitionSiteHiddenTypes<'tcx>, [] resolver: ( rustc_middle::ty::ResolverAstLowering, - rustc_ast::Crate + rustc_data_structures::steal::Steal + ), + [] index_ast: ( + rustc_index::IndexVec + >, + rustc_ast::NodeId, ), - [] index_ast: rustc_index::IndexVec< - rustc_span::def_id::LocalDefId, - rustc_ast::AstOwner<'tcx> - >, [] 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/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index fc8657f7e010c..4a78766b09e31 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -197,13 +197,14 @@ rustc_queries! { desc { "getting the resolver outputs" } } - query resolver_for_lowering_raw(_: ()) -> (&'tcx (ty::ResolverAstLowering, ast::Crate), &'tcx ty::ResolverGlobalCtxt) { + query resolver_for_lowering_raw(_: ()) -> (&'tcx (ty::ResolverAstLowering, Steal), &'tcx ty::ResolverGlobalCtxt) { eval_always no_hash 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 03183b1a1aec9..87b25a0524610 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -3520,7 +3520,7 @@ impl<'tcx> TyCtxt<'tcx> { self.resolutions(()).extern_crate_map.get(&def_id).copied() } - pub fn resolver_for_lowering(self) -> &'tcx (ty::ResolverAstLowering, ast::Crate) { + pub fn resolver_for_lowering(self) -> &'tcx (ty::ResolverAstLowering, 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 acc0d286fbb2c..58635e121e3a0 100644 --- a/compiler/rustc_passes/src/debugger_visualizer.rs +++ b/compiler/rustc_passes/src/debugger_visualizer.rs @@ -84,7 +84,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 13e29097ce423..7a9e9af435ca0 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/invalid/invalid-rustc_legacy_const_generics-issue-123077.stderr b/tests/ui/invalid/invalid-rustc_legacy_const_generics-issue-123077.stderr index 6f5d719006d8f..111d6d524e5fb 100644 --- a/tests/ui/invalid/invalid-rustc_legacy_const_generics-issue-123077.stderr +++ b/tests/ui/invalid/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