about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_driver/driver.rs2
-rw-r--r--src/librustc_plugin/registry.rs6
-rw-r--r--src/libsyntax/ext/base.rs9
-rw-r--r--src/libsyntax/ext/expand.rs59
-rw-r--r--src/libsyntax/ext/placeholders.rs13
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs39
-rw-r--r--src/libsyntax_ext/lib.rs5
-rw-r--r--src/test/compile-fail-fulldeps/auxiliary/macro_crate_MacroRulesTT.rs26
-rw-r--r--src/test/compile-fail-fulldeps/plugin-MacroRulesTT.rs18
9 files changed, 63 insertions, 114 deletions
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 36e9fccdf5f..f07025910f0 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -674,11 +674,11 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
         }
         let features = sess.features.borrow();
         let cfg = syntax::ext::expand::ExpansionConfig {
-            crate_name: crate_name.to_string(),
             features: Some(&features),
             recursion_limit: sess.recursion_limit.get(),
             trace_mac: sess.opts.debugging_opts.trace_macros,
             should_test: sess.opts.test,
+            ..syntax::ext::expand::ExpansionConfig::default(crate_name.to_string())
         };
         let mut ecx = ExtCtxt::new(&sess.parse_sess, krate.config.clone(), cfg, &mut resolver);
         let ret = syntax::ext::expand::expand_crate(&mut ecx, syntax_exts, krate);
diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs
index 435196d9561..8f0cc2c3d75 100644
--- a/src/librustc_plugin/registry.rs
+++ b/src/librustc_plugin/registry.rs
@@ -17,7 +17,7 @@ use rustc::mir::transform::MirMapPass;
 
 use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT};
 use syntax::ext::base::{IdentTT, MultiModifier, MultiDecorator};
-use syntax::ext::base::{MacroExpanderFn, MacroRulesTT};
+use syntax::ext::base::MacroExpanderFn;
 use syntax::parse::token;
 use syntax::ast;
 use syntax::feature_gate::AttributeType;
@@ -111,10 +111,6 @@ impl<'a> Registry<'a> {
             }
             MultiDecorator(ext) => MultiDecorator(ext),
             MultiModifier(ext) => MultiModifier(ext),
-            MacroRulesTT => {
-                self.sess.err("plugin tried to register a new MacroRulesTT");
-                return;
-            }
         }));
     }
 
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index fb4816d3847..9d0d74138cd 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -177,7 +177,8 @@ pub trait IdentMacroExpander {
                    cx: &'cx mut ExtCtxt,
                    sp: Span,
                    ident: ast::Ident,
-                   token_tree: Vec<tokenstream::TokenTree> )
+                   token_tree: Vec<tokenstream::TokenTree>,
+                   attrs: Vec<ast::Attribute>)
                    -> Box<MacResult+'cx>;
 }
 
@@ -193,7 +194,8 @@ impl<F> IdentMacroExpander for F
                    cx: &'cx mut ExtCtxt,
                    sp: Span,
                    ident: ast::Ident,
-                   token_tree: Vec<tokenstream::TokenTree> )
+                   token_tree: Vec<tokenstream::TokenTree>,
+                   _attrs: Vec<ast::Attribute>)
                    -> Box<MacResult+'cx>
     {
         (*self)(cx, sp, ident, token_tree)
@@ -455,9 +457,6 @@ pub enum SyntaxExtension {
     /// the block.
     ///
     IdentTT(Box<IdentMacroExpander + 'static>, Option<Span>, bool),
-
-    /// Represents `macro_rules!` itself.
-    MacroRulesTT,
 }
 
 pub type NamedSyntaxExtension = (Name, SyntaxExtension);
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 62e299684b7..4e87d8ee9dd 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -12,7 +12,7 @@ use ast::{Block, Crate, Ident, Mac_, PatKind};
 use ast::{MacStmtStyle, StmtKind, ItemKind};
 use ast;
 use ext::hygiene::Mark;
-use ext::placeholders::{self, placeholder, PlaceholderExpander};
+use ext::placeholders::{placeholder, PlaceholderExpander};
 use attr::{self, HasAttrs};
 use codemap::{ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
 use syntax_pos::{self, Span, ExpnId};
@@ -173,19 +173,12 @@ impl Invocation {
 
 pub struct MacroExpander<'a, 'b:'a> {
     pub cx: &'a mut ExtCtxt<'b>,
-    pub single_step: bool,
-    pub keep_macs: bool,
     monotonic: bool, // c.f. `cx.monotonic_expander()`
 }
 
 impl<'a, 'b> MacroExpander<'a, 'b> {
     pub fn new(cx: &'a mut ExtCtxt<'b>, monotonic: bool) -> Self {
-        MacroExpander {
-            cx: cx,
-            monotonic: monotonic,
-            single_step: false,
-            keep_macs: false,
-        }
+        MacroExpander { cx: cx, monotonic: monotonic }
     }
 
     fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
@@ -238,7 +231,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 expansions.push(Vec::new());
             }
             expansions[depth].push((mark.as_u32(), expansion));
-            if !self.single_step {
+            if !self.cx.ecfg.single_step {
                 invocations.extend(new_invocations.into_iter().rev());
             }
         }
@@ -381,47 +374,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                     }
                 });
 
