summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
authorMarvin Löbel <loebel.marvin@gmail.com>2014-07-19 21:34:24 +0200
committerMarvin Löbel <loebel.marvin@gmail.com>2014-07-21 23:45:23 +0200
commit94d92e6830768cc026348766f7f74fc3fd510888 (patch)
tree633aa0b962ea285402458469ba1a4614880288da /src/libsyntax/ext
parentdf68c6f3c35354662b39128d56d5dcc6deadf591 (diff)
downloadrust-94d92e6830768cc026348766f7f74fc3fd510888.tar.gz
rust-94d92e6830768cc026348766f7f74fc3fd510888.zip
Moved `syntax::ext::base::SyntaxEnv` into `syntax::ext::base::ExtCtx`
Diffstat (limited to 'src/libsyntax/ext')
-rw-r--r--src/libsyntax/ext/base.rs36
-rw-r--r--src/libsyntax/ext/expand.rs378
2 files changed, 213 insertions, 201 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 5341f0c2d61..9160c16e0d3 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -23,6 +23,7 @@ use ext::mtwt;
 
 use std::collections::HashMap;
 use std::gc::{Gc, GC};
+use std::rc::Rc;
 
 // new-style macro! tt code:
 //
@@ -104,9 +105,9 @@ pub type IdentMacroExpanderFn =
 /// just into the compiler's internal macro table, for `make_def`).
 pub trait MacResult {
     /// Define a new macro.
-    // this particular flavor should go away; the idea that a macro might
-    // expand into either a macro definition or an expression, depending
-    // on what the context wants, is kind of silly.
+    // this should go away; the idea that a macro might expand into
+    // either a macro definition or an expression, depending on what
+    // the context wants, is kind of silly.
     fn make_def(&self) -> Option<MacroDef> {
         None
     }
@@ -314,7 +315,7 @@ impl BlockInfo {
 
 /// The base map of methods for expanding syntax extension
 /// 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
     fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
         NormalTT(box BasicMacroExpander {
@@ -431,7 +432,9 @@ pub struct ExtCtxt<'a> {
 
     pub mod_path: Vec<ast::Ident> ,
     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> {
@@ -445,6 +448,7 @@ impl<'a> ExtCtxt<'a> {
             ecfg: ecfg,
             trace_mac: false,
             exported_macros: Vec::new(),
+            syntax_env: initial_syntax_expander_table(),
         }
     }
 
@@ -453,7 +457,6 @@ impl<'a> ExtCtxt<'a> {
             match e.node {
                 ast::ExprMac(..) => {
                     let mut expander = expand::MacroExpander {
-                        extsbox: syntax_expander_table(),
                         cx: self,
                     };
                     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,
 /// we want to implement the notion of a transformation
 /// environment.
-
+///
 /// 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
 // to add an empty frame for every context. Let's just
 // get it working, first....
@@ -657,15 +663,11 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
 
 struct MapChainFrame {
     info: BlockInfo,
-    map: HashMap<Name, SyntaxExtension>,
-}
-
-pub struct SyntaxEnv {
-    chain: Vec<MapChainFrame> ,
+    map: HashMap<Name, Rc<SyntaxExtension>>,
 }
 
 impl SyntaxEnv {
-    pub fn new() -> SyntaxEnv {
+    fn new() -> SyntaxEnv {
         let mut map = SyntaxEnv { chain: Vec::new() };
         map.push_frame();
         map
@@ -692,10 +694,10 @@ impl SyntaxEnv {
         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() {
             match frame.map.find(k) {
-                Some(v) => return Some(v),
+                Some(v) => return Some(v.clone()),
                 None => {}
             }
         }
@@ -703,7 +705,7 @@ impl SyntaxEnv {
     }
 
     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 {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index c10f3ce0774..0c04c07a51e 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -208,7 +208,7 @@ fn expand_mac_invoc<T>(mac: &ast::Mac, span: &codemap::Span,
             }
             let extname = pth.segments.get(0).identifier;
             let extnamestr = token::get_ident(extname);
-            match fld.extsbox.find(&extname.name) {
+            match fld.cx.syntax_env.find(&extname.name) {
                 None => {
                     fld.cx.span_err(
                         pth.span,
@@ -218,46 +218,48 @@ fn expand_mac_invoc<T>(mac: &ast::Mac, span: &codemap::Span,
                     // let compilation continue
                     None
                 }
-                Some(&NormalTT(ref expandfun, exp_span)) => {
-                    fld.cx.bt_push(ExpnInfo {
-                            call_site: *span,
-                            callee: NameAndSpan {
-                                name: extnamestr.get().to_string(),
-                                format: MacroBang,
-                                span: exp_span,
-                            },
-                        });
-                    let fm = fresh_mark();
-                    let marked_before = mark_tts(tts.as_slice(), fm);
-
-                    // The span that we pass to the expanders we want to
-                    // be the root of the call stack. That's the most
-                    // relevant span and it's the actual invocation of
-                    // the macro.
-                    let mac_span = original_span(fld.cx);
-
-                    let expanded = expandfun.expand(fld.cx,
-                                                    mac_span.call_site,
-                                                    marked_before.as_slice());
-                    let parsed = match parse_thunk(expanded) {
-                        Some(e) => e,
-                        None => {
-                            fld.cx.span_err(
-                                pth.span,
-                                format!("non-expression macro in expression position: {}",
-                                        extnamestr.get().as_slice()
-                                        ).as_slice());
-                            return None;
-                        }
-                    };
-                    Some(mark_thunk(parsed,fm))
-                }
-                _ => {
-                    fld.cx.span_err(
-                        pth.span,
-                        format!("'{}' is not a tt-style macro",
-                                extnamestr.get()).as_slice());
-                    None
+                Some(rc) => match *rc {
+                    NormalTT(ref expandfun, exp_span) => {
+                        fld.cx.bt_push(ExpnInfo {
+                                call_site: *span,
+                                callee: NameAndSpan {
+                                    name: extnamestr.get().to_string(),
+                                    format: MacroBang,
+                                    span: exp_span,
+                                },
+                            });
+                        let fm = fresh_mark();
+                        let marked_before = mark_tts(tts.as_slice(), fm);
+
+                        // The span that we pass to the expanders we want to
+                        // be the root of the call stack. That's the most
+                        // relevant span and it's the actual invocation of
+                        // the macro.
+                        let mac_span = original_span(fld.cx);
+
+                        let expanded = expandfun.expand(fld.cx,
+                                                        mac_span.call_site,
+                                                        marked_before.as_slice());
+                        let parsed = match parse_thunk(expanded) {
+                            Some(e) => e,
+                            None => {
+                                fld.cx.span_err(
+                                    pth.span,
+                                    format!("non-expression macro in expression position: {}",
+                                            extnamestr.get().as_slice()
+                                            ).as_slice());
+                                return None;
+                            }
+                        };
+                        Some(mark_thunk(parsed,fm))
+                    }
+                    _ => {
+                        fld.cx.span_err(
+                            pth.span,
+                            format!("'{}' is not a tt-style macro",
+                                    extnamestr.get()).as_slice());
+                        None
+                    }
                 }
             }
         }
@@ -288,10 +290,10 @@ fn expand_loop_block(loop_block: P<Block>,
             // The rename *must* be added to the enclosed syntax context for
             // `break` or `continue` to pick up because by definition they are
             // in a block enclosed by loop head.
-            fld.extsbox.push_frame();
-            fld.extsbox.info().pending_renames.push(rename);
+            fld.cx.syntax_env.push_frame();
+            fld.cx.syntax_env.info().pending_renames.push(rename);
             let expanded_block = expand_block_elts(&*loop_block, fld);
-            fld.extsbox.pop_frame();
+            fld.cx.syntax_env.pop_frame();
 
             (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() {
         let mname = attr.name();
 
-        match fld.extsbox.find(&intern(mname.get())) {
-            Some(&ItemDecorator(dec_fn)) => {
-                attr::mark_used(attr);
+        match fld.cx.syntax_env.find(&intern(mname.get())) {
+            Some(rc) => match *rc {
+                ItemDecorator(dec_fn) => {
+                    attr::mark_used(attr);
 
-                fld.cx.bt_push(ExpnInfo {
-                    call_site: attr.span,
-                    callee: NameAndSpan {
-                        name: mname.get().to_string(),
-                        format: MacroAttribute,
-                        span: None
-                    }
-                });
+                    fld.cx.bt_push(ExpnInfo {
+                        call_site: attr.span,
+                        callee: NameAndSpan {
+                            name: mname.get().to_string(),
+                            format: MacroAttribute,
+                            span: None
+                        }
+                    });
 
-                // we'd ideally decorator_items.push_all(expand_item(item, fld)),
-                // but that double-mut-borrows fld
-                let mut items: SmallVector<Gc<ast::Item>> = SmallVector::zero();
-                dec_fn(fld.cx, attr.span, attr.node.value, it,
-                       |item| items.push(item));
-                decorator_items.extend(items.move_iter()
-                    .flat_map(|item| expand_item(item, fld).move_iter()));
+                    // we'd ideally decorator_items.push_all(expand_item(item, fld)),
+                    // but that double-mut-borrows fld
+                    let mut items: SmallVector<Gc<ast::Item>> = SmallVector::zero();
+                    dec_fn(fld.cx, attr.span, attr.node.value, it,
+                        |item| items.push(item));
+                    decorator_items.extend(items.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()),
         }
     }
@@ -353,7 +358,7 @@ fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander)
         ast::ItemMod(_) | ast::ItemForeignMod(_) => {
             fld.cx.mod_push(it.ident);
             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,
                                           noop_fold_item(&*it, fld));
             fld.cx.mod_pop();
@@ -377,8 +382,8 @@ fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
                          -> Gc<ast::Item> {
     // partition the attributes into ItemModifiers and others
     let (modifiers, other_attrs) = it.attrs.partitioned(|attr| {
-        match fld.extsbox.find(&intern(attr.name().get())) {
-            Some(&ItemModifier(_)) => true,
+        match fld.cx.syntax_env.find(&intern(attr.name().get())) {
+            Some(rc) => match *rc { ItemModifier(_) => true, _ => false },
             _ => false
         }
     });
@@ -395,20 +400,23 @@ fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
     for attr in modifiers.iter() {
         let mname = attr.name();
 
-        match fld.extsbox.find(&intern(mname.get())) {
-            Some(&ItemModifier(dec_fn)) => {
-                attr::mark_used(attr);
-                fld.cx.bt_push(ExpnInfo {
-                    call_site: attr.span,
-                    callee: NameAndSpan {
-                        name: mname.get().to_string(),
-                        format: MacroAttribute,
-                        span: None,
-                    }
-                });
-                it = dec_fn(fld.cx, attr.span, attr.node.value, it);
-                fld.cx.bt_pop();
-            }
+        match fld.cx.syntax_env.find(&intern(mname.get())) {
+            Some(rc) => match *rc {
+                ItemModifier(dec_fn) => {
+                    attr::mark_used(attr);
+                    fld.cx.bt_push(ExpnInfo {
+                        call_site: attr.span,
+                        callee: NameAndSpan {
+                            name: mname.get().to_string(),
+                            format: MacroAttribute,
+                            span: None,
+                        }
+                    });
+                    it = dec_fn(fld.cx, attr.span, attr.node.value, it);
+                    fld.cx.bt_pop();
+                }
+                _ => 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 extnamestr = token::get_ident(extname);
     let fm = fresh_mark();
-    let expanded = match fld.extsbox.find(&extname.name) {
+    let expanded = match fld.cx.syntax_env.find(&extname.name) {
         None => {
             fld.cx.span_err(pth.span,
                             format!("macro undefined: '{}!'",
@@ -461,70 +469,72 @@ fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
             return SmallVector::zero();
         }
 
-        Some(&NormalTT(ref expander, span)) => {
-            if it.ident.name != parse::token::special_idents::invalid.name {
-                fld.cx
-                   .span_err(pth.span,
-                             format!("macro {}! expects no ident argument, \
-                                      given '{}'",
-                                     extnamestr,
-                                     token::get_ident(it.ident)).as_slice());
-                return SmallVector::zero();
+        Some(rc) => match *rc {
+            NormalTT(ref expander, span) => {
+                if it.ident.name != parse::token::special_idents::invalid.name {
+                    fld.cx
+                    .span_err(pth.span,
+                                format!("macro {}! expects no ident argument, \
+                                        given '{}'",
+                                        extnamestr,
+                                        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
+                    }
+                });
+                // mark before expansion:
+                let marked_before = mark_tts(tts.as_slice(), fm);
+                expander.expand(fld.cx, it.span, marked_before.as_slice())
             }
-            fld.cx.bt_push(ExpnInfo {
-                call_site: it.span,
-                callee: NameAndSpan {
-                    name: extnamestr.get().to_string(),
-                    format: MacroBang,
-                    span: span
+            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();
                 }
-            });
-            // mark before expansion:
-            let marked_before = mark_tts(tts.as_slice(), fm);
-            expander.expand(fld.cx, it.span, marked_before.as_slice())
-        }
-        Some(&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)
             }
-            fld.cx.bt_push(ExpnInfo {
-                call_site: it.span,
-                callee: NameAndSpan {
-                    name: extnamestr.get().to_string(),
-                    format: MacroBang,
-                    span: span
+            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();
                 }
-            });
-            // 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",
+                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();
             }
-            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
             // need to be marked. Not that it could be marked anyway.
             // 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") {
                 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)
                     };
                     // 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:
                     let new_init_opt = init.map(|e| fld.fold_expr(e));
                     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
 fn expand_block(blk: &Block, fld: &mut MacroExpander) -> P<Block> {
     // 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))
 }
 
@@ -753,7 +763,7 @@ fn expand_block_elts(b: &Block, fld: &mut MacroExpander) -> P<Block> {
         b.stmts.iter().flat_map(|x| {
             // perform all pending renames
             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};
                 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();
     let new_expr = b.expr.map(|x| {
         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};
             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 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 => {
             fld.cx.span_err(pth.span,
                             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);
         }
 
-        Some(&NormalTT(ref expander, span)) => {
-            fld.cx.bt_push(ExpnInfo {
-                call_site: p.span,
-                callee: NameAndSpan {
-                    name: extnamestr.get().to_string(),
-                    format: MacroBang,
-                    span: span
-                }
-            });
-
-            let fm = fresh_mark();
-            let marked_before = mark_tts(tts.as_slice(), fm);
-            let mac_span = original_span(fld.cx);
-            let expanded = match expander.expand(fld.cx,
-                                   mac_span.call_site,
-                                   marked_before.as_slice()).make_pat() {
-                Some(e) => e,
-                None => {
-                    fld.cx.span_err(
-                        pth.span,
-                        format!(
-                            "non-pattern macro in pattern position: {}",
-                            extnamestr.get()
-                        ).as_slice()
-                    );
-                    return DummyResult::raw_pat(p.span);
-                }
-            };
+        Some(rc) => match *rc {
+            NormalTT(ref expander, span) => {
+                fld.cx.bt_push(ExpnInfo {
+                    call_site: p.span,
+                    callee: NameAndSpan {
+                        name: extnamestr.get().to_string(),
+                        format: MacroBang,
+                        span: span
+                    }
+                });
 
-            // mark after:
-            mark_pat(expanded,fm)
-        }
-        _ => {
-            fld.cx.span_err(p.span,
-                            format!("{}! is not legal in pattern position",
-                                    extnamestr.get()).as_slice());
-            return DummyResult::raw_pat(p.span);
+                let fm = fresh_mark();
+                let marked_before = mark_tts(tts.as_slice(), fm);
+                let mac_span = original_span(fld.cx);
+                let expanded = match expander.expand(fld.cx,
+                                    mac_span.call_site,
+                                    marked_before.as_slice()).make_pat() {
+                    Some(e) => e,
+                    None => {
+                        fld.cx.span_err(
+                            pth.span,
+                            format!(
+                                "non-pattern macro in pattern position: {}",
+                                extnamestr.get()
+                            ).as_slice()
+                        );
+                        return DummyResult::raw_pat(p.span);
+                    }
+                };
+
+                // mark after:
+                mark_pat(expanded,fm)
+            }
+            _ => {
+                fld.cx.span_err(p.span,
+                                format!("{}! is not legal in pattern position",
+                                        extnamestr.get()).as_slice());
+                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
 pub struct MacroExpander<'a, 'b> {
-    pub extsbox: SyntaxEnv,
     pub cx: &'a mut ExtCtxt<'b>,
 }
 
@@ -1044,7 +1055,6 @@ pub fn expand_crate(parse_sess: &parse::ParseSess,
                     c: Crate) -> Crate {
     let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg);
     let mut expander = MacroExpander {
-        extsbox: syntax_expander_table(),
         cx: &mut cx,
     };
 
@@ -1063,7 +1073,7 @@ pub fn expand_crate(parse_sess: &parse::ParseSess,
     }
 
     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);