Skip to content

Commit 2a0d1cb

Browse files
committed
Auto merge of #68814 - Aaron1011:fix/proc-macro-order-two, r=petrochenkov
Record proc macro harness order for use during metadata deserialization Fixes #68690 When we generate the proc macro harness, we now explicitly recorder the order in which we generate entries. We then use this ordering data to deserialize the correct proc-macro-data from the crate metadata.
2 parents 8ba3ca0 + 5164598 commit 2a0d1cb

File tree

12 files changed

+84
-34
lines changed

12 files changed

+84
-34
lines changed

src/librustc/hir/map/collector.rs

+1
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
140140
trait_impls: _,
141141
body_ids: _,
142142
modules: _,
143+
proc_macros: _,
143144
} = *krate;
144145

145146
alloc_hir_dep_nodes(

src/librustc_ast_lowering/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
530530
let module = self.lower_mod(&c.module);
531531
let attrs = self.lower_attrs(&c.attrs);
532532
let body_ids = body_ids(&self.bodies);
533+
let proc_macros = c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id]).collect();
533534

534535
self.resolver.definitions().init_node_id_to_hir_id_mapping(self.node_id_to_hir_id);
535536

@@ -546,6 +547,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
546547
body_ids,
547548
trait_impls: self.trait_impls,
548549
modules: self.modules,
550+
proc_macros,
549551
}
550552
}
551553

src/librustc_builtin_macros/proc_macro_harness.rs

+43-18
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ use rustc_span::hygiene::AstPass;
88
use rustc_span::symbol::{kw, sym};
99
use rustc_span::{Span, DUMMY_SP};
1010
use smallvec::smallvec;
11-
use syntax::ast::{self, Ident};
11+
use std::cell::RefCell;
12+
use syntax::ast::{self, Ident, NodeId};
1213
use syntax::attr;
1314
use syntax::expand::is_proc_macro_attr;
1415
use syntax::ptr::P;
1516
use syntax::visit::{self, Visitor};
1617