-                kind.make_from(expander.expand(self.cx, span, ident, marked_tts))
-            }
-
-            MacroRulesTT => {
-                if ident.name == keywords::Invalid.name() {
-                    self.cx.span_err(path.span,
-                                    &format!("macro {}! expects an ident argument", extname));
-                    return kind.dummy(span);
-                };
-
-                self.cx.bt_push(ExpnInfo {
-                    call_site: span,
-                    callee: NameAndSpan {
-                        format: MacroBang(extname),
-                        span: None,
-                        // `macro_rules!` doesn't directly allow unstable
-                        // (this is orthogonal to whether the macro it creates allows it)
-                        allow_internal_unstable: false,
-                    }
-                });
-
-                let def = ast::MacroDef {
-                    ident: ident,
-                    id: ast::DUMMY_NODE_ID,
-                    span: span,
-                    imported_from: None,
-                    use_locally: true,
-                    body: marked_tts,
-                    export: attr::contains_name(&attrs, "macro_export"),
-                    allow_internal_unstable: attr::contains_name(&attrs, "allow_internal_unstable"),
-                    attrs: attrs,
-                };
-
-                self.cx.insert_macro(def.clone());
-
-                // If keep_macs is true, expands to a MacEager::items instead.
-                if self.keep_macs {
-                    Some(placeholders::reconstructed_macro_rules(&def, &path))
-                } else {
-                    Some(placeholders::macro_scope_placeholder())
-                }
+                kind.make_from(expander.expand(self.cx, span, ident, marked_tts, attrs))
             }
 
             MultiDecorator(..) | MultiModifier(..) => {
@@ -726,6 +679,8 @@ pub struct ExpansionConfig<'feat> {
     pub recursion_limit: usize,
     pub trace_mac: bool,
     pub should_test: bool, // If false, strip `#[test]` nodes
+    pub single_step: bool,
+    pub keep_macs: bool,
 }
 
 macro_rules! feature_tests {
@@ -749,6 +704,8 @@ impl<'feat> ExpansionConfig<'feat> {
             recursion_limit: 64,
             trace_mac: false,
             should_test: false,
+            single_step: false,
+            keep_macs: false,
         }
     }
 
diff --git a/src/libsyntax/ext/placeholders.rs b/src/libsyntax/ext/placeholders.rs
index 47f366a8876..0ede6dd98e5 100644
--- a/src/libsyntax/ext/placeholders.rs
+++ b/src/libsyntax/ext/placeholders.rs
@@ -13,7 +13,7 @@ use codemap::{DUMMY_SP, dummy_spanned};
 use ext::base::ExtCtxt;
 use ext::expand::{Expansion, ExpansionKind};
 use fold::*;
-use parse::token::keywords;
+use parse::token::{intern, keywords};
 use ptr::P;
 use util::move_map::MoveMap;
 use util::small_vector::SmallVector;
@@ -214,7 +214,7 @@ impl<'a, 'b> Folder for PlaceholderExpander<'a, 'b> {
     }
 }
 
