Skip to content

Commit 76d34f3

Browse files
authored
Rollup merge of #64528 - Aaron1011:fix/proc-macro-type, r=alexcrichton
Load proc macro metadata in the correct order. Serialized proc macro metadata is assumed to have a one-to-one correspondence with the entries in static array generated by proc_macro_harness. However, we were previously serializing proc macro metadata in a different order than proc macros were laied out in the static array. This lead to us associating the wrong data with a proc macro when generating documentation, causing Rustdoc to generate incorrect docs for proc macros. This commit keeps track of the order in which we insert proc macros into the generated static array. We use this same order when serializing proc macro metadata, ensuring that we can later associate the metadata for a proc macro with its entry in the static array. Fixes #64251
2 parents b2501a1 + 3daa8bd commit 76d34f3

File tree

3 files changed

+79
-49
lines changed

3 files changed

+79
-49
lines changed

src/librustc_metadata/decoder.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,11 @@ impl<'a, 'tcx> CrateMetadata {
489489

490490
fn raw_proc_macro(&self, id: DefIndex) -> &ProcMacro {
491491
// DefIndex's in root.proc_macro_data have a one-to-one correspondence
492-
// with items in 'raw_proc_macros'
492+
// with items in 'raw_proc_macros'.
493+
// NOTE: If you update the order of macros in 'proc_macro_data' for any reason,
494+
// you must also update src/libsyntax_ext/proc_macro_harness.rs
495+
// Failing to do so will result in incorrect data being associated
496+
// with proc macros when deserialized.
493497
let pos = self.root.proc_macro_data.unwrap().decode(self).position(|i| i == id).unwrap();
494498
&self.raw_proc_macros.unwrap()[pos]
495499
}

src/libsyntax_ext/proc_macro_harness.rs

+62-47
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,24 @@ struct ProcMacroDerive {
2020
attrs: Vec<ast::Name>,
2121
}
2222

23+
enum ProcMacroDefType {
24+
Attr,
25+
Bang
26+
}
27+
2328
struct ProcMacroDef {
2429
function_name: Ident,
2530
span: Span,
31+
def_type: ProcMacroDefType
32+
}
33+
34+
enum ProcMacro {
35+
Derive(ProcMacroDerive),
36+
Def(ProcMacroDef)
2637
}
2738

2839
struct CollectProcMacros<'a> {
29-
derives: Vec<ProcMacroDerive>,
30-
attr_macros: Vec<ProcMacroDef>,
31-
bang_macros: Vec<ProcMacroDef>,
40+
macros: Vec<ProcMacro>,
3241
in_root: bool,
3342
handler: &'a errors::Handler,
3443
is_proc_macro_crate: bool,
@@ -46,22 +55,22 @@ pub fn inject(sess: &ParseSess,
4655
let ecfg = ExpansionConfig::default("proc_macro".to_string());
4756
let mut cx = ExtCtxt::new(sess, ecfg, resolver);
4857

49-
let (derives, attr_macros, bang_macros) = {
50-
let mut collect = CollectProcMacros {
51-
derives: Vec::new(),
52-
attr_macros: Vec::new(),
53-
bang_macros: Vec::new(),
54-
in_root: true,
55-
handler,
56-
is_proc_macro_crate,
57-
is_test_crate,
58-
};
59-
if has_proc_macro_decls || is_proc_macro_crate {
60-
visit::walk_crate(&mut collect, &krate);
61-
}
62-
(collect.derives, collect.attr_macros, collect.bang_macros)
58+
let mut collect = CollectProcMacros {
59+
macros: Vec::new(),
60+
in_root: true,
61+
handler,
62+
is_proc_macro_crate,
63+
is_test_crate,
6364
};
6465

66+
if has_proc_macro_decls || is_proc_macro_crate {
67+
visit::walk_crate(&mut collect, &krate);
68+
}
69+
// NOTE: If you change the order of macros in this vec
70+
// for any reason, you must also update 'raw_proc_macro'
71+
// in src/librustc_metadata/decoder.rs
72+
let macros = collect.macros;
73+
6574
if !is_proc_macro_crate {
6675
return krate
6776
}
@@ -74,7 +83,7 @@ pub fn inject(sess: &ParseSess,
7483
return krate;
7584
}
7685

77-
krate.module.items.push(mk_decls(&mut cx, &derives, &attr_macros, &bang_macros));
86+
krate.module.items.push(mk_decls(&mut cx, &macros));
7887

7988
krate
8089
}
@@ -161,12 +170,12 @@ impl<'a> CollectProcMacros<'a> {
161170
};
162171

163172
if self.in_root && item.vis.node.is_pub() {
164-
self.derives.push(ProcMacroDerive {
173+
self.macros.push(ProcMacro::Derive(ProcMacroDerive {
165174
span: item.span,
166175
trait_name: trait_ident.name,
167176
function_name: item.ident,
168177
attrs: proc_attrs,
169-
});
178+
}));
170179
} else {
171180
let msg = if !self.in_root {
172181
"functions tagged with `#[proc_macro_derive]` must \
@@ -180,10 +189,11 @@ impl<'a> CollectProcMacros<'a> {
180189

181190
fn collect_attr_proc_macro(&mut self, item: &'a ast::Item) {
182191
if self.in_root && item.vis.node.is_pub() {
183-
self.attr_macros.push(ProcMacroDef {
192+
self.macros.push(ProcMacro::Def(ProcMacroDef {
184193
span: item.span,
185194
function_name: item.ident,
186-
});
195+
def_type: ProcMacroDefType::Attr
196+
}));
187197
} else {
188198
let msg = if !self.in_root {
189199
"functions tagged with `#[proc_macro_attribute]` must \
@@ -197,10 +207,11 @@ impl<'a> CollectProcMacros<'a> {
197207

198208
fn collect_bang_proc_macro(&mut self, item: &'a ast::Item) {
199209
if self.in_root && item.vis.node.is_pub() {
200-
self.bang_macros.push(ProcMacroDef {
210+
self.macros.push(ProcMacro::Def(ProcMacroDef {
201211
span: item.span,
202212
function_name: item.ident,
203-
});
213+
def_type: ProcMacroDefType::Bang
214+
}));
204215
} else {
205216
let msg = if !self.in_root {
206217
"functions tagged with `#[proc_macro]` must \
@@ -322,9 +333,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
322333
// }
323334
fn mk_decls(
324335
cx: &mut ExtCtxt<'_>,
325-
custom_derives: &[ProcMacroDerive],
326-
custom_attrs: &[ProcMacroDef],
327-
custom_macros: &[ProcMacroDef],
336+
macros: &[ProcMacro],
328337
) -> P<ast::Item> {
329338
let expn_id = cx.resolver.expansion_for_ast_pass(
330339
DUMMY_SP,
@@ -354,26 +363,32 @@ fn mk_decls(
354363
let proc_macro_ty_method_path = |method| cx.expr_path(cx.path(span, vec![
355364
proc_macro, bridge, client, proc_macro_ty, method,
356365
]));
357-
custom_derives.iter().map(|cd| {
358-
cx.expr_call(span, proc_macro_ty_method_path(custom_derive), vec![
359-
cx.expr_str(cd.span, cd.trait_name),
360-
cx.expr_vec_slice(
361-
span,
362-
cd.attrs.iter().map(|&s| cx.expr_str(cd.span, s)).collect::<Vec<_>>()
363-
),
364-
local_path(cd.span, cd.function_name),
365-
])
366-
}).chain(custom_attrs.iter().map(|ca| {
367-
cx.expr_call(span, proc_macro_ty_method_path(attr), vec![
368-
cx.expr_str(ca.span, ca.function_name.name),
369-
local_path(ca.span, ca.function_name),
370-
])
371-
})).chain(custom_macros.iter().map(|cm| {
372-
cx.expr_call(span, proc_macro_ty_method_path(bang), vec![
373-
cx.expr_str(cm.span, cm.function_name.name),
374-
local_path(cm.span, cm.function_name),
375-
])
376-
})).collect()
366+
macros.iter().map(|m| {
367+
match m {
368+
ProcMacro::Derive(cd) => {
369+
cx.expr_call(span, proc_macro_ty_method_path(custom_derive), vec![
370+
cx.expr_str(cd.span, cd.trait_name),
371+
cx.expr_vec_slice(
372+
span,
373+
cd.attrs.iter().map(|&s| cx.expr_str(cd.span, s)).collect::<Vec<_>>()
374+
),
375+
local_path(cd.span, cd.function_name),
376+
])
377+
},
378+
ProcMacro::Def(ca) => {
379+
let ident = match ca.def_type {
380+
ProcMacroDefType::Attr => attr,
381+
ProcMacroDefType::Bang => bang
382+
};
383+
384+
cx.expr_call(span, proc_macro_ty_method_path(ident), vec![
385+
cx.expr_str(ca.span, ca.function_name.name),
386+
local_path(ca.span, ca.function_name),
387+
])
388+
389+
}
390+
}
391+
}).collect()
377392
};
378393

379394
let decls_static = cx.item_static(

src/test/rustdoc/inline_cross/proc_macro.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,19 @@ extern crate some_macros;
1010
// @has proc_macro/macro.some_proc_macro.html
1111
// @has proc_macro/attr.some_proc_attr.html
1212
// @has proc_macro/derive.SomeDerive.html
13-
pub use some_macros::{some_proc_macro, some_proc_attr, SomeDerive};
13+
14+
// @has proc_macro/macro.some_proc_macro.html
15+
// @has - 'a proc-macro that swallows its input and does nothing.'
16+
pub use some_macros::some_proc_macro;
1417

1518
// @has proc_macro/macro.reexported_macro.html
1619
// @has - 'Doc comment from the original crate'
1720
pub use some_macros::reexported_macro;
21+
22+
// @has proc_macro/attr.some_proc_attr.html
23+
// @has - 'a proc-macro attribute that passes its item through verbatim.'
24+
pub use some_macros::some_proc_attr;
25+
26+
// @has proc_macro/derive.SomeDerive.html
27+
// @has - 'a derive attribute that adds nothing to its input.'
28+
pub use some_macros::SomeDerive;

0 commit comments

Comments
 (0)