]> git.lizzy.rs Git - rust.git/blobdiff - src/libsyntax/ext/tt/macro_rules.rs
rollup merge of #17355 : gamazeps/issue17210
[rust.git] / src / libsyntax / ext / tt / macro_rules.rs
index 1eb37abb781a3d73e2f111fe4ebe734b707feed7..7a7dbc54c9ef940eda864006a669bca9a3243465 100644 (file)
@@ -8,13 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ast::{Ident, Matcher_, Matcher, MatchTok, MatchNonterminal, MatchSeq};
-use ast::{TTDelim};
+use ast::{Ident, Matcher_, Matcher, MatchTok, MatchNonterminal, MatchSeq, TTDelim};
 use ast;
 use codemap::{Span, Spanned, DUMMY_SP};
 use ext::base::{ExtCtxt, MacResult, MacroDef};
 use ext::base::{NormalTT, TTMacroExpander};
-use ext::base;
 use ext::tt::macro_parser::{Success, Error, Failure};
 use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
 use ext::tt::macro_parser::{parse, parse_or_else};
 use parse::token::{FAT_ARROW, SEMI, NtMatchers, NtTT, EOF};
 use parse::token;
 use print;
+use ptr::P;
+
 use util::small_vector::SmallVector;
 
 use std::cell::RefCell;
 use std::rc::Rc;
-use std::gc::Gc;
 
 struct ParserAnyMacro<'a> {
     parser: RefCell<Parser<'a>>,
@@ -59,17 +58,17 @@ fn ensure_complete_parse(&self, allow_semi: bool) {
 }
 
 impl<'a> MacResult for ParserAnyMacro<'a> {
-    fn make_expr(&self) -> Option<Gc<ast::Expr>> {
+    fn make_expr(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Expr>> {
         let ret = self.parser.borrow_mut().parse_expr();
         self.ensure_complete_parse(true);
         Some(ret)
     }
-    fn make_pat(&self) -> Option<Gc<ast::Pat>> {
+    fn make_pat(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Pat>> {
         let ret = self.parser.borrow_mut().parse_pat();
         self.ensure_complete_parse(false);
         Some(ret)
     }
-    fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
+    fn make_items(self: Box<ParserAnyMacro<'a>>) -> Option<SmallVector<P<ast::Item>>> {
         let mut ret = SmallVector::zero();
         loop {
             let mut parser = self.parser.borrow_mut();
@@ -85,20 +84,23 @@ fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
         Some(ret)
     }
 
-    fn make_methods(&self) -> Option<SmallVector<Gc<ast::Method>>> {
+    fn make_methods(self: Box<ParserAnyMacro<'a>>) -> Option<SmallVector<P<ast::Method>>> {
         let mut ret = SmallVector::zero();
         loop {
             let mut parser = self.parser.borrow_mut();
             match parser.token {
                 EOF => break,
-                _ => ret.push(parser.parse_method(None))
+                _ => {
+                    let attrs = parser.parse_outer_attributes();
+                    ret.push(parser.parse_method(attrs, ast::Inherited))
+                }
             }
         }
         self.ensure_complete_parse(false);
         Some(ret)
     }
 
-    fn make_stmt(&self) -> Option<Gc<ast::Stmt>> {
+    fn make_stmt(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Stmt>> {
         let attrs = self.parser.borrow_mut().parse_outer_attributes();
         let ret = self.parser.borrow_mut().parse_stmt(attrs);
         self.ensure_complete_parse(true);
@@ -113,11 +115,11 @@ struct MacroRulesMacroExpander {
 }
 
 impl TTMacroExpander for MacroRulesMacroExpander {
-    fn expand(&self,
-              cx: &mut ExtCtxt,
-              sp: Span,
-              arg: &[ast::TokenTree])
-              -> Box<MacResult> {
+    fn expand<'cx>(&self,
+                   cx: &'cx mut ExtCtxt,
+                   sp: Span,
+                   arg: &[ast::TokenTree])
+                   -> Box<MacResult+'cx> {
         generic_extension(cx,
                           sp,
                           self.name,
@@ -128,22 +130,22 @@ fn expand(&self,
 }
 
 struct MacroRulesDefiner {
-    def: RefCell<Option<MacroDef>>
+    def: Option<MacroDef>
 }
 impl MacResult for MacroRulesDefiner {
-    fn make_def(&self) -> Option<MacroDef> {
-        Some(self.def.borrow_mut().take().expect("MacroRulesDefiner expanded twice"))
+    fn make_def(&mut self) -> Option<MacroDef> {
+        Some(self.def.take().expect("empty MacroRulesDefiner"))
     }
 }
 
 /// Given `lhses` and `rhses`, this is the new macro we create
-fn generic_extension(cx: &ExtCtxt,
-                     sp: Span,
-                     name: Ident,
-                     arg: &[ast::TokenTree],
-                     lhses: &[Rc<NamedMatch>],
-                     rhses: &[Rc<NamedMatch>])
-                     -> Box<MacResult> {
+fn generic_extension<'cx>(cx: &'cx ExtCtxt,
+                          sp: Span,
+                          name: Ident,
+                          arg: &[ast::TokenTree],
+                          lhses: &[Rc<NamedMatch>],
+                          rhses: &[Rc<NamedMatch>])
+                          -> Box<MacResult+'cx> {
     if cx.trace_macros() {
         println!("{}! {} {} {}",
                  token::get_ident(name),
@@ -171,8 +173,8 @@ fn generic_extension(cx: &ExtCtxt,
               Success(named_matches) => {
                 let rhs = match *rhses[i] {
                     // okay, what's your transcriber?
-                    MatchedNonterminal(NtTT(tt)) => {
-                        match *tt {
+                    MatchedNonterminal(NtTT(ref tt)) => {
+                        match **tt {
                             // cut off delimiters; don't parse 'em
                             TTDelim(ref tts) => {
                                 (*tts).slice(1u,(*tts).len()-1u)
@@ -195,7 +197,7 @@ fn generic_extension(cx: &ExtCtxt,
                 // Weird, but useful for X-macros.
                 return box ParserAnyMacro {
                     parser: RefCell::new(p),
-                } as Box<MacResult>
+                } as Box<MacResult+'cx>
               }
               Failure(sp, ref msg) => if sp.lo >= best_fail_spot.lo {
                 best_fail_spot = sp;
@@ -213,11 +215,11 @@ fn generic_extension(cx: &ExtCtxt,
 /// This procedure performs the expansion of the
 /// macro_rules! macro. It parses the RHS and adds
 /// an extension to the current context.
-pub fn add_new_extension(cx: &mut ExtCtxt,
-                         sp: Span,
-                         name: Ident,
-                         arg: Vec<ast::TokenTree> )
-                         -> Box<base::MacResult> {
+pub fn add_new_extension<'cx>(cx: &'cx mut ExtCtxt,
+                              sp: Span,
+                              name: Ident,
+                              arg: Vec<ast::TokenTree> )
+                              -> Box<MacResult+'cx> {
     // these spans won't matter, anyways
     fn ms(m: Matcher_) -> Matcher {
         Spanned {
@@ -270,9 +272,9 @@ fn ms(m: Matcher_) -> Matcher {
     };
 
     box MacroRulesDefiner {
-        def: RefCell::new(Some(MacroDef {
+        def: Some(MacroDef {
             name: token::get_ident(name).to_string(),
             ext: NormalTT(exp, Some(sp))
-        }))
-    } as Box<MacResult>
+        })
+    } as Box<MacResult+'cx>
 }