@@ -8,13 +8,15 @@ use rustc_span::hygiene::AstPass;
88use rustc_span::symbol::{kw, sym};
99use rustc_span::{Span, DUMMY_SP};
1010use smallvec::smallvec;
11- use syntax::ast::{self, Ident};
11+ use std::cell::RefCell;
12+ use syntax::ast::{self, Ident, NodeId};
1213use syntax::attr;
1314use syntax::expand::is_proc_macro_attr;
1415use syntax::ptr::P;
1516use syntax::visit::{self, Visitor};
1617
1718struct ProcMacroDerive {
19+ id: NodeId,
1820 trait_name: ast::Name,
1921 function_name: Ident,
2022 span: Span,
@@ -27,6 +29,7 @@ enum ProcMacroDefType {
2729}
2830
2931struct 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, ¯os));
89+ let decls = mk_decls(&mut krate, &mut cx, ¯os);
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,
0 commit comments