-pub fn reconstructed_macro_rules(def: &ast::MacroDef, path: &ast::Path) -> Expansion {
+pub fn reconstructed_macro_rules(def: &ast::MacroDef) -> Expansion {
     Expansion::Items(SmallVector::one(P(ast::Item {
         ident: def.ident,
         attrs: def.attrs.clone(),
@@ -222,7 +222,14 @@ pub fn reconstructed_macro_rules(def: &ast::MacroDef, path: &ast::Path) -> Expan
         node: ast::ItemKind::Mac(ast::Mac {
             span: def.span,
             node: ast::Mac_ {
-                path: path.clone(),
+                path: ast::Path {
+                    span: DUMMY_SP,
+                    global: false,
+                    segments: vec![ast::PathSegment {
+                        identifier: ast::Ident::with_empty_ctxt(intern("macro_rules")),
+                        parameters: ast::PathParameters::none(),
+                    }],
+                },
                 tts: def.body.clone(),
             }
         }),
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 51ef45b97be..da82c9ffab1 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -8,10 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ast;
+use {ast, attr};
 use syntax_pos::{Span, DUMMY_SP};
-use ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension};
-use ext::base::{NormalTT, TTMacroExpander};
+use ext::base::{DummyResult, ExtCtxt, MacEager, MacResult, SyntaxExtension};
+use ext::base::{IdentMacroExpander, NormalTT, TTMacroExpander};
+use ext::placeholders;
 use ext::tt::macro_parser::{Success, Error, Failure};
 use ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
 use ext::tt::macro_parser::parse;
@@ -242,6 +243,38 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
      cx.span_fatal(best_fail_spot.substitute_dummy(sp), &best_fail_msg[..]);
 }
 
+pub struct MacroRulesExpander;
+impl IdentMacroExpander for MacroRulesExpander {
+    fn expand(&self,
+              cx: &mut ExtCtxt,
+              span: Span,
+              ident: ast::Ident,
+              tts: Vec<tokenstream::TokenTree>,
+              attrs: Vec<ast::Attribute>)
+              -> Box<MacResult> {
+        let def = ast::MacroDef {
+            ident: ident,
+            id: ast::DUMMY_NODE_ID,
+            span: span,
+            imported_from: None,
+            use_locally: true,
+            body: tts,
+            export: attr::contains_name(&attrs, "macro_export"),
+            allow_internal_unstable: attr::contains_name(&attrs, "allow_internal_unstable"),
+            attrs: attrs,
+        };
+
+        cx.insert_macro(def.clone());
+
+        // If keep_macs is true, expands to a MacEager::items instead.
+        if cx.ecfg.keep_macs {
+            MacEager::items(placeholders::reconstructed_macro_rules(&def).make_items())
+        } else {
+            MacEager::items(placeholders::macro_scope_placeholder().make_items())
+        }
+    }
+}
+
 // Note that macro-by-example's input is also matched against a token tree:
 //                   $( $lhs:tt => $rhs:tt );+
 //
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index 3a6212e5445..e0c028195ba 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -50,8 +50,9 @@ pub mod deriving;
 
 use std::rc::Rc;
 use syntax::ast;
-use syntax::ext::base::{MacroExpanderFn, MacroRulesTT, NormalTT, MultiModifier};
+use syntax::ext::base::{MacroExpanderFn, NormalTT, IdentTT, MultiModifier};
 use syntax::ext::hygiene::Mark;
+use syntax::ext::tt::macro_rules::MacroRulesExpander;
 use syntax::parse::token::intern;
 
 pub fn register_builtins(resolver: &mut syntax::ext::base::Resolver, enable_quotes: bool) {
@@ -59,7 +60,7 @@ pub fn register_builtins(resolver: &mut syntax::ext::base::Resolver, enable_quot
         resolver.add_macro(Mark::root(), ast::Ident::with_empty_ctxt(intern(name)), Rc::new(ext));
     };
 
-    register("macro_rules", MacroRulesTT);
+    register("macro_rules", IdentTT(Box::new(MacroRulesExpander), None, false));
 
     macro_rules! register {
         ($( $name:ident: $f:expr, )*) => { $(
diff --git a/src/test/compile-fail-fulldeps/auxiliary/macro_crate_MacroRulesTT.rs b/src/test/compile-fail-fulldeps/auxiliary/macro_crate_MacroRulesTT.rs
deleted file mode 100644
index 9e693fcc564..00000000000
--- a/src/test/compile-fail-fulldeps/auxiliary/macro_crate_MacroRulesTT.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// force-host
-
-#![feature(plugin_registrar, rustc_private)]
-
-extern crate syntax;
-extern crate rustc;
-extern crate rustc_plugin;
-
-use syntax::parse::token;
-use syntax::ext::base::MacroRulesTT;
-use rustc_plugin::Registry;
-
-#[plugin_registrar]
-pub fn plugin_registrar(reg: &mut Registry) {
-    reg.register_syntax_extension(token::intern("bogus"), MacroRulesTT);
-}
diff --git a/src/test/compile-fail-fulldeps/plugin-MacroRulesTT.rs b/src/test/compile-fail-fulldeps/plugin-MacroRulesTT.rs
deleted file mode 100644
index e13ddd13f5d..00000000000
--- a/src/test/compile-fail-fulldeps/plugin-MacroRulesTT.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:macro_crate_MacroRulesTT.rs
-// ignore-stage1
-// error-pattern: plugin tried to register a new MacroRulesTT
-
-#![feature(plugin)]
-#![plugin(macro_crate_MacroRulesTT)]
-
-fn main() { }