about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-09-23 23:09:23 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-09-26 04:29:30 +0000
commitb90ceddcee2e7f4ed4236e6c52ddf8e585f3df6a (patch)
tree583c922fd2e8b1678f08b4a8872a533edde65f4b /src/libsyntax
parent4a8467b62d572eabedf50c09b52f177e87160e96 (diff)
downloadrust-b90ceddcee2e7f4ed4236e6c52ddf8e585f3df6a.tar.gz
rust-b90ceddcee2e7f4ed4236e6c52ddf8e585f3df6a.zip
Refactor `ensure_complete_parse`.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ext/expand.rs20
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs35
-rw-r--r--src/libsyntax/parse/parser.rs21
3 files changed, 31 insertions, 45 deletions
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 0d4e3ebdd20..62339695807 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use ast::{Block, Crate, Ident, Mac_, PatKind};
-use ast::{MacStmtStyle, StmtKind, ItemKind};
+use ast::{Name, MacStmtStyle, StmtKind, ItemKind};
 use ast;
 use ext::hygiene::Mark;
 use ext::placeholders::{placeholder, PlaceholderExpander};
@@ -299,10 +299,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         };
 
         attr::mark_used(&attr);
+        let name = intern(&attr.name());
         self.cx.bt_push(ExpnInfo {
             call_site: attr.span,
             callee: NameAndSpan {
-                format: MacroAttribute(intern(&attr.name())),
+                format: MacroAttribute(name),
                 span: Some(attr.span),
                 allow_internal_unstable: false,
             }
@@ -325,7 +326,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 let item_toks = TokenStream::from_tts(tts_for_item(&item, &self.cx.parse_sess));
 
                 let tok_result = mac.expand(self.cx, attr.span, attr_toks, item_toks);
-                self.parse_expansion(tok_result, kind, attr.span)
+                self.parse_expansion(tok_result, kind, name, attr.span)
             }
             _ => unreachable!(),
         }
@@ -424,7 +425,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
 
                 let toks = TokenStream::from_tts(marked_tts);
                 let tok_result = expandfun.expand(self.cx, span, toks);
-                Some(self.parse_expansion(tok_result, kind, span))
+                Some(self.parse_expansion(tok_result, kind, extname, span))
             }
         };
 
@@ -443,7 +444,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         })
     }
 
-    fn parse_expansion(&mut self, toks: TokenStream, kind: ExpansionKind, span: Span) -> Expansion {
+    fn parse_expansion(&mut self, toks: TokenStream, kind: ExpansionKind, name: Name, span: Span)
+                       -> Expansion {
         let mut parser = self.cx.new_parser_from_tts(&toks.to_tts());
         let expansion = match parser.parse_expansion(kind, false) {
             Ok(expansion) => expansion,
@@ -452,13 +454,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 return kind.dummy(span);
             }
         };
-        parser.ensure_complete_parse(kind == ExpansionKind::Expr, |parser| {
-            let msg = format!("macro expansion ignores token `{}` and any following",
-                              parser.this_token_to_string());
-            parser.diagnostic().struct_span_err(parser.span, &msg)
-                .span_note(span, "caused by the macro expansion here")
-                .emit();
-        });
+        parser.ensure_complete_parse(name, kind.name(), span);
         // FIXME better span info
         expansion.fold_with(&mut ChangeSpan { span: span })
     }
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index e78eeb8f7a4..d222de2dd36 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -39,32 +39,19 @@ pub struct ParserAnyMacro<'a> {
 }
 
 impl<'a> ParserAnyMacro<'a> {
-    /// Make sure we don't have any tokens left to parse, so we don't
-    /// silently drop anything. `allow_semi` is so that "optional"
-    /// semicolons at the end of normal expressions aren't complained
-    /// about e.g. the semicolon in `macro_rules! kapow { () => {
-    /// panic!(); } }` doesn't get picked up by .parse_expr(), but it's
-    /// allowed to be there.
-    fn ensure_complete_parse(&mut self, allow_semi: bool, context: &str) {
+    pub fn make(mut self: Box<ParserAnyMacro<'a>>, kind: ExpansionKind) -> Expansion {
         let ParserAnyMacro { site_span, macro_ident, ref mut parser } = *self;
-        parser.ensure_complete_parse(allow_semi, |parser| {
-            let token_str = parser.this_token_to_string();
-            let msg = format!("macro expansion ignores token `{}` and any \
-                               following",
-                              token_str);
-            let span = parser.span;
-            let mut err = parser.diagnostic().struct_span_err(span, &msg);
-            let msg = format!("caused by the macro expansion here; the usage \
-                               of `{}!` is likely invalid in {} context",
-                               macro_ident, context);
-            err.span_note(site_span, &msg)
-               .emit();
-        });
-    }
+        let expansion = panictry!(parser.parse_expansion(kind, true));
 
-    pub fn make(mut self: Box<ParserAnyMacro<'a>>, kind: ExpansionKind) -> Expansion {
-        let expansion = panictry!(self.parser.parse_expansion(kind, true));
-        self.ensure_complete_parse(kind == ExpansionKind::Expr, kind.name());
+        // We allow semicolons at the end of expressions -- e.g. the semicolon in
+        // `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`,
+        // but `m!()` is allowed in expression positions (c.f. issue #34706).
+        if kind == ExpansionKind::Expr && parser.token == token::Semi {
+            parser.bump();
+        }
+
+        // Make sure we don't have any tokens left to parse so we don't silently drop anything.
+        parser.ensure_complete_parse(macro_ident.name, kind.name(), site_span);
         expansion
     }
 }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 23085fadc5e..410ecf068b9 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -6172,14 +6172,17 @@ impl<'a> Parser<'a> {
         }
     }
 
-    pub fn ensure_complete_parse<F>(&mut self, allow_semi: bool, on_err: F)
-        where F: FnOnce(&Parser)
-    {
-        if allow_semi && self.token == token::Semi {
-            self.bump();
-        }
-        if self.token != token::Eof {
-            on_err(self);
-        }
+    pub fn ensure_complete_parse(&mut self, macro_name: ast::Name, kind_name: &str, span: Span) {
+        if self.token == token::Eof {
+            return
+        }
+
+        let msg = format!("macro expansion ignores token `{}` and any following",
+                          self.this_token_to_string());
+        let mut err = self.diagnostic().struct_span_err(self.span, &msg);
+        let msg = format!("caused by the macro expansion here; the usage \
+                           of `{}!` is likely invalid in {} context",
+                           macro_name, kind_name);
+        err.span_note(span, &msg).emit();
     }
 }