Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 73d7719

Browse files
committedAug 16, 2019
Serialize additional data for procedural macros
Split off from #62855 This PR deerializes the declaration `Span` and attributes for all procedural macros from their underlying function definitions. This allows Rustdoc to properly render doc comments and source links when inlining procedural macros across crates
1 parent bdfd698 commit 73d7719

17 files changed

+238
-212
lines changed
 

‎src/libproc_macro/bridge/client.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,14 @@ pub enum ProcMacro {
468468
}
469469

470470
impl ProcMacro {
471+
pub fn name(&self) -> &'static str {
472+
match self {
473+
ProcMacro::CustomDerive { trait_name, .. } => trait_name,
474+
ProcMacro::Attr { name, .. } => name,
475+
ProcMacro::Bang { name, ..} => name
476+
}
477+
}
478+
471479
pub const fn custom_derive(
472480
trait_name: &'static str,
473481
attributes: &'static [&'static str],

‎src/librustc/hir/def_id.rs

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::ty::{self, TyCtxt};
2-
use crate::hir::map::definitions::FIRST_FREE_DEF_INDEX;
32
use rustc_data_structures::indexed_vec::Idx;
43
use std::fmt;
54
use std::u32;
@@ -102,31 +101,6 @@ newtype_index! {
102101
}
103102
}
104103

105-
impl DefIndex {
106-
// Proc macros from a proc-macro crate have a kind of virtual DefIndex. This
107-
// function maps the index of the macro within the crate (which is also the
108-
// index of the macro in the CrateMetadata::proc_macros array) to the
109-
// corresponding DefIndex.
110-
pub fn from_proc_macro_index(proc_macro_index: usize) -> DefIndex {
111-
// DefIndex for proc macros start from FIRST_FREE_DEF_INDEX,
112-
// because the first FIRST_FREE_DEF_INDEX indexes are reserved
113-
// for internal use.
114-
let def_index = DefIndex::from(
115-
proc_macro_index.checked_add(FIRST_FREE_DEF_INDEX)
116-
.expect("integer overflow adding `proc_macro_index`"));
117-
assert!(def_index != CRATE_DEF_INDEX);
118-
def_index
119-
}
120-
121-
// This function is the reverse of from_proc_macro_index() above.
122-
pub fn to_proc_macro_index(self: DefIndex) -> usize {
123-
self.index().checked_sub(FIRST_FREE_DEF_INDEX)
124-
.unwrap_or_else(|| {
125-
bug!("using local index {:?} as proc-macro index", self)
126-
})
127-
}
128-
}
129-
130104
impl rustc_serialize::UseSpecializedEncodable for DefIndex {}
131105
impl rustc_serialize::UseSpecializedDecodable for DefIndex {}
132106

‎src/librustc/hir/map/definitions.rs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -411,10 +411,6 @@ impl Definitions {
411411
}
412412

413413
/// Adds a root definition (no parent) and a few other reserved definitions.
414-
///
415-
/// After the initial definitions are created the first `FIRST_FREE_DEF_INDEX` indexes
416-
/// are taken, so the "user" indexes will be allocated starting with `FIRST_FREE_DEF_INDEX`
417-
/// in ascending order.
418414
pub fn create_root_def(&mut self,
419415
crate_name: &str,
420416
crate_disambiguator: CrateDisambiguator)
@@ -589,19 +585,6 @@ impl DefPathData {
589585
}
590586
}
591587

592-
/// Evaluates to the number of tokens passed to it.
593-
///
594-
/// Logarithmic counting: every one or two recursive expansions, the number of
595-
/// tokens to count is divided by two, instead of being reduced by one.
596-
/// Therefore, the recursion depth is the binary logarithm of the number of
597-
/// tokens to count, and the expanded tree is likewise very small.
598-
macro_rules! count {
599-
() => (0usize);
600-
($one:tt) => (1usize);
601-
($($pairs:tt $_p:tt)*) => (count!($($pairs)*) << 1usize);
602-
($odd:tt $($rest:tt)*) => (count!($($rest)*) | 1usize);
603-
}
604-
605588
// We define the GlobalMetaDataKind enum with this macro because we want to
606589
// make sure that we exhaustively iterate over all variants when registering
607590
// the corresponding DefIndices in the DefTable.
@@ -614,8 +597,6 @@ macro_rules! define_global_metadata_kind {
614597
$($variant),*
615598
}
616599

617-
pub const FIRST_FREE_DEF_INDEX: usize = 1 + count!($($variant)*);
618-
619600
impl GlobalMetaDataKind {
620601
fn allocate_def_indices(definitions: &mut Definitions) {
621602
$({

‎src/librustc_metadata/creader.rs

Lines changed: 25 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
33
use crate::cstore::{self, CStore, CrateSource, MetadataBlob};
44
use crate::locator::{self, CratePaths};
5-
use crate::decoder::proc_macro_def_path_table;
6-
use crate::schema::CrateRoot;
5+
use crate::schema::{CrateRoot};
76
use rustc_data_structures::sync::{Lrc, RwLock, Lock};
87

98
use rustc::hir::def_id::CrateNum;
@@ -26,11 +25,11 @@ use std::{cmp, fs};
2625
use syntax::ast;
2726
use syntax::attr;
2827
use syntax::ext::allocator::{global_allocator_spans, AllocatorKind};
29-
use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind};
3028
use syntax::symbol::{Symbol, sym};
3129
use syntax::{span_err, span_fatal};
3230
use syntax_pos::{Span, DUMMY_SP};
3331
use log::{debug, info, log_enabled};
32+
use proc_macro::bridge::client::ProcMacro;
3433

3534
pub struct Library {
3635
pub dylib: Option<(PathBuf, PathKind)>,
@@ -230,24 +229,13 @@ impl<'a> CrateLoader<'a> {
230229

231230
let dependencies: Vec<CrateNum> = cnum_map.iter().cloned().collect();
232231

233-
let proc_macros = crate_root.proc_macro_decls_static.map(|_| {
232+
let raw_proc_macros = crate_root.proc_macro_data.map(|_| {
234233
if self.sess.opts.debugging_opts.dual_proc_macros {
235-
let host_lib = host_lib.unwrap();
236-
self.load_derive_macros(
237-
&host_lib.metadata.get_root(),
238-
host_lib.dylib.map(|p| p.0),
239-
span
240-
)
234+
let host_lib = host_lib.as_ref().unwrap();
235+
self.dlsym_proc_macros(host_lib.dylib.as_ref().map(|p| p.0.clone()),
236+
&host_lib.metadata.get_root(), span)
241237
} else {
242-
self.load_derive_macros(&crate_root, dylib.clone().map(|p| p.0), span)
243-
}
244-
});
245-
246-
let def_path_table = record_time(&self.sess.perf_stats.decode_def_path_tables_time, || {
247-
if let Some(proc_macros) = &proc_macros {
248-
proc_macro_def_path_table(&crate_root, proc_macros)
249-
} else {
250-
crate_root.def_path_table.decode((&metadata, self.sess))
238+
self.dlsym_proc_macros(dylib.clone().map(|p| p.0), &crate_root, span)
251239
}
252240
});
253241

@@ -260,13 +248,16 @@ impl<'a> CrateLoader<'a> {
260248
.map(|trait_impls| (trait_impls.trait_id, trait_impls.impls))
261249
.collect();
262250

251+
let def_path_table = record_time(&self.sess.perf_stats.decode_def_path_tables_time, || {
252+
crate_root.def_path_table.decode((&metadata, self.sess))
253+
});
254+
263255
let cmeta = cstore::CrateMetadata {
264256
name: crate_root.name,
265257
imported_name: ident,
266258
extern_crate: Lock::new(None),
267259
def_path_table: Lrc::new(def_path_table),
268260
trait_impls,
269-
proc_macros,
270261
root: crate_root,
271262
blob: metadata,
272263
cnum_map,
@@ -280,7 +271,10 @@ impl<'a> CrateLoader<'a> {
280271
rlib,
281272
rmeta,
282273
},
283-
private_dep
274+
private_dep,
275+
span,
276+
host_lib,
277+
raw_proc_macros
284278
};
285279

286280
let cmeta = Lrc::new(cmeta);
@@ -300,8 +294,6 @@ impl<'a> CrateLoader<'a> {
300294
// message we emit
301295
let mut proc_macro_locator = locate_ctxt.clone();
302296

303-
// Try to load a proc macro
304-
proc_macro_locator.is_proc_macro = Some(true);
305297

306298
// Load the proc macro crate for the target
307299
let (locator, target_result) = if self.sess.opts.debugging_opts.dual_proc_macros {
@@ -389,7 +381,7 @@ impl<'a> CrateLoader<'a> {
389381
match result {
390382
(LoadResult::Previous(cnum), None) => {
391383
let data = self.cstore.get_crate_data(cnum);
392-
if data.root.proc_macro_decls_static.is_some() {
384+
if data.root.proc_macro_data.is_some() {
393385
dep_kind = DepKind::UnexportedMacrosOnly;
394386
}
395387
data.dep_kind.with_lock(|data_dep_kind| {
@@ -482,7 +474,7 @@ impl<'a> CrateLoader<'a> {
482474
dep_kind: DepKind)
483475
-> cstore::CrateNumMap {
484476
debug!("resolving deps of external crate");
485-
if crate_root.proc_macro_decls_static.is_some() {
477+
if crate_root.proc_macro_data.is_some() {
486478
return cstore::CrateNumMap::new();
487479
}
488480

@@ -574,19 +566,13 @@ impl<'a> CrateLoader<'a> {
574566
}
575567
}
576568

577-
/// Loads custom derive macros.
578-
///
579-
/// Note that this is intentionally similar to how we load plugins today,
580-
/// but also intentionally separate. Plugins are likely always going to be
581-
/// implemented as dynamic libraries, but we have a possible future where
582-
/// custom derive (and other macro-1.1 style features) are implemented via
583-
/// executables and custom IPC.
584-
fn load_derive_macros(&mut self, root: &CrateRoot<'_>, dylib: Option<PathBuf>, span: Span)
585-
-> Vec<(ast::Name, Lrc<SyntaxExtension>)> {
586-
use std::{env, mem};
569+
fn dlsym_proc_macros(&self,
570+
dylib: Option<PathBuf>,
571+
root: &CrateRoot<'_>,
572+
span: Span
573+
) -> &'static [ProcMacro] {
574+
use std::env;
587575
use crate::dynamic_lib::DynamicLibrary;
588-
use proc_macro::bridge::client::ProcMacro;
589-
use syntax::ext::proc_macro::{BangProcMacro, AttrProcMacro, ProcMacroDerive};
590576

591577
let path = match dylib {
592578
Some(dylib) => dylib,
@@ -608,38 +594,11 @@ impl<'a> CrateLoader<'a> {
608594
*(sym as *const &[ProcMacro])
609595
};
610596

611-
let extensions = decls.iter().map(|&decl| {
612-
let (name, kind, helper_attrs) = match decl {
613-
ProcMacro::CustomDerive { trait_name, attributes, client } => {
614-
let helper_attrs =
615-
attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
616-
(
617-
trait_name,
618-
SyntaxExtensionKind::Derive(Box::new(ProcMacroDerive {
619-
client, attrs: helper_attrs.clone()
620-
})),
621-
helper_attrs,
622-
)
623-
}
624-
ProcMacro::Attr { name, client } => (
625-
name, SyntaxExtensionKind::Attr(Box::new(AttrProcMacro { client })), Vec::new()
626-
),
627-
ProcMacro::Bang { name, client } => (
628-
name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new()
629-
)
630-
};
631-
632-
(Symbol::intern(name), Lrc::new(SyntaxExtension {
633-
helper_attrs,
634-
..SyntaxExtension::default(kind, root.edition)
635-
}))
636-
}).collect();
637-
638597
// Intentionally leak the dynamic library. We can't ever unload it
639598
// since the library can make things that will live arbitrarily long.
640-
mem::forget(lib);
599+
std::mem::forget(lib);
641600

642-
extensions
601+
decls
643602
}
644603

645604
/// Look for a plugin registrar. Returns library path, crate

‎src/librustc_metadata/cstore.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ pub use crate::cstore_impl::{provide, provide_extern};
2828
pub type CrateNumMap = IndexVec<CrateNum, CrateNum>;
2929

3030
pub use rustc_data_structures::sync::MetadataRef;
31+
use crate::creader::Library;
32+
use syntax_pos::Span;
33+
use proc_macro::bridge::client::ProcMacro;
3134

3235
pub struct MetadataBlob(pub MetadataRef);
3336

@@ -82,11 +85,19 @@ pub struct CrateMetadata {
8285
pub dep_kind: Lock<DepKind>,
8386
pub source: CrateSource,
8487

85-
pub proc_macros: Option<Vec<(ast::Name, Lrc<SyntaxExtension>)>>,
86-
8788
/// Whether or not this crate should be consider a private dependency
8889
/// for purposes of the 'exported_private_dependencies' lint
89-
pub private_dep: bool
90+
pub private_dep: bool,
91+
92+
pub host_lib: Option<Library>,
93+
pub span: Span,
94+
95+
pub raw_proc_macros: Option<&'static [ProcMacro]>,
96+
}
97+
98+
pub struct FullProcMacro {
99+
pub name: ast::Name,
100+
pub ext: Lrc<SyntaxExtension>
90101
}
91102

92103
pub struct CStore {

‎src/librustc_metadata/cstore_impl.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -426,8 +426,8 @@ impl cstore::CStore {
426426

427427
pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
428428
let data = self.get_crate_data(id.krate);
429-
if let Some(ref proc_macros) = data.proc_macros {
430-
return LoadedMacro::ProcMacro(proc_macros[id.index.to_proc_macro_index()].1.clone());
429+
if data.is_proc_macro_crate() {
430+
return LoadedMacro::ProcMacro(data.get_proc_macro(id.index, sess).ext);
431431
} else if data.name == sym::proc_macro && data.item_name(id.index) == sym::quote {
432432
let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
433433
let kind = SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client }));
@@ -439,7 +439,8 @@ impl cstore::CStore {
439439
}
440440

441441
let def = data.get_macro(id.index);
442-
let macro_full_name = data.def_path(id.index).to_string_friendly(|_| data.imported_name);
442+
let macro_full_name = data.def_path(id.index)
443+
.to_string_friendly(|_| data.imported_name);
443444
let source_name = FileName::Macros(macro_full_name);
444445

445446
let source_file = sess.parse_sess.source_map().new_source_file(source_name, def.body);

‎src/librustc_metadata/decoder.rs

Lines changed: 113 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
// Decoding metadata from a single crate's metadata
22

3-
use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule};
3+
use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule, FullProcMacro};
44
use crate::schema::*;
55

66
use rustc_data_structures::sync::{Lrc, ReadGuard};
7-
use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash, Definitions};
7+
use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
88
use rustc::hir;
99
use rustc::middle::cstore::LinkagePreference;
1010
use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
1111
use rustc::hir::def::{self, Res, DefKind, CtorOf, CtorKind};
1212
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
13-
use rustc::hir::map::definitions::DefPathTable;
1413
use rustc_data_structures::fingerprint::Fingerprint;
1514
use rustc::middle::lang_items;
1615
use rustc::mir::{self, interpret};
@@ -30,10 +29,11 @@ use syntax::attr;
3029
use syntax::ast::{self, Ident};
3130
use syntax::source_map;
3231
use syntax::symbol::{Symbol, sym};
33-
use syntax::ext::base::{MacroKind, SyntaxExtension};
34-
use syntax::ext::hygiene::ExpnId;
35-
use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP};
32+
use syntax::ext::base::{MacroKind, SyntaxExtensionKind, SyntaxExtension};
33+
use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, symbol::{InternedString}};
3634
use log::debug;
35+
use proc_macro::bridge::client::ProcMacro;
36+
use syntax::ext::proc_macro::{AttrProcMacro, ProcMacroDerive, BangProcMacro};
3737

3838
pub struct DecodeContext<'a, 'tcx> {
3939
opaque: opaque::Decoder<'a>,
@@ -138,7 +138,7 @@ impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> LazySeq<T> {
138138
pub fn decode<M: Metadata<'a, 'tcx>>(
139139
self,
140140
meta: M,
141-
) -> impl Iterator<Item = T> + Captures<'a> + Captures<'tcx> + 'x {
141+
) -> impl ExactSizeIterator<Item = T> + Captures<'a> + Captures<'tcx> + 'x {
142142
let mut dcx = meta.decoder(self.position);
143143
dcx.lazy_state = LazyState::NodeStart(self.position);
144144
(0..self.len).map(move |_| T::decode(&mut dcx).unwrap())
@@ -434,46 +434,16 @@ impl<'tcx> EntryKind<'tcx> {
434434
}
435435
}
436436

437-
/// Creates the "fake" DefPathTable for a given proc macro crate.
438-
///
439-
/// The DefPathTable is as follows:
440-
///
441-
/// CRATE_ROOT (DefIndex 0:0)
442-
/// |- GlobalMetaDataKind data (DefIndex 1:0 .. DefIndex 1:N)
443-
/// |- proc macro #0 (DefIndex 1:N)
444-
/// |- proc macro #1 (DefIndex 1:N+1)
445-
/// \- ...
446-
crate fn proc_macro_def_path_table(crate_root: &CrateRoot<'_>,
447-
proc_macros: &[(ast::Name, Lrc<SyntaxExtension>)])
448-
-> DefPathTable
449-
{
450-
let mut definitions = Definitions::default();
451-
452-
let name = crate_root.name.as_str();
453-
let disambiguator = crate_root.disambiguator;
454-
debug!("creating proc macro def path table for {:?}/{:?}", name, disambiguator);
455-
let crate_root = definitions.create_root_def(&name, disambiguator);
456-
for (index, (name, _)) in proc_macros.iter().enumerate() {
457-
let def_index = definitions.create_def_with_parent(
458-
crate_root,
459-
ast::DUMMY_NODE_ID,
460-
DefPathData::MacroNs(name.as_interned_str()),
461-
ExpnId::root(),
462-
DUMMY_SP);
463-
debug!("definition for {:?} is {:?}", name, def_index);
464-
assert_eq!(def_index, DefIndex::from_proc_macro_index(index));
465-
}
466-
467-
definitions.def_path_table().clone()
468-
}
469-
470437
impl<'a, 'tcx> CrateMetadata {
438+
pub fn is_proc_macro_crate(&self) -> bool {
439+
self.root.proc_macro_decls_static.is_some()
440+
}
471441
fn is_proc_macro(&self, id: DefIndex) -> bool {
472-
self.proc_macros.is_some() && id != CRATE_DEF_INDEX
442+
self.is_proc_macro_crate() &&
443+
self.root.proc_macro_data.unwrap().decode(self).find(|x| *x == id).is_some()
473444
}
474445

475446
fn maybe_entry(&self, item_id: DefIndex) -> Option<Lazy<Entry<'tcx>>> {
476-
assert!(!self.is_proc_macro(item_id));
477447
self.root.entries_index.lookup(self.blob.raw_bytes(), item_id)
478448
}
479449

@@ -496,29 +466,89 @@ impl<'a, 'tcx> CrateMetadata {
496466
}
497467
}
498468

469+
fn raw_proc_macro(&self, id: DefIndex) -> &ProcMacro {
470+
// DefIndex's in root.proc_macro_data have a one-to-one correspondence
471+
// with items in 'raw_proc_macros'
472+
let pos = self.root.proc_macro_data.unwrap().decode(self).position(|i| i == id).unwrap();
473+
&self.raw_proc_macros.unwrap()[pos]
474+
}
475+
499476
pub fn item_name(&self, item_index: DefIndex) -> Symbol {
500-
self.def_key(item_index)
501-
.disambiguated_data
502-
.data
503-
.get_opt_name()
504-
.expect("no name in item_name")
505-
.as_symbol()
477+
if !self.is_proc_macro(item_index) {
478+
self.def_key(item_index)
479+
.disambiguated_data
480+
.data
481+
.get_opt_name()
482+
.expect("no name in item_name")
483+
.as_symbol()
484+
} else {
485+
Symbol::intern(self.raw_proc_macro(item_index).name())
486+
}
506487
}
507488

508489
pub fn def_kind(&self, index: DefIndex) -> Option<DefKind> {
509490
if !self.is_proc_macro(index) {
510491
self.entry(index).kind.def_kind()
511492
} else {
512493
Some(DefKind::Macro(
513-
self.proc_macros.as_ref().unwrap()[index.to_proc_macro_index()].1.macro_kind()
494+
macro_kind(self.raw_proc_macro(index))
514495
))
515496
}
516497
}
517498

518499
pub fn get_span(&self, index: DefIndex, sess: &Session) -> Span {
519-
match self.is_proc_macro(index) {
520-
true => DUMMY_SP,
521-
false => self.entry(index).span.decode((self, sess)),
500+
self.entry(index).span.decode((self, sess))
501+
}
502+
503+
504+
pub fn get_proc_macro(&self, id: DefIndex, sess: &Session) -> FullProcMacro {
505+
if sess.opts.debugging_opts.dual_proc_macros {
506+
let host_lib = self.host_lib.as_ref().unwrap();
507+
self.load_proc_macro(
508+
&host_lib.metadata.get_root(),
509+
id,
510+
sess
511+
)
512+
} else {
513+
self.load_proc_macro(&self.root, id, sess)
514+
}
515+
}
516+
517+
fn load_proc_macro(&self, root: &CrateRoot<'_>,
518+
id: DefIndex,
519+
sess: &Session)
520+
-> FullProcMacro {
521+
522+
let raw_macro = self.raw_proc_macro(id);
523+
let (name, kind, helper_attrs) = match *raw_macro {
524+
ProcMacro::CustomDerive { trait_name, attributes, client } => {
525+
let helper_attrs =
526+
attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
527+
(
528+
trait_name,
529+
SyntaxExtensionKind::Derive(Box::new(ProcMacroDerive {
530+
client, attrs: helper_attrs.clone()
531+
})),
532+
helper_attrs,
533+
)
534+
}
535+
ProcMacro::Attr { name, client } => (
536+
name, SyntaxExtensionKind::Attr(Box::new(AttrProcMacro { client })), Vec::new()
537+
),
538+
ProcMacro::Bang { name, client } => (
539+
name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new()
540+
)
541+
};
542+
543+
let span = self.get_span(id, sess);
544+
545+
FullProcMacro {
546+
name: Symbol::intern(name),
547+
ext: Lrc::new(SyntaxExtension {
548+
span,
549+
helper_attrs,
550+
..SyntaxExtension::default(kind, root.edition)
551+
})
522552
}
523553
}
524554

@@ -715,7 +745,7 @@ impl<'a, 'tcx> CrateMetadata {
715745

716746
/// Iterates over the language items in the given crate.
717747
pub fn get_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] {
718-
if self.proc_macros.is_some() {
748+
if self.is_proc_macro_crate() {
719749
// Proc macro crates do not export any lang-items to the target.
720750
&[]
721751
} else {
@@ -730,18 +760,18 @@ impl<'a, 'tcx> CrateMetadata {
730760
pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F, sess: &Session)
731761
where F: FnMut(def::Export<hir::HirId>)
732762
{
733-
if let Some(ref proc_macros) = self.proc_macros {
763+
if let Some(proc_macros_ids) = self.root.proc_macro_data.map(|d| d.decode(self)) {
734764
/* If we are loading as a proc macro, we want to return the view of this crate
735-
* as a proc macro crate, not as a Rust crate. See `proc_macro_def_path_table`
736-
* for the DefPathTable we are corresponding to.
765+
* as a proc macro crate.
737766
*/
738767
if id == CRATE_DEF_INDEX {
739-
for (id, &(name, ref ext)) in proc_macros.iter().enumerate() {
768+
for def_index in proc_macros_ids {
769+
let raw_macro = self.raw_proc_macro(def_index);
740770
let res = Res::Def(
741-
DefKind::Macro(ext.macro_kind()),
742-
self.local_def_id(DefIndex::from_proc_macro_index(id)),
771+
DefKind::Macro(macro_kind(raw_macro)),
772+
self.local_def_id(def_index),
743773
);
744-
let ident = Ident::with_dummy_span(name);
774+
let ident = Ident::from_str(raw_macro.name());
745775
callback(def::Export {
746776
ident: ident,
747777
res: res,
@@ -952,11 +982,8 @@ impl<'a, 'tcx> CrateMetadata {
952982
}
953983
}
954984

955-
pub fn get_item_attrs(&self, node_id: DefIndex, sess: &Session) -> Lrc<[ast::Attribute]> {
956-
if self.is_proc_macro(node_id) {
957-
return Lrc::new([]);
958-
}
959985

986+
pub fn get_item_attrs(&self, node_id: DefIndex, sess: &Session) -> Lrc<[ast::Attribute]> {
960987
// The attributes for a tuple struct/variant are attached to the definition, not the ctor;
961988
// we assume that someone passing in a tuple struct ctor is actually wanting to
962989
// look at the definition
@@ -1014,7 +1041,7 @@ impl<'a, 'tcx> CrateMetadata {
10141041
tcx: TyCtxt<'tcx>,
10151042
filter: Option<DefId>,
10161043
) -> &'tcx [DefId] {
1017-
if self.proc_macros.is_some() {
1044+
if self.is_proc_macro_crate() {
10181045
// proc-macro crates export no trait impls.
10191046
return &[]
10201047
}
@@ -1058,7 +1085,7 @@ impl<'a, 'tcx> CrateMetadata {
10581085

10591086

10601087
pub fn get_native_libraries(&self, sess: &Session) -> Vec<NativeLibrary> {
1061-
if self.proc_macros.is_some() {
1088+
if self.is_proc_macro_crate() {
10621089
// Proc macro crates do not have any *target* native libraries.
10631090
vec![]
10641091
} else {
@@ -1067,7 +1094,7 @@ impl<'a, 'tcx> CrateMetadata {
10671094
}
10681095

10691096
pub fn get_foreign_modules(&self, tcx: TyCtxt<'tcx>) -> &'tcx [ForeignModule] {
1070-
if self.proc_macros.is_some() {
1097+
if self.is_proc_macro_crate() {
10711098
// Proc macro crates do not have any *target* foreign modules.
10721099
&[]
10731100
} else {
@@ -1090,7 +1117,7 @@ impl<'a, 'tcx> CrateMetadata {
10901117
}
10911118

10921119
pub fn get_missing_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] {
1093-
if self.proc_macros.is_some() {
1120+
if self.is_proc_macro_crate() {
10941121
// Proc macro crates do not depend on any target weak lang-items.
10951122
&[]
10961123
} else {
@@ -1114,7 +1141,7 @@ impl<'a, 'tcx> CrateMetadata {
11141141
&self,
11151142
tcx: TyCtxt<'tcx>,
11161143
) -> Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)> {
1117-
if self.proc_macros.is_some() {
1144+
if self.is_proc_macro_crate() {
11181145
// If this crate is a custom derive crate, then we're not even going to
11191146
// link those in so we skip those crates.
11201147
vec![]
@@ -1183,13 +1210,18 @@ impl<'a, 'tcx> CrateMetadata {
11831210

11841211
#[inline]
11851212
pub fn def_key(&self, index: DefIndex) -> DefKey {
1186-
self.def_path_table.def_key(index)
1213+
let mut key = self.def_path_table.def_key(index);
1214+
if self.is_proc_macro(index) {
1215+
let name = self.raw_proc_macro(index).name();
1216+
key.disambiguated_data.data = DefPathData::MacroNs(InternedString::intern(name));
1217+
}
1218+
key
11871219
}
11881220

11891221
// Returns the path leading to the thing with this `id`.
11901222
pub fn def_path(&self, id: DefIndex) -> DefPath {
11911223
debug!("def_path(cnum={:?}, id={:?})", self.cnum, id);
1192-
DefPath::make(self.cnum, id, |parent| self.def_path_table.def_key(parent))
1224+
DefPath::make(self.cnum, id, |parent| self.def_key(parent))
11931225
}
11941226

11951227
#[inline]
@@ -1302,3 +1334,13 @@ impl<'a, 'tcx> CrateMetadata {
13021334
self.source_map_import_info.borrow()
13031335
}
13041336
}
1337+
1338+
// Cannot be implemented on 'ProcMacro', as libproc_macro
1339+
// does not depend on libsyntax
1340+
fn macro_kind(raw: &ProcMacro) -> MacroKind {
1341+
match raw {
1342+
ProcMacro::CustomDerive { .. } => MacroKind::Derive,
1343+
ProcMacro::Attr { .. } => MacroKind::Attr,
1344+
ProcMacro::Bang { .. } => MacroKind::Bang
1345+
}
1346+
}

‎src/librustc_metadata/encoder.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use rustc_data_structures::sync::Lrc;
3030
use std::u32;
3131
use syntax::ast;
3232
use syntax::attr;
33+
use syntax::ext::proc_macro::is_proc_macro_attr;
3334
use syntax::source_map::Spanned;
3435
use syntax::symbol::{kw, sym};
3536
use syntax_pos::{self, FileName, SourceFile, Span};
@@ -376,6 +377,8 @@ impl<'tcx> EncodeContext<'tcx> {
376377
}
377378

378379
fn encode_crate_root(&mut self) -> Lazy<CrateRoot<'tcx>> {
380+
let is_proc_macro = self.tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro);
381+
379382
let mut i = self.position();
380383

381384
let crate_deps = self.encode_crate_deps();
@@ -456,16 +459,23 @@ impl<'tcx> EncodeContext<'tcx> {
456459
self.lazy_seq(interpret_alloc_index)
457460
};
458461

462+
459463
i = self.position();
460464
let entries_index = self.entries_index.write_index(&mut self.opaque);
461465
let entries_index_bytes = self.position() - i;
462466

467+
// Encode the proc macro data
468+
i = self.position();
469+
let proc_macro_data = self.encode_proc_macros();
470+
let proc_macro_data_bytes = self.position() - i;
471+
472+
463473
let attrs = tcx.hir().krate_attrs();
464-
let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro);
465474
let has_default_lib_allocator = attr::contains_name(&attrs, sym::default_lib_allocator);
466475
let has_global_allocator = *tcx.sess.has_global_allocator.get();
467476
let has_panic_handler = *tcx.sess.has_panic_handler.try_get().unwrap_or(&false);
468477

478+
469479
let root = self.lazy(&CrateRoot {
470480
name: tcx.crate_name(LOCAL_CRATE),
471481
extra_filename: tcx.sess.opts.cg.extra_filename.clone(),
@@ -484,6 +494,7 @@ impl<'tcx> EncodeContext<'tcx> {
484494
} else {
485495
None
486496
},
497+
proc_macro_data,
487498
proc_macro_stability: if is_proc_macro {
488499
tcx.lookup_stability(DefId::local(CRATE_DEF_INDEX)).map(|stab| stab.clone())
489500
} else {
@@ -532,6 +543,7 @@ impl<'tcx> EncodeContext<'tcx> {
532543
println!(" impl bytes: {}", impl_bytes);
533544
println!(" exp. symbols bytes: {}", exported_symbols_bytes);
534545
println!(" def-path table bytes: {}", def_path_table_bytes);
546+
println!(" proc-macro-data-bytes: {}", proc_macro_data_bytes);
535547
println!(" item bytes: {}", item_bytes);
536548
println!(" entries index bytes: {}", entries_index_bytes);
537549
println!(" zero bytes: {}", zero_bytes);
@@ -1463,6 +1475,22 @@ impl EncodeContext<'tcx> {
14631475
self.lazy_seq(foreign_modules.iter().cloned())
14641476
}
14651477

1478+
fn encode_proc_macros(&mut self) -> Option<LazySeq<DefIndex>> {
1479+
let is_proc_macro = self.tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro);
1480+
if is_proc_macro {
1481+
let proc_macros: Vec<_> = self.tcx.hir().krate().items.values().filter_map(|item| {
1482+
if item.attrs.iter().any(|attr| is_proc_macro_attr(attr)) {
1483+
Some(item.hir_id.owner)
1484+
} else {
1485+
None
1486+
}
1487+
}).collect();
1488+
Some(self.lazy_seq(proc_macros))
1489+
} else {
1490+
None
1491+
}
1492+
}
1493+
14661494
fn encode_crate_deps(&mut self) -> LazySeq<CrateDep> {
14671495
let crates = self.tcx.crates();
14681496

‎src/librustc_metadata/locator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,7 @@ impl<'a> Context<'a> {
716716

717717
let root = metadata.get_root();
718718
if let Some(is_proc_macro) = self.is_proc_macro {
719-
if root.proc_macro_decls_static.is_some() != is_proc_macro {
719+
if root.proc_macro_data.is_some() != is_proc_macro {
720720
return None;
721721
}
722722
}

‎src/librustc_metadata/schema.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@ pub struct CrateRoot<'tcx> {
182182

183183
pub entries_index: LazySeq<index::Index<'tcx>>,
184184

185+
/// The DefIndex's of any proc macros delcared by
186+
/// this crate
187+
pub proc_macro_data: Option<LazySeq<DefIndex>>,
188+
185189
pub compiler_builtins: bool,
186190
pub needs_allocator: bool,
187191
pub needs_panic_runtime: bool,

‎src/test/ui/macros/same-sequence-span.stderr

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,21 @@ error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fra
1818
--> $DIR/same-sequence-span.rs:20:1
1919
|
2020
LL | proc_macro_sequence::make_foo!();
21-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed after `expr` fragments
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
22+
| |
23+
| not allowed after `expr` fragments
24+
| in this macro invocation
2225
|
2326
= note: allowed there are: `=>`, `,` or `;`
2427

2528
error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragments
2629
--> $DIR/same-sequence-span.rs:20:1
2730
|
2831
LL | proc_macro_sequence::make_foo!();
29-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed after `expr` fragments
32+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
33+
| |
34+
| not allowed after `expr` fragments
35+
| in this macro invocation
3036
|
3137
= note: allowed there are: `=>`, `,` or `;`
3238

‎src/test/ui/proc-macro/generate-mod.stderr

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@ error[E0412]: cannot find type `FromOutside` in this scope
22
--> $DIR/generate-mod.rs:9:1
33
|
44
LL | generate_mod::check!();
5-
| ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
5+
| ^^^^^^^^^^^^^^^^^^^^^^^
6+
| |
7+
| not found in this scope
8+
| in this macro invocation
69

710
error[E0412]: cannot find type `Outer` in this scope
811
--> $DIR/generate-mod.rs:9:1
912
|
1013
LL | generate_mod::check!();
11-
| ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
14+
| ^^^^^^^^^^^^^^^^^^^^^^^
15+
| |
16+
| not found in this scope
17+
| in this macro invocation
1218

1319
error[E0412]: cannot find type `FromOutside` in this scope
1420
--> $DIR/generate-mod.rs:12:1

‎src/test/ui/proc-macro/invalid-punct-ident-4.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ error: unexpected close delimiter: `)`
22
--> $DIR/invalid-punct-ident-4.rs:6:1
33
|
44
LL | lexer_failure!();
5-
| ^^^^^^^^^^^^^^^^^ unexpected close delimiter
5+
| ^^^^^^^^^^^^^^^^^
6+
| |
7+
| unexpected close delimiter
8+
| in this macro invocation
69

710
error: proc macro panicked
811
--> $DIR/invalid-punct-ident-4.rs:6:1

‎src/test/ui/proc-macro/lints_in_proc_macros.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ error[E0425]: cannot find value `foobar2` in this scope
22
--> $DIR/lints_in_proc_macros.rs:12:5
33
|
44
LL | bang_proc_macro2!();
5-
| ^^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `foobar`
5+
| ^^^^^^^^^^^^^^^^^^^^
6+
| |
7+
| help: a local variable with a similar name exists: `foobar`
8+
| in this macro invocation
69

710
error: aborting due to previous error
811

‎src/test/ui/proc-macro/multispan.stderr

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: hello to you, too!
22
--> $DIR/multispan.rs:14:5
33
|
44
LL | hello!(hi);
5-
| ^^^^^^^^^^^
5+
| ^^^^^^^^^^^ in this macro invocation
66
|
77
note: found these 'hi's
88
--> $DIR/multispan.rs:14:12
@@ -14,7 +14,7 @@ error: hello to you, too!
1414
--> $DIR/multispan.rs:17:5
1515
|
1616
LL | hello!(hi hi);
17-
| ^^^^^^^^^^^^^^
17+
| ^^^^^^^^^^^^^^ in this macro invocation
1818
|
1919
note: found these 'hi's
2020
--> $DIR/multispan.rs:17:12
@@ -26,7 +26,7 @@ error: hello to you, too!
2626
--> $DIR/multispan.rs:20:5
2727
|
2828
LL | hello!(hi hi hi);
29-
| ^^^^^^^^^^^^^^^^^
29+
| ^^^^^^^^^^^^^^^^^ in this macro invocation
3030
|
3131
note: found these 'hi's
3232
--> $DIR/multispan.rs:20:12
@@ -38,7 +38,7 @@ error: hello to you, too!
3838
--> $DIR/multispan.rs:23:5
3939
|
4040
LL | hello!(hi hey hi yo hi beep beep hi hi);
41-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
4242
|
4343
note: found these 'hi's
4444
--> $DIR/multispan.rs:23:12
@@ -50,7 +50,7 @@ error: hello to you, too!
5050
--> $DIR/multispan.rs:24:5
5151
|
5252
LL | hello!(hi there, hi how are you? hi... hi.);
53-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
53+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
5454
|
5555
note: found these 'hi's
5656
--> $DIR/multispan.rs:24:12
@@ -62,7 +62,7 @@ error: hello to you, too!
6262
--> $DIR/multispan.rs:25:5
6363
|
6464
LL | hello!(whoah. hi di hi di ho);
65-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
65+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
6666
|
6767
note: found these 'hi's
6868
--> $DIR/multispan.rs:25:19
@@ -74,7 +74,7 @@ error: hello to you, too!
7474
--> $DIR/multispan.rs:26:5
7575
|
7676
LL | hello!(hi good hi and good bye);
77-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
77+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
7878
|
7979
note: found these 'hi's
8080
--> $DIR/multispan.rs:26:12

‎src/test/ui/proc-macro/subspan.stderr

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: found 'hi's
22
--> $DIR/subspan.rs:11:1
33
|
44
LL | subspan!("hi");
5-
| ^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^ in this macro invocation
66
|
77
note: here
88
--> $DIR/subspan.rs:11:11
@@ -14,7 +14,7 @@ error: found 'hi's
1414
--> $DIR/subspan.rs:14:1
1515
|
1616
LL | subspan!("hihi");
17-
| ^^^^^^^^^^^^^^^^^
17+
| ^^^^^^^^^^^^^^^^^ in this macro invocation
1818
|
1919
note: here
2020
--> $DIR/subspan.rs:14:11
@@ -26,7 +26,7 @@ error: found 'hi's
2626
--> $DIR/subspan.rs:17:1
2727
|
2828
LL | subspan!("hihihi");
29-
| ^^^^^^^^^^^^^^^^^^^
29+
| ^^^^^^^^^^^^^^^^^^^ in this macro invocation
3030
|
3131
note: here
3232
--> $DIR/subspan.rs:17:11
@@ -38,7 +38,7 @@ error: found 'hi's
3838
--> $DIR/subspan.rs:20:1
3939
|
4040
LL | subspan!("why I hide? hi!");
41-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
4242
|
4343
note: here
4444
--> $DIR/subspan.rs:20:17
@@ -50,7 +50,7 @@ error: found 'hi's
5050
--> $DIR/subspan.rs:21:1
5151
|
5252
LL | subspan!("hey, hi, hidy, hidy, hi hi");
53-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
53+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
5454
|
5555
note: here
5656
--> $DIR/subspan.rs:21:16
@@ -62,7 +62,7 @@ error: found 'hi's
6262
--> $DIR/subspan.rs:22:1
6363
|
6464
LL | subspan!("this is a hi, and this is another hi");
65-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
65+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
6666
|
6767
note: here
6868
--> $DIR/subspan.rs:22:12
@@ -74,7 +74,7 @@ error: found 'hi's
7474
--> $DIR/subspan.rs:23:1
7575
|
7676
LL | subspan!("how are you this evening");
77-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
77+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
7878
|
7979
note: here
8080
--> $DIR/subspan.rs:23:24
@@ -86,7 +86,7 @@ error: found 'hi's
8686
--> $DIR/subspan.rs:24:1
8787
|
8888
LL | subspan!("this is highly eradic");
89-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
89+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
9090
|
9191
note: here
9292
--> $DIR/subspan.rs:24:12

‎src/test/ui/proc-macro/three-equals.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: found 2 equal signs, need exactly 3
22
--> $DIR/three-equals.rs:15:5
33
|
44
LL | three_equals!(==);
5-
| ^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^ in this macro invocation
66
|
77
= help: input must be: `===`
88

0 commit comments

Comments
 (0)
Please sign in to comment.