1718
struct ProcMacroDerive {
19+
id: NodeId,
1820
trait_name: ast::Name,
1921
function_name: Ident,
2022
span: Span,
@@ -27,6 +29,7 @@ enum ProcMacroDefType {
2729
}
2830

2931
struct ProcMacroDef {
32+
id: NodeId,
3033
function_name: Ident,
3134
span: Span,
3235
def_type: ProcMacroDefType,
@@ -69,9 +72,6 @@ pub fn inject(
6972
if has_proc_macro_decls || is_proc_macro_crate {
7073
visit::walk_crate(&mut collect, &krate);
7174
}
72-
// NOTE: If you change the order of macros in this vec
73-
// for any reason, you must also update 'raw_proc_macro'
74-
// in src/librustc_metadata/decoder.rs
7575
let macros = collect.macros;
7676

7777
if !is_proc_macro_crate {
@@ -86,7 +86,8 @@ pub fn inject(
8686
return krate;
8787
}
8888

89-
krate.module.items.push(mk_decls(&mut cx, &macros));
89+
let decls = mk_decls(&mut krate, &mut cx, &macros);
90+
krate.module.items.push(decls);
9091

9192
krate
9293
}
@@ -181,6 +182,7 @@ impl<'a> CollectProcMacros<'a> {
181182

182183
if self.in_root && item.vis.node.is_pub() {
183184
self.macros.push(ProcMacro::Derive(ProcMacroDerive {
185+
id: item.id,
184186
span: item.span,
185187
trait_name: trait_ident.name,
186188
function_name: item.ident,
@@ -200,6 +202,7 @@ impl<'a> CollectProcMacros<'a> {
200202
fn collect_attr_proc_macro(&mut self, item: &'a ast::Item) {
201203
if self.in_root && item.vis.node.is_pub() {
202204
self.macros.push(ProcMacro::Def(ProcMacroDef {
205+
id: item.id,
203206
span: item.span,
204207
function_name: item.ident,
205208
def_type: ProcMacroDefType::Attr,
@@ -218,6 +221,7 @@ impl<'a> CollectProcMacros<'a> {
218221
fn collect_bang_proc_macro(&mut self, item: &'a ast::Item) {
219222
if self.in_root && item.vis.node.is_pub() {
220223
self.macros.push(ProcMacro::Def(ProcMacroDef {
224+
id: item.id,
221225
span: item.span,
222226
function_name: item.ident,
223227
def_type: ProcMacroDefType::Bang,
@@ -357,7 +361,15 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
357361
// // ...
358362
// ];
359363
// }
360-
fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
364+
fn mk_decls(
365+
ast_krate: &mut ast::Crate,
366+
cx: &mut ExtCtxt<'_>,
367+
macros: &[ProcMacro],
368+
) -> P<ast::Item> {
369+
// We're the ones filling in this Vec,
370+
// so it should be empty to start with
371+
assert!(ast_krate.proc_macros.is_empty());
372+
361373
let expn_id = cx.resolver.expansion_for_ast_pass(
362374
DUMMY_SP,
363375
AstPass::ProcMacroHarness,
@@ -376,6 +388,12 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
376388
let attr = cx.ident_of("attr", span);
377389
let bang = cx.ident_of("bang", span);
378390

391+
let krate_ref = RefCell::new(ast_krate);
392+
393+
// We add NodeIds to 'krate.proc_macros' in the order
394+
// that we generate expressions. The position of each NodeId
395+
// in the 'proc_macros' Vec corresponds to its position
396+
// in the static array that will be generated
379397
let decls = {
380398
let local_path =
381399
|sp: Span, name| cx.expr_path(cx.path(sp.with_ctxt(span.ctxt()), vec![name]));
@@ -385,19 +403,26 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
385403
macros
386404
.iter()
387405
.map(|m| match m {
388-
ProcMacro::Derive(cd) => cx.expr_call(
389-
span,
390-
proc_macro_ty_method_path(custom_derive),
391-
vec![
392-
cx.expr_str(cd.span, cd.trait_name),
393-
cx.expr_vec_slice(
394-
span,
395-
cd.attrs.iter().map(|&s| cx.expr_str(cd.span, s)).collect::<Vec<_>>(),
396-
),
397-
local_path(cd.span, cd.function_name),
398-
],
399-
),
406+
ProcMacro::Derive(cd) => {
407+
krate_ref.borrow_mut().proc_macros.push(cd.id);
408+
cx.expr_call(
409+
span,
410+
proc_macro_ty_method_path(custom_derive),
411+
vec![
412+
cx.expr_str(cd.span, cd.trait_name),
413+
cx.expr_vec_slice(
414+
span,
415+
cd.attrs
416+
.iter()
417+
.map(|&s| cx.expr_str(cd.span, s))
418+
.collect::<Vec<_>>(),
419+
),
420+
local_path(cd.span, cd.function_name),
421+
],
422+
)
423+
}
400424
ProcMacro::Def(ca) => {
425+
krate_ref.borrow_mut().proc_macros.push(ca.id);
401426
let ident = match ca.def_type {
402427
ProcMacroDefType::Attr => attr,
403428
ProcMacroDefType::Bang => bang,

src/librustc_hir/hir.rs

+3
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,9 @@ pub struct Crate<'hir> {
635635
/// A list of modules written out in the order in which they
636636
/// appear in the crate. This includes the main crate module.
637637
pub modules: BTreeMap<HirId, ModuleItems>,
638+
/// A list of proc macro HirIds, written out in the order in which
639+
/// they are declared in the static array generated by proc_macro_harness.
640+
pub proc_macros: Vec<HirId>,
638641
}
639642

640643
impl Crate<'hir> {

src/librustc_metadata/rmeta/decoder.rs

-4
Original file line numberDiff line numberDiff line change
@@ -637,10 +637,6 @@ impl<'a, 'tcx> CrateMetadata {
637637
fn raw_proc_macro(&self, id: DefIndex) -> &ProcMacro {
638638
// DefIndex's in root.proc_macro_data have a one-to-one correspondence
639639
// with items in 'raw_proc_macros'.
640-
// NOTE: If you update the order of macros in 'proc_macro_data' for any reason,
641-
// you must also update src/librustc_builtin_macros/proc_macro_harness.rs
642-
// Failing to do so will result in incorrect data being associated
643-
// with proc macros when deserialized.
644640
let pos = self.root.proc_macro_data.unwrap().decode(self).position(|i| i == id).unwrap();
645641
&self.raw_proc_macros.unwrap()[pos]
646642
}

src/librustc_metadata/rmeta/encoder.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ use std::path::Path;
3434
use std::u32;
3535
use syntax::ast;
3636
use syntax::attr;
37-
use syntax::expand::is_proc_macro_attr;
3837

3938
use rustc_hir as hir;
4039
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
@@ -1328,13 +1327,7 @@ impl EncodeContext<'tcx> {
13281327
let is_proc_macro = self.tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro);
13291328
if is_proc_macro {
13301329
let tcx = self.tcx;
1331-
Some(self.lazy(tcx.hir().krate().items.values().filter_map(|item| {
1332-
if item.attrs.iter().any(|attr| is_proc_macro_attr(attr)) {
1333-
Some(item.hir_id.owner)
1334-
} else {
1335-
None
1336-
}
1337-
})))
1330+
Some(self.lazy(tcx.hir().krate().proc_macros.iter().map(|p| p.owner)))
13381331
} else {
13391332
None
13401333
}

src/librustc_parse/parser/module.rs

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ impl<'a> Parser<'a> {
3535
attrs: self.parse_inner_attributes()?,
3636
module: self.parse_mod_items(&token::Eof, lo)?,
3737
span: lo.to(self.token.span),
38+
// Filled in by proc_macro_harness::inject()
39+
proc_macros: Vec::new(),
3840
});
3941
krate
4042
}

src/libsyntax/ast.rs

+7
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,13 @@ pub struct Crate {
429429
pub module: Mod,
430430
pub attrs: Vec<Attribute>,
431431
pub span: Span,
432+
/// The order of items in the HIR is unrelated to the order of
433+
/// items in the AST. However, we generate proc macro harnesses
434+
/// based on the AST order, and later refer to these harnesses
435+
/// from the HIR. This field keeps track of the order in which
436+
/// we generated proc macros harnesses, so that we can map
437+
/// HIR proc macros items back to their harness items.
438+
pub proc_macros: Vec<NodeId>,
432439
}
433440

434441
/// Possible values inside of compile-time attribute lists.

src/libsyntax/mut_visit.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -989,7 +989,7 @@ pub fn noop_visit_mod<T: MutVisitor>(Mod { inner, items, inline: _ }: &mut Mod,
989989
}
990990

991991
pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) {
992-
visit_clobber(krate, |Crate { module, attrs, span }| {
992+
visit_clobber(krate, |Crate { module, attrs, span, proc_macros }| {
993993
let item = P(Item {
994994
ident: Ident::invalid(),
995995
attrs,
@@ -1004,11 +1004,11 @@ pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) {
10041004
let len = items.len();
10051005
if len == 0 {
10061006
let module = Mod { inner: span, items: vec![], inline: true };
1007-
Crate { module, attrs: vec![], span }
1007+
Crate { module, attrs: vec![], span, proc_macros }
10081008
} else if len == 1 {
10091009
let Item { attrs, span, kind, .. } = items.into_iter().next().unwrap().into_inner();
10101010
match kind {
1011-
ItemKind::Mod(module) => Crate { module, attrs, span },
1011+
ItemKind::Mod(module) => Crate { module, attrs, span, proc_macros },
10121012
_ => panic!("visitor converted a module to not a module"),
10131013
}
10141014
} else {

src/test/rustdoc/inline_cross/auxiliary/proc_macro.rs

+13
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@ extern crate proc_macro;
99

1010
use proc_macro::TokenStream;
1111

12+
macro_rules! make_attr_macro {
13+
($name:ident) => {
14+
/// Generated doc comment
15+
#[proc_macro_attribute]
16+
pub fn $name(args: TokenStream, input: TokenStream) -> TokenStream {
17+
panic!()
18+
}
19+
}
20+
}
21+
22+
make_attr_macro!(first_attr);
23+
make_attr_macro!(second_attr);
24+
1225
/// a proc-macro that swallows its input and does nothing.
1326
#[proc_macro]
1427
pub fn some_proc_macro(_input: TokenStream) -> TokenStream {

src/test/rustdoc/inline_cross/proc_macro.rs

+8
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,11 @@ pub use some_macros::some_proc_attr;
2626
// @has proc_macro/derive.SomeDerive.html
2727
// @has - 'a derive attribute that adds nothing to its input.'
2828
pub use some_macros::SomeDerive;
29+
30+
// @has proc_macro/attr.first_attr.html
31+
// @has - 'Generated doc comment'
32+
pub use some_macros::first_attr;
33+
34+
// @has proc_macro/attr.second_attr.html
35+
// @has - 'Generated doc comment'
36+
pub use some_macros::second_attr;
+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"module":{"inner":{"lo":0,"hi":0},"items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":{"_field0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["extern",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["core",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":"Semi","span":{"lo":0,"hi":0}}]},"NonJoint"]]}}],"inline":true},"attrs":[],"span":{"lo":0,"hi":0}}
1+
{"module":{"inner":{"lo":0,"hi":0},"items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":{"_field0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["extern",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["core",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":"Semi","span":{"lo":0,"hi":0}}]},"NonJoint"]]}}],"inline":true},"attrs":[],"span":{"lo":0,"hi":0},"proc_macros":[]}

0 commit comments

Comments
 (0)