From f8efe5d8222db70964f46b6523be81d6e7c38e65 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 16 Jul 2021 22:22:08 +0200 Subject: [PATCH] Compute proc_macros in resolutions. --- compiler/rustc_ast/src/ast.rs | 7 ---- compiler/rustc_ast/src/mut_visit.rs | 8 ++--- compiler/rustc_ast_lowering/src/lib.rs | 4 --- .../src/proc_macro_harness.rs | 36 +++++++------------ compiler/rustc_expand/src/base.rs | 8 +++++ compiler/rustc_hir/src/hir.rs | 3 -- compiler/rustc_interface/src/passes.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 20 ++++++----- compiler/rustc_middle/src/ty/mod.rs | 3 ++ compiler/rustc_parse/src/parser/item.rs | 3 +- compiler/rustc_resolve/src/lib.rs | 8 +++++ compiler/rustc_resolve/src/macros.rs | 4 +++ 12 files changed, 52 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 0632d937c4c..443698a796d 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -502,13 +502,6 @@ pub struct Crate { pub attrs: Vec, pub items: Vec>, pub span: Span, - /// The order of items in the HIR is unrelated to the order of - /// items in the AST. However, we generate proc macro harnesses - /// based on the AST order, and later refer to these harnesses - /// from the HIR. This field keeps track of the order in which - /// we generated proc macros harnesses, so that we can map - /// HIR proc macros items back to their harness items. - pub proc_macros: Vec, } /// Possible values inside of compile-time attribute lists. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 368a23e3429..b7e446a8bee 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1059,7 +1059,7 @@ pub fn noop_visit_fn_header(header: &mut FnHeader, vis: &mut T) { // FIXME: Avoid visiting the crate as a `Mod` item, flat map only the inner items if possible, // or make crate visiting first class if necessary. pub fn noop_visit_crate(krate: &mut Crate, vis: &mut T) { - visit_clobber(krate, |Crate { attrs, items, span, proc_macros }| { + visit_clobber(krate, |Crate { attrs, items, span }| { let item_vis = Visibility { kind: VisibilityKind::Public, span: span.shrink_to_lo(), tokens: None }; let item = P(Item { @@ -1075,13 +1075,11 @@ pub fn noop_visit_crate(krate: &mut Crate, vis: &mut T) { let len = items.len(); if len == 0 { - Crate { attrs: vec![], items: vec![], span, proc_macros } + Crate { attrs: vec![], items: vec![], span } } else if len == 1 { let Item { attrs, span, kind, .. } = items.into_iter().next().unwrap().into_inner(); match kind { - ItemKind::Mod(_, ModKind::Loaded(items, ..)) => { - Crate { attrs, items, span, proc_macros } - } + ItemKind::Mod(_, ModKind::Loaded(items, ..)) => Crate { attrs, items, span }, _ => panic!("visitor converted a module to not a module"), } } else { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 7a26aa5c3d6..f8d366fdee7 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -474,9 +474,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.owners.ensure_contains_elem(CRATE_DEF_ID, || None); self.owners[CRATE_DEF_ID] = Some(hir::OwnerNode::Crate(module)); - let proc_macros = - c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id].unwrap()).collect(); - let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default(); for (k, v) in self.resolver.take_trait_map().into_iter() { if let Some(Some(hir_id)) = self.node_id_to_hir_id.get(k) { @@ -510,7 +507,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { owners: self.owners, bodies: self.bodies, modules: self.modules, - proc_macros, trait_map, attrs: self.attrs, }; diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index 7971c1fff42..6f61e4cba07 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -13,7 +13,6 @@ use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use smallvec::smallvec; -use std::cell::RefCell; struct ProcMacroDerive { id: NodeId, @@ -90,7 +89,7 @@ pub fn inject( return krate; } - let decls = mk_decls(&mut krate, &mut cx, ¯os); + let decls = mk_decls(&mut cx, ¯os); krate.items.push(decls); krate @@ -289,15 +288,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { // // ... // ]; // } -fn mk_decls( - ast_krate: &mut ast::Crate, - cx: &mut ExtCtxt<'_>, - macros: &[ProcMacro], -) -> P { - // We're the ones filling in this Vec, - // so it should be empty to start with - assert!(ast_krate.proc_macros.is_empty()); - +fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P { let expn_id = cx.resolver.expansion_for_ast_pass( DUMMY_SP, AstPass::ProcMacroHarness, @@ -316,26 +307,25 @@ fn mk_decls( let attr = Ident::new(sym::attr, span); let bang = Ident::new(sym::bang, span); - let krate_ref = RefCell::new(ast_krate); - - // We add NodeIds to 'krate.proc_macros' in the order + // We add NodeIds to 'resolver.proc_macros' in the order // that we generate expressions. The position of each NodeId // in the 'proc_macros' Vec corresponds to its position // in the static array that will be generated let decls = { - let local_path = - |sp: Span, name| cx.expr_path(cx.path(sp.with_ctxt(span.ctxt()), vec![name])); - let proc_macro_ty_method_path = |method| { + let local_path = |cx: &ExtCtxt<'_>, sp: Span, name| { + cx.expr_path(cx.path(sp.with_ctxt(span.ctxt()), vec![name])) + }; + let proc_macro_ty_method_path = |cx: &ExtCtxt<'_>, method| { cx.expr_path(cx.path(span, vec![proc_macro, bridge, client, proc_macro_ty, method])) }; macros .iter() .map(|m| match m { ProcMacro::Derive(cd) => { - krate_ref.borrow_mut().proc_macros.push(cd.id); + cx.resolver.declare_proc_macro(cd.id); cx.expr_call( span, - proc_macro_ty_method_path(custom_derive), + proc_macro_ty_method_path(cx, custom_derive), vec![ cx.expr_str(cd.span, cd.trait_name), cx.expr_vec_slice( @@ -345,12 +335,12 @@ fn mk_decls( .map(|&s| cx.expr_str(cd.span, s)) .collect::>(), ), - local_path(cd.span, cd.function_name), + local_path(cx, cd.span, cd.function_name), ], ) } ProcMacro::Def(ca) => { - krate_ref.borrow_mut().proc_macros.push(ca.id); + cx.resolver.declare_proc_macro(ca.id); let ident = match ca.def_type { ProcMacroDefType::Attr => attr, ProcMacroDefType::Bang => bang, @@ -358,10 +348,10 @@ fn mk_decls( cx.expr_call( span, - proc_macro_ty_method_path(ident), + proc_macro_ty_method_path(cx, ident), vec![ cx.expr_str(ca.span, ca.function_name.name), - local_path(ca.span, ca.function_name), + local_path(cx, ca.span, ca.function_name), ], ) } diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index a4b7bdd9155..ebf168d7de7 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -894,6 +894,14 @@ pub trait ResolverExpand { /// Decodes the proc-macro quoted span in the specified crate, with the specified id. /// No caching is performed. fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span; + + /// The order of items in the HIR is unrelated to the order of + /// items in the AST. However, we generate proc macro harnesses + /// based on the AST order, and later refer to these harnesses + /// from the HIR. This field keeps track of the order in which + /// we generated proc macros harnesses, so that we can map + /// HIR proc macros items back to their harness items. + fn declare_proc_macro(&mut self, id: NodeId); } #[derive(Clone, Default)] diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 489b2848b09..a43ef9bb1a0 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -676,9 +676,6 @@ pub struct Crate<'hir> { /// A list of modules written out in the order in which they /// appear in the crate. This includes the main crate module. pub modules: BTreeMap, - /// A list of proc macro HirIds, written out in the order in which - /// they are declared in the static array generated by proc_macro_harness. - pub proc_macros: Vec, /// Map indicating what traits are in scope for places where this /// is relevant; generated by resolve. diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 5dc57f6023b..7127ec57c08 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -324,7 +324,7 @@ pub fn configure_and_expand( }; let extern_mod_loaded = |ident: Ident, attrs, items, span| { - let krate = ast::Crate { attrs, items, span, proc_macros: vec![] }; + let krate = ast::Crate { attrs, items, span }; pre_expansion_lint(sess, lint_store, &krate, &ident.name.as_str()); (krate.attrs, krate.items) }; diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 2cd4fe3b706..d8b9a479976 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -454,7 +454,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let table = self.tcx.resolutions(()).definitions.def_path_table(); if self.is_proc_macro { for def_index in std::iter::once(CRATE_DEF_INDEX) - .chain(self.tcx.hir().krate().proc_macros.iter().map(|p| p.owner.local_def_index)) + .chain(self.tcx.resolutions(()).proc_macros.iter().map(|p| p.local_def_index)) { let def_key = self.lazy(table.def_key(def_index)); let def_path_hash = self.lazy(table.def_path_hash(def_index)); @@ -1630,7 +1630,8 @@ impl EncodeContext<'a, 'tcx> { let proc_macro_decls_static = tcx.proc_macro_decls_static(()).unwrap().local_def_index; let stability = tcx.lookup_stability(DefId::local(CRATE_DEF_INDEX)).copied(); - let macros = self.lazy(hir.krate().proc_macros.iter().map(|p| p.owner.local_def_index)); + let macros = + self.lazy(tcx.resolutions(()).proc_macros.iter().map(|p| p.local_def_index)); let spans = self.tcx.sess.parse_sess.proc_macro_quoted_spans(); for (i, span) in spans.into_iter().enumerate() { let span = self.lazy(span); @@ -1649,13 +1650,14 @@ impl EncodeContext<'a, 'tcx> { // Normally, this information is encoded when we walk the items // defined in this crate. However, we skip doing that for proc-macro crates, // so we manually encode just the information that we need - for proc_macro in &hir.krate().proc_macros { - let id = proc_macro.owner.local_def_index; - let mut name = hir.name(*proc_macro); - let span = hir.span(*proc_macro); + for &proc_macro in &tcx.resolutions(()).proc_macros { + let id = proc_macro; + let proc_macro = hir.local_def_id_to_hir_id(proc_macro); + let mut name = hir.name(proc_macro); + let span = hir.span(proc_macro); // Proc-macros may have attributes like `#[allow_internal_unstable]`, // so downstream crates need access to them. - let attrs = hir.attrs(*proc_macro); + let attrs = hir.attrs(proc_macro); let macro_kind = if tcx.sess.contains_name(attrs, sym::proc_macro) { MacroKind::Bang } else if tcx.sess.contains_name(attrs, sym::proc_macro_attribute) { @@ -1673,10 +1675,10 @@ impl EncodeContext<'a, 'tcx> { bug!("Unknown proc-macro type for item {:?}", id); }; - let mut def_key = self.tcx.hir().def_key(proc_macro.owner); + let mut def_key = self.tcx.hir().def_key(id); def_key.disambiguated_data.data = DefPathData::MacroNs(name); - let def_id = DefId::local(id); + let def_id = id.to_def_id(); record!(self.tables.def_kind[def_id] <- DefKind::Macro(macro_kind)); record!(self.tables.kind[def_id] <- EntryKind::ProcMacro(macro_kind)); record!(self.tables.attributes[def_id] <- attrs); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6ff1215b149..d01ca27b851 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -134,6 +134,9 @@ pub struct ResolverOutputs { pub extern_prelude: FxHashMap, pub main_def: Option, pub trait_impls: BTreeMap>, + /// A list of proc macro LocalDefIds, written out in the order in which + /// they are declared in the static array generated by proc_macro_harness. + pub proc_macros: Vec, } #[derive(Clone, Copy, Debug)] diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index e5537d43eba..10c73fd64bc 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -26,8 +26,7 @@ impl<'a> Parser<'a> { /// Parses a source module as a crate. This is the main entry point for the parser. pub fn parse_crate_mod(&mut self) -> PResult<'a, ast::Crate> { let (attrs, items, span) = self.parse_mod(&token::Eof)?; - let proc_macros = Vec::new(); // Filled in by `proc_macro_harness::inject()`. - Ok(ast::Crate { attrs, items, span, proc_macros }) + Ok(ast::Crate { attrs, items, span }) } /// Parses a `mod { ... }` or `mod ;` item. diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 51e0ee0a57f..152d34fd635 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1035,6 +1035,9 @@ pub struct Resolver<'a> { main_def: Option, trait_impls: BTreeMap>, + /// A list of proc macro LocalDefIds, written out in the order in which + /// they are declared in the static array generated by proc_macro_harness. + proc_macros: Vec, } /// Nothing really interesting here; it just provides memory for the rest of the crate. @@ -1400,6 +1403,7 @@ impl<'a> Resolver<'a> { item_generics_num_lifetimes: Default::default(), main_def: Default::default(), trait_impls: Default::default(), + proc_macros: Default::default(), }; let root_parent_scope = ParentScope::module(graph_root, &resolver); @@ -1434,6 +1438,7 @@ impl<'a> Resolver<'a> { } pub fn into_outputs(self) -> ResolverOutputs { + let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect(); let definitions = self.definitions; let visibilities = self.visibilities; let extern_crate_map = self.extern_crate_map; @@ -1458,10 +1463,12 @@ impl<'a> Resolver<'a> { .collect(), main_def, trait_impls: self.trait_impls, + proc_macros, } } pub fn clone_outputs(&self) -> ResolverOutputs { + let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect(); ResolverOutputs { definitions: self.definitions.clone(), cstore: Box::new(self.cstore().clone()), @@ -1478,6 +1485,7 @@ impl<'a> Resolver<'a> { .collect(), main_def: self.main_def.clone(), trait_impls: self.trait_impls.clone(), + proc_macros, } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 7f86f891c44..6dc3aa0888a 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -466,6 +466,10 @@ impl<'a> ResolverExpand for Resolver<'a> { fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span { self.crate_loader.cstore().get_proc_macro_quoted_span_untracked(krate, id, self.session) } + + fn declare_proc_macro(&mut self, id: NodeId) { + self.proc_macros.push(id) + } } impl<'a> Resolver<'a> {