1
Fork 0

Moved syntax::ext::base::SyntaxEnv into syntax::ext::base::ExtCtx

This commit is contained in:
Marvin Löbel 2014-07-19 21:34:24 +02:00
parent df68c6f3c3
commit 94d92e6830
2 changed files with 213 additions and 201 deletions

View file

@ -23,6 +23,7 @@ use ext::mtwt;
use std::collections::HashMap; use std::collections::HashMap;
use std::gc::{Gc, GC}; use std::gc::{Gc, GC};
use std::rc::Rc;
// new-style macro! tt code: // new-style macro! tt code:
// //
@ -104,9 +105,9 @@ pub type IdentMacroExpanderFn =
/// just into the compiler's internal macro table, for `make_def`). /// just into the compiler's internal macro table, for `make_def`).
pub trait MacResult { pub trait MacResult {
/// Define a new macro. /// Define a new macro.
// this particular flavor should go away; the idea that a macro might // this should go away; the idea that a macro might expand into
// expand into either a macro definition or an expression, depending // either a macro definition or an expression, depending on what
// on what the context wants, is kind of silly. // the context wants, is kind of silly.
fn make_def(&self) -> Option<MacroDef> { fn make_def(&self) -> Option<MacroDef> {
None None
} }
@ -314,7 +315,7 @@ impl BlockInfo {
/// The base map of methods for expanding syntax extension /// The base map of methods for expanding syntax extension
/// AST nodes into full ASTs /// AST nodes into full ASTs
pub fn syntax_expander_table() -> SyntaxEnv { fn initial_syntax_expander_table() -> SyntaxEnv {
// utility function to simplify creating NormalTT syntax extensions // utility function to simplify creating NormalTT syntax extensions
fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension { fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
NormalTT(box BasicMacroExpander { NormalTT(box BasicMacroExpander {
@ -431,7 +432,9 @@ pub struct ExtCtxt<'a> {
pub mod_path: Vec<ast::Ident> , pub mod_path: Vec<ast::Ident> ,
pub trace_mac: bool, pub trace_mac: bool,
pub exported_macros: Vec<Gc<ast::Item>> pub exported_macros: Vec<Gc<ast::Item>>,
pub syntax_env: SyntaxEnv,
} }
impl<'a> ExtCtxt<'a> { impl<'a> ExtCtxt<'a> {
@ -445,6 +448,7 @@ impl<'a> ExtCtxt<'a> {
ecfg: ecfg, ecfg: ecfg,
trace_mac: false, trace_mac: false,
exported_macros: Vec::new(), exported_macros: Vec::new(),
syntax_env: initial_syntax_expander_table(),
} }
} }
@ -453,7 +457,6 @@ impl<'a> ExtCtxt<'a> {
match e.node { match e.node {
ast::ExprMac(..) => { ast::ExprMac(..) => {
let mut expander = expand::MacroExpander { let mut expander = expand::MacroExpander {
extsbox: syntax_expander_table(),
cx: self, cx: self,
}; };
e = expand::expand_expr(e, &mut expander); e = expand::expand_expr(e, &mut expander);
@ -642,10 +645,13 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
/// In order to have some notion of scoping for macros, /// In order to have some notion of scoping for macros,
/// we want to implement the notion of a transformation /// we want to implement the notion of a transformation
/// environment. /// environment.
///
/// This environment maps Names to SyntaxExtensions. /// This environment maps Names to SyntaxExtensions.
pub struct SyntaxEnv {
chain: Vec<MapChainFrame> ,
}
//impl question: how to implement it? Initially, the // impl question: how to implement it? Initially, the
// env will contain only macros, so it might be painful // env will contain only macros, so it might be painful
// to add an empty frame for every context. Let's just // to add an empty frame for every context. Let's just
// get it working, first.... // get it working, first....
@ -657,15 +663,11 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
struct MapChainFrame { struct MapChainFrame {
info: BlockInfo, info: BlockInfo,
map: HashMap<Name, SyntaxExtension>, map: HashMap<Name, Rc<SyntaxExtension>>,
}
pub struct SyntaxEnv {
chain: Vec<MapChainFrame> ,
} }
impl SyntaxEnv { impl SyntaxEnv {
pub fn new() -> SyntaxEnv { fn new() -> SyntaxEnv {
let mut map = SyntaxEnv { chain: Vec::new() }; let mut map = SyntaxEnv { chain: Vec::new() };
map.push_frame(); map.push_frame();
map map
@ -692,10 +694,10 @@ impl SyntaxEnv {
unreachable!() unreachable!()
} }
pub fn find<'a>(&'a self, k: &Name) -> Option<&'a SyntaxExtension> { pub fn find(&self, k: &Name) -> Option<Rc<SyntaxExtension>> {
for frame in self.chain.iter().rev() { for frame in self.chain.iter().rev() {
match frame.map.find(k) { match frame.map.find(k) {
Some(v) => return Some(v), Some(v) => return Some(v.clone()),
None => {} None => {}
} }
} }
@ -703,7 +705,7 @@ impl SyntaxEnv {
} }
pub fn insert(&mut self, k: Name, v: SyntaxExtension) { pub fn insert(&mut self, k: Name, v: SyntaxExtension) {
self.find_escape_frame().map.insert(k, v); self.find_escape_frame().map.insert(k, Rc::new(v));
} }
pub fn info<'a>(&'a mut self) -> &'a mut BlockInfo { pub fn info<'a>(&'a mut self) -> &'a mut BlockInfo {

View file

@ -208,7 +208,7 @@ fn expand_mac_invoc<T>(mac: &ast::Mac, span: &codemap::Span,
} }
let extname = pth.segments.get(0).identifier; let extname = pth.segments.get(0).identifier;
let extnamestr = token::get_ident(extname); let extnamestr = token::get_ident(extname);
match fld.extsbox.find(&extname.name) { match fld.cx.syntax_env.find(&extname.name) {
None => { None => {
fld.cx.span_err( fld.cx.span_err(
pth.span, pth.span,
@ -218,46 +218,48 @@ fn expand_mac_invoc<T>(mac: &ast::Mac, span: &codemap::Span,
// let compilation continue // let compilation continue
None None
} }
Some(&NormalTT(ref expandfun, exp_span)) => { Some(rc) => match *rc {
fld.cx.bt_push(ExpnInfo { NormalTT(ref expandfun, exp_span) => {
call_site: *span, fld.cx.bt_push(ExpnInfo {
callee: NameAndSpan { call_site: *span,
name: extnamestr.get().to_string(), callee: NameAndSpan {
format: MacroBang, name: extnamestr.get().to_string(),
span: exp_span, format: MacroBang,
}, span: exp_span,
}); },
let fm = fresh_mark(); });
let marked_before = mark_tts(tts.as_slice(), fm); let fm = fresh_mark();
let marked_before = mark_tts(tts.as_slice(), fm);
// The span that we pass to the expanders we want to // The span that we pass to the expanders we want to
// be the root of the call stack. That's the most // be the root of the call stack. That's the most
// relevant span and it's the actual invocation of // relevant span and it's the actual invocation of
// the macro. // the macro.
let mac_span = original_span(fld.cx); let mac_span = original_span(fld.cx);
let expanded = expandfun.expand(fld.cx, let expanded = expandfun.expand(fld.cx,
mac_span.call_site, mac_span.call_site,
marked_before.as_slice()); marked_before.as_slice());
let parsed = match parse_thunk(expanded) { let parsed = match parse_thunk(expanded) {
Some(e) => e, Some(e) => e,
None => { None => {
fld.cx.span_err( fld.cx.span_err(
pth.span, pth.span,
format!("non-expression macro in expression position: {}", format!("non-expression macro in expression position: {}",
extnamestr.get().as_slice() extnamestr.get().as_slice()
).as_slice()); ).as_slice());
return None; return None;
} }
}; };
Some(mark_thunk(parsed,fm)) Some(mark_thunk(parsed,fm))
} }
_ => { _ => {
fld.cx.span_err( fld.cx.span_err(
pth.span, pth.span,
format!("'{}' is not a tt-style macro", format!("'{}' is not a tt-style macro",
extnamestr.get()).as_slice()); extnamestr.get()).as_slice());
None None
}
} }
} }
} }
@ -288,10 +290,10 @@ fn expand_loop_block(loop_block: P<Block>,
// The rename *must* be added to the enclosed syntax context for // The rename *must* be added to the enclosed syntax context for
// `break` or `continue` to pick up because by definition they are // `break` or `continue` to pick up because by definition they are
// in a block enclosed by loop head. // in a block enclosed by loop head.
fld.extsbox.push_frame(); fld.cx.syntax_env.push_frame();
fld.extsbox.info().pending_renames.push(rename); fld.cx.syntax_env.info().pending_renames.push(rename);
let expanded_block = expand_block_elts(&*loop_block, fld); let expanded_block = expand_block_elts(&*loop_block, fld);
fld.extsbox.pop_frame(); fld.cx.syntax_env.pop_frame();
(expanded_block, Some(renamed_ident)) (expanded_block, Some(renamed_ident))
} }
@ -321,29 +323,32 @@ fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander)
for attr in it.attrs.iter() { for attr in it.attrs.iter() {
let mname = attr.name(); let mname = attr.name();
match fld.extsbox.find(&intern(mname.get())) { match fld.cx.syntax_env.find(&intern(mname.get())) {
Some(&ItemDecorator(dec_fn)) => { Some(rc) => match *rc {
attr::mark_used(attr); ItemDecorator(dec_fn) => {
attr::mark_used(attr);
fld.cx.bt_push(ExpnInfo { fld.cx.bt_push(ExpnInfo {
call_site: attr.span, call_site: attr.span,
callee: NameAndSpan { callee: NameAndSpan {
name: mname.get().to_string(), name: mname.get().to_string(),
format: MacroAttribute, format: MacroAttribute,
span: None span: None
} }
}); });
// we'd ideally decorator_items.push_all(expand_item(item, fld)), // we'd ideally decorator_items.push_all(expand_item(item, fld)),
// but that double-mut-borrows fld // but that double-mut-borrows fld
let mut items: SmallVector<Gc<ast::Item>> = SmallVector::zero(); let mut items: SmallVector<Gc<ast::Item>> = SmallVector::zero();
dec_fn(fld.cx, attr.span, attr.node.value, it, dec_fn(fld.cx, attr.span, attr.node.value, it,
|item| items.push(item)); |item| items.push(item));
decorator_items.extend(items.move_iter() decorator_items.extend(items.move_iter()
.flat_map(|item| expand_item(item, fld).move_iter())); .flat_map(|item| expand_item(item, fld).move_iter()));
fld.cx.bt_pop(); fld.cx.bt_pop();
} }
_ => new_attrs.push((*attr).clone()),
},
_ => new_attrs.push((*attr).clone()), _ => new_attrs.push((*attr).clone()),
} }
} }
@ -353,7 +358,7 @@ fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander)
ast::ItemMod(_) | ast::ItemForeignMod(_) => { ast::ItemMod(_) | ast::ItemForeignMod(_) => {
fld.cx.mod_push(it.ident); fld.cx.mod_push(it.ident);
let macro_escape = contains_macro_escape(new_attrs.as_slice()); let macro_escape = contains_macro_escape(new_attrs.as_slice());
let result = with_exts_frame!(fld.extsbox, let result = with_exts_frame!(fld.cx.syntax_env,
macro_escape, macro_escape,
noop_fold_item(&*it, fld)); noop_fold_item(&*it, fld));
fld.cx.mod_pop(); fld.cx.mod_pop();
@ -377,8 +382,8 @@ fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
-> Gc<ast::Item> { -> Gc<ast::Item> {
// partition the attributes into ItemModifiers and others // partition the attributes into ItemModifiers and others
let (modifiers, other_attrs) = it.attrs.partitioned(|attr| { let (modifiers, other_attrs) = it.attrs.partitioned(|attr| {
match fld.extsbox.find(&intern(attr.name().get())) { match fld.cx.syntax_env.find(&intern(attr.name().get())) {
Some(&ItemModifier(_)) => true, Some(rc) => match *rc { ItemModifier(_) => true, _ => false },
_ => false _ => false
} }
}); });
@ -395,20 +400,23 @@ fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
for attr in modifiers.iter() { for attr in modifiers.iter() {
let mname = attr.name(); let mname = attr.name();
match fld.extsbox.find(&intern(mname.get())) { match fld.cx.syntax_env.find(&intern(mname.get())) {
Some(&ItemModifier(dec_fn)) => { Some(rc) => match *rc {
attr::mark_used(attr); ItemModifier(dec_fn) => {
fld.cx.bt_push(ExpnInfo { attr::mark_used(attr);
call_site: attr.span, fld.cx.bt_push(ExpnInfo {
callee: NameAndSpan { call_site: attr.span,
name: mname.get().to_string(), callee: NameAndSpan {
format: MacroAttribute, name: mname.get().to_string(),
span: None, format: MacroAttribute,
} span: None,
}); }
it = dec_fn(fld.cx, attr.span, attr.node.value, it); });
fld.cx.bt_pop(); it = dec_fn(fld.cx, attr.span, attr.node.value, it);
} fld.cx.bt_pop();
}
_ => unreachable!()
},
_ => unreachable!() _ => unreachable!()
} }
} }
@ -452,7 +460,7 @@ fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
let extname = pth.segments.get(0).identifier; let extname = pth.segments.get(0).identifier;
let extnamestr = token::get_ident(extname); let extnamestr = token::get_ident(extname);
let fm = fresh_mark(); let fm = fresh_mark();
let expanded = match fld.extsbox.find(&extname.name) { let expanded = match fld.cx.syntax_env.find(&extname.name) {
None => { None => {
fld.cx.span_err(pth.span, fld.cx.span_err(pth.span,
format!("macro undefined: '{}!'", format!("macro undefined: '{}!'",
@ -461,70 +469,72 @@ fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
return SmallVector::zero(); return SmallVector::zero();
} }
Some(&NormalTT(ref expander, span)) => { Some(rc) => match *rc {
if it.ident.name != parse::token::special_idents::invalid.name { NormalTT(ref expander, span) => {
fld.cx if it.ident.name != parse::token::special_idents::invalid.name {
.span_err(pth.span, fld.cx
format!("macro {}! expects no ident argument, \ .span_err(pth.span,
given '{}'", format!("macro {}! expects no ident argument, \
extnamestr, given '{}'",
token::get_ident(it.ident)).as_slice()); extnamestr,
return SmallVector::zero(); token::get_ident(it.ident)).as_slice());
} return SmallVector::zero();
fld.cx.bt_push(ExpnInfo {
call_site: it.span,
callee: NameAndSpan {
name: extnamestr.get().to_string(),
format: MacroBang,
span: span
} }
}); fld.cx.bt_push(ExpnInfo {
// mark before expansion: call_site: it.span,
let marked_before = mark_tts(tts.as_slice(), fm); callee: NameAndSpan {
expander.expand(fld.cx, it.span, marked_before.as_slice()) name: extnamestr.get().to_string(),
} format: MacroBang,
Some(&IdentTT(ref expander, span)) => { span: span
if it.ident.name == parse::token::special_idents::invalid.name { }
fld.cx.span_err(pth.span, });
format!("macro {}! expects an ident argument", // mark before expansion:
let marked_before = mark_tts(tts.as_slice(), fm);
expander.expand(fld.cx, it.span, marked_before.as_slice())
}
IdentTT(ref expander, span) => {
if it.ident.name == parse::token::special_idents::invalid.name {
fld.cx.span_err(pth.span,
format!("macro {}! expects an ident argument",
extnamestr.get()).as_slice());
return SmallVector::zero();
}
fld.cx.bt_push(ExpnInfo {
call_site: it.span,
callee: NameAndSpan {
name: extnamestr.get().to_string(),
format: MacroBang,
span: span
}
});
// mark before expansion:
let marked_tts = mark_tts(tts.as_slice(), fm);
expander.expand(fld.cx, it.span, it.ident, marked_tts)
}
LetSyntaxTT(ref expander, span) => {
if it.ident.name == parse::token::special_idents::invalid.name {
fld.cx.span_err(pth.span,
format!("macro {}! expects an ident argument",
extnamestr.get()).as_slice());
return SmallVector::zero();
}
fld.cx.bt_push(ExpnInfo {
call_site: it.span,
callee: NameAndSpan {
name: extnamestr.get().to_string(),
format: MacroBang,
span: span
}
});
// DON'T mark before expansion:
expander.expand(fld.cx, it.span, it.ident, tts)
}
_ => {
fld.cx.span_err(it.span,
format!("{}! is not legal in item position",
extnamestr.get()).as_slice()); extnamestr.get()).as_slice());
return SmallVector::zero(); return SmallVector::zero();
} }
fld.cx.bt_push(ExpnInfo {
call_site: it.span,
callee: NameAndSpan {
name: extnamestr.get().to_string(),
format: MacroBang,
span: span
}
});
// mark before expansion:
let marked_tts = mark_tts(tts.as_slice(), fm);
expander.expand(fld.cx, it.span, it.ident, marked_tts)
}
Some(&LetSyntaxTT(ref expander, span)) => {
if it.ident.name == parse::token::special_idents::invalid.name {
fld.cx.span_err(pth.span,
format!("macro {}! expects an ident argument",
extnamestr.get()).as_slice());
return SmallVector::zero();
}
fld.cx.bt_push(ExpnInfo {
call_site: it.span,
callee: NameAndSpan {
name: extnamestr.get().to_string(),
format: MacroBang,
span: span
}
});
// DON'T mark before expansion:
expander.expand(fld.cx, it.span, it.ident, tts)
}
_ => {
fld.cx.span_err(it.span,
format!("{}! is not legal in item position",
extnamestr.get()).as_slice());
return SmallVector::zero();
} }
}; };
@ -534,7 +544,7 @@ fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
// result of expanding a LetSyntaxTT, and thus doesn't // result of expanding a LetSyntaxTT, and thus doesn't
// need to be marked. Not that it could be marked anyway. // need to be marked. Not that it could be marked anyway.
// create issue to recommend refactoring here? // create issue to recommend refactoring here?
fld.extsbox.insert(intern(name.as_slice()), ext); fld.cx.syntax_env.insert(intern(name.as_slice()), ext);
if attr::contains_name(it.attrs.as_slice(), "macro_export") { if attr::contains_name(it.attrs.as_slice(), "macro_export") {
fld.cx.exported_macros.push(it); fld.cx.exported_macros.push(it);
} }
@ -641,7 +651,7 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
rename_fld.fold_pat(expanded_pat) rename_fld.fold_pat(expanded_pat)
}; };
// add them to the existing pending renames: // add them to the existing pending renames:
fld.extsbox.info().pending_renames.push_all_move(new_pending_renames); fld.cx.syntax_env.info().pending_renames.push_all_move(new_pending_renames);
// also, don't forget to expand the init: // also, don't forget to expand the init:
let new_init_opt = init.map(|e| fld.fold_expr(e)); let new_init_opt = init.map(|e| fld.fold_expr(e));
let rewritten_local = let rewritten_local =
@ -742,7 +752,7 @@ fn fn_decl_arg_bindings(fn_decl: &ast::FnDecl) -> Vec<ast::Ident> {
// expand a block. pushes a new exts_frame, then calls expand_block_elts // expand a block. pushes a new exts_frame, then calls expand_block_elts
fn expand_block(blk: &Block, fld: &mut MacroExpander) -> P<Block> { fn expand_block(blk: &Block, fld: &mut MacroExpander) -> P<Block> {
// see note below about treatment of exts table // see note below about treatment of exts table
with_exts_frame!(fld.extsbox,false, with_exts_frame!(fld.cx.syntax_env,false,
expand_block_elts(blk, fld)) expand_block_elts(blk, fld))
} }
@ -753,7 +763,7 @@ fn expand_block_elts(b: &Block, fld: &mut MacroExpander) -> P<Block> {
b.stmts.iter().flat_map(|x| { b.stmts.iter().flat_map(|x| {
// perform all pending renames // perform all pending renames
let renamed_stmt = { let renamed_stmt = {
let pending_renames = &mut fld.extsbox.info().pending_renames; let pending_renames = &mut fld.cx.syntax_env.info().pending_renames;
let mut rename_fld = IdentRenamer{renames:pending_renames}; let mut rename_fld = IdentRenamer{renames:pending_renames};
rename_fld.fold_stmt(&**x).expect_one("rename_fold didn't return one value") rename_fld.fold_stmt(&**x).expect_one("rename_fold didn't return one value")
}; };
@ -762,7 +772,7 @@ fn expand_block_elts(b: &Block, fld: &mut MacroExpander) -> P<Block> {
}).collect(); }).collect();
let new_expr = b.expr.map(|x| { let new_expr = b.expr.map(|x| {
let expr = { let expr = {
let pending_renames = &mut fld.extsbox.info().pending_renames; let pending_renames = &mut fld.cx.syntax_env.info().pending_renames;
let mut rename_fld = IdentRenamer{renames:pending_renames}; let mut rename_fld = IdentRenamer{renames:pending_renames};
rename_fld.fold_expr(x) rename_fld.fold_expr(x)
}; };
@ -795,7 +805,7 @@ fn expand_pat(p: Gc<ast::Pat>, fld: &mut MacroExpander) -> Gc<ast::Pat> {
} }
let extname = pth.segments.get(0).identifier; let extname = pth.segments.get(0).identifier;
let extnamestr = token::get_ident(extname); let extnamestr = token::get_ident(extname);
let marked_after = match fld.extsbox.find(&extname.name) { let marked_after = match fld.cx.syntax_env.find(&extname.name) {
None => { None => {
fld.cx.span_err(pth.span, fld.cx.span_err(pth.span,
format!("macro undefined: '{}!'", format!("macro undefined: '{}!'",
@ -804,43 +814,45 @@ fn expand_pat(p: Gc<ast::Pat>, fld: &mut MacroExpander) -> Gc<ast::Pat> {
return DummyResult::raw_pat(p.span); return DummyResult::raw_pat(p.span);
} }
Some(&NormalTT(ref expander, span)) => { Some(rc) => match *rc {
fld.cx.bt_push(ExpnInfo { NormalTT(ref expander, span) => {
call_site: p.span, fld.cx.bt_push(ExpnInfo {
callee: NameAndSpan { call_site: p.span,
name: extnamestr.get().to_string(), callee: NameAndSpan {
format: MacroBang, name: extnamestr.get().to_string(),
span: span format: MacroBang,
} span: span
}); }
});
let fm = fresh_mark(); let fm = fresh_mark();
let marked_before = mark_tts(tts.as_slice(), fm); let marked_before = mark_tts(tts.as_slice(), fm);
let mac_span = original_span(fld.cx); let mac_span = original_span(fld.cx);
let expanded = match expander.expand(fld.cx, let expanded = match expander.expand(fld.cx,
mac_span.call_site, mac_span.call_site,
marked_before.as_slice()).make_pat() { marked_before.as_slice()).make_pat() {
Some(e) => e, Some(e) => e,
None => { None => {
fld.cx.span_err( fld.cx.span_err(
pth.span, pth.span,
format!( format!(
"non-pattern macro in pattern position: {}", "non-pattern macro in pattern position: {}",
extnamestr.get() extnamestr.get()
).as_slice() ).as_slice()
); );
return DummyResult::raw_pat(p.span); return DummyResult::raw_pat(p.span);
} }
}; };
// mark after: // mark after:
mark_pat(expanded,fm) mark_pat(expanded,fm)
} }
_ => { _ => {
fld.cx.span_err(p.span, fld.cx.span_err(p.span,
format!("{}! is not legal in pattern position", format!("{}! is not legal in pattern position",
extnamestr.get()).as_slice()); extnamestr.get()).as_slice());
return DummyResult::raw_pat(p.span); return DummyResult::raw_pat(p.span);
}
} }
}; };
@ -975,7 +987,6 @@ fn expand_and_rename_fn_decl_and_block(fn_decl: &ast::FnDecl, block: Gc<ast::Blo
/// A tree-folder that performs macro expansion /// A tree-folder that performs macro expansion
pub struct MacroExpander<'a, 'b> { pub struct MacroExpander<'a, 'b> {
pub extsbox: SyntaxEnv,
pub cx: &'a mut ExtCtxt<'b>, pub cx: &'a mut ExtCtxt<'b>,
} }
@ -1044,7 +1055,6 @@ pub fn expand_crate(parse_sess: &parse::ParseSess,
c: Crate) -> Crate { c: Crate) -> Crate {
let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg); let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg);
let mut expander = MacroExpander { let mut expander = MacroExpander {
extsbox: syntax_expander_table(),
cx: &mut cx, cx: &mut cx,
}; };
@ -1063,7 +1073,7 @@ pub fn expand_crate(parse_sess: &parse::ParseSess,
} }
for (name, extension) in user_exts.move_iter() { for (name, extension) in user_exts.move_iter() {
expander.extsbox.insert(name, extension); expander.cx.syntax_env.insert(name, extension);
} }
let mut ret = expander.fold_crate(c); let mut ret = expander.fold_crate(c);