Skip to content

Commit f1ad425

Browse files
committed
use side table to store exported macros
Per discussion with @sfackler, refactored the expander to change the way that exported macros are collected. Specifically, a crate now contains a side table of spans that exported macros go into. This has two benefits. First, the encoder doesn't need to scan through the expanded crate in order to discover exported macros. Second, the expander can drop all expanded macros from the crate, with the pleasant result that a fully expanded crate contains no macro invocations (which include macro definitions).
1 parent 50d9965 commit f1ad425

File tree

7 files changed

+34
-35
lines changed

7 files changed

+34
-35
lines changed

src/librustc/driver/session.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ use syntax::{ast, codemap};
2828
use std::os;
2929
use std::cell::{Cell, RefCell};
3030

31-
31+
// Represents the data associated with a compilation
32+
// session for a single crate.
3233
pub struct Session {
3334
pub targ_cfg: config::Config,
3435
pub opts: config::Options,

src/librustc/metadata/encoder.rs

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,37 +1584,25 @@ fn encode_plugin_registrar_fn(ecx: &EncodeContext, ebml_w: &mut Encoder) {
15841584
}
15851585
}
15861586

1587-
struct MacroDefVisitor<'a, 'b, 'c> {
1588-
ecx: &'a EncodeContext<'b>,
1589-
ebml_w: &'a mut Encoder<'c>
1590-
}
1591-
1592-
impl<'a, 'b, 'c> Visitor<()> for MacroDefVisitor<'a, 'b, 'c> {
1593-
fn visit_item(&mut self, item: &Item, _: ()) {
1594-
match item.node {
1595-
ItemMac(..) => {
1596-
let def = self.ecx.tcx.sess.codemap().span_to_snippet(item.span)
1597-
.expect("Unable to find source for macro");
1598-
self.ebml_w.start_tag(tag_macro_def);
1599-
self.ebml_w.wr_str(def.as_slice());
1600-
self.ebml_w.end_tag();
1601-
}
1602-
_ => {}
1603-
}
1604-
visit::walk_item(self, item, ());
1605-
}
1587+
/// Given a span, write the text of that span into the output stream
1588+
/// as an exported macro
1589+
fn encode_macro_def(ecx: &EncodeContext,
1590+
ebml_w: &mut Encoder,
1591+
span: &syntax::codemap::Span) {
1592+
let def = ecx.tcx.sess.codemap().span_to_snippet(*span)
1593+
.expect("Unable to find source for macro");
1594+
ebml_w.start_tag(tag_macro_def);
1595+
ebml_w.wr_str(def.as_slice());
1596+
ebml_w.end_tag();
16061597
}
16071598

1608-
fn encode_macro_defs<'a>(ecx: &'a EncodeContext,
1609-
krate: &Crate,
1610-
ebml_w: &'a mut Encoder) {
1599+
/// Serialize the text of the exported macros
1600+
fn encode_macro_defs(ecx: &EncodeContext,
1601+
krate: &Crate,
1602+
ebml_w: &mut Encoder) {
16111603
ebml_w.start_tag(tag_exported_macros);
1612-
{
1613-
let mut visitor = MacroDefVisitor {
1614-
ecx: ecx,
1615-
ebml_w: ebml_w,
1616-
};
1617-
visit::walk_crate(&mut visitor, krate, ());
1604+
for span in krate.exported_macros.iter() {
1605+
encode_macro_def(ecx, ebml_w, span);
16181606
}
16191607
ebml_w.end_tag();
16201608
}

src/libsyntax/ast.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ pub struct Crate {
249249
pub attrs: Vec<Attribute>,
250250
pub config: CrateConfig,
251251
pub span: Span,
252+
pub exported_macros: Vec<Span>
252253
}
253254

254255
pub type MetaItem = Spanned<MetaItem_>;
@@ -1245,6 +1246,7 @@ mod test {
12451246
hi: BytePos(20),
12461247
expn_info: None,
12471248
},
1249+
exported_macros: Vec::new(),
12481250
};
12491251
// doesn't matter which encoder we use....
12501252
let _f = &e as &serialize::Encodable<json::Encoder, io::IoError>;

src/libsyntax/ext/base.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ pub struct ExtCtxt<'a> {
410410

411411
pub mod_path: Vec<ast::Ident> ,
412412
pub trace_mac: bool,
413+
pub exported_macros: Vec<codemap::Span>
413414
}
414415

415416
impl<'a> ExtCtxt<'a> {
@@ -421,7 +422,8 @@ impl<'a> ExtCtxt<'a> {
421422
backtrace: None,
422423
mod_path: Vec::new(),
423424
ecfg: ecfg,
424-
trace_mac: false
425+
trace_mac: false,
426+
exported_macros: Vec::new(),
425427
}
426428
}
427429

@@ -539,6 +541,9 @@ impl<'a> ExtCtxt<'a> {
539541
pub fn name_of(&self, st: &str) -> ast::Name {
540542
token::intern(st)
541543
}
544+
pub fn push_exported_macro(&mut self, span: codemap::Span) {
545+
self.exported_macros.push(span);
546+
}
542547
}
543548

544549
/// Extract a string literal from the macro expanded version of `expr`,

src/libsyntax/ext/expand.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -518,10 +518,9 @@ fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
518518
// create issue to recommend refactoring here?
519519
fld.extsbox.insert(intern(name.as_slice()), ext);
520520
if attr::contains_name(it.attrs.as_slice(), "macro_export") {
521-
SmallVector::one(it)
522-
} else {
523-
SmallVector::zero()
521+
fld.cx.push_exported_macro(it.span);
524522
}
523+
SmallVector::zero()
525524
}
526525
None => {
527526
match expanded.make_items() {
@@ -1039,6 +1038,7 @@ pub struct ExportedMacros {
10391038

10401039
pub fn expand_crate(parse_sess: &parse::ParseSess,
10411040
cfg: ExpansionConfig,
1041+
// these are the macros being imported to this crate:
10421042
macros: Vec<ExportedMacros>,
10431043
user_exts: Vec<NamedSyntaxExtension>,
10441044
c: Crate) -> Crate {
@@ -1066,7 +1066,8 @@ pub fn expand_crate(parse_sess: &parse::ParseSess,
10661066
expander.extsbox.insert(name, extension);
10671067
}
10681068

1069-
let ret = expander.fold_crate(c);
1069+
let mut ret = expander.fold_crate(c);
1070+
ret.exported_macros = expander.cx.exported_macros.clone();
10701071
parse_sess.span_diagnostic.handler().abort_if_errors();
10711072
return ret;
10721073
}

src/libsyntax/fold.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,7 @@ pub fn noop_fold_crate<T: Folder>(c: Crate, folder: &mut T) -> Crate {
713713
attrs: c.attrs.iter().map(|x| folder.fold_attribute(*x)).collect(),
714714
config: c.config.iter().map(|x| fold_meta_item_(*x, folder)).collect(),
715715
span: folder.new_span(c.span),
716+
exported_macros: c.exported_macros.iter().map(|sp| folder.new_span(*sp)).collect(),
716717
}
717718
}
718719

src/libsyntax/parse/parser.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5386,7 +5386,8 @@ impl<'a> Parser<'a> {
53865386
module: m,
53875387
attrs: inner,
53885388
config: self.cfg.clone(),
5389-
span: mk_sp(lo, self.span.lo)
5389+
span: mk_sp(lo, self.span.lo),
5390+
exported_macros: Vec::new(),
53905391
}
53915392
}
53925393

0 commit comments

Comments
 (0)