about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAdolfo OchagavĂ­a <aochagavia92@gmail.com>2015-01-18 17:18:29 +0100
committerAdolfo OchagavĂ­a <aochagavia92@gmail.com>2015-01-18 19:18:48 +0100
commite3d099de6f46616ac5c0eea957ceebfa50419c6a (patch)
tree59186e9ce913c33986412bc209b258d1134103bb
parentdcaeb6aa23ecba2dc2af870668a9239136d20fa3 (diff)
downloadrust-e3d099de6f46616ac5c0eea957ceebfa50419c6a.tar.gz
rust-e3d099de6f46616ac5c0eea957ceebfa50419c6a.zip
Fix #21356
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs29
1 files changed, 15 insertions, 14 deletions
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index fc341e3bd85..957e59cbcdd 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ast::{TokenTree, TtDelimited, TtSequence, TtToken};
-use ast;
+use ast::{self, TokenTree, TtDelimited, TtSequence, TtToken};
 use codemap::{Span, DUMMY_SP};
 use ext::base::{ExtCtxt, MacResult, SyntaxExtension};
 use ext::base::{NormalTT, TTMacroExpander};
@@ -19,9 +18,8 @@ use ext::tt::macro_parser::{parse, parse_or_else};
 use parse::lexer::{new_tt_reader, new_tt_reader_with_doc_flag};
 use parse::parser::Parser;
 use parse::attr::ParserAttr;
-use parse::token::{special_idents, gensym_ident, NtTT, Token};
+use parse::token::{self, special_idents, gensym_ident, NtTT, Token};
 use parse::token::Token::*;
-use parse::token;
 use print;
 use ptr::P;
 
@@ -333,16 +331,20 @@ fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
 
                 let tok = if let TtToken(_, ref tok) = *token { tok } else { unreachable!() };
                 // If T' is in the set FOLLOW(NT), continue. Else, reject.
-                match &next_token {
-                    &Eof => return Some((sp, tok.clone())),
-                    _ if is_in_follow(cx, &next_token, frag_spec.as_str()) => continue,
-                    next => {
+                match (&next_token, is_in_follow(cx, &next_token, frag_spec.as_str())) {
+                    (&Eof, _) => return Some((sp, tok.clone())),
+                    (_, Ok(true)) => continue,
+                    (next, Ok(false)) => {
                         cx.span_err(sp, format!("`${0}:{1}` is followed by `{2}`, which \
                                                  is not allowed for `{1}` fragments",
                                                  name.as_str(), frag_spec.as_str(),
                                                  token_to_string(next)).as_slice());
                         continue
                     },
+                    (_, Err(msg)) => {
+                        cx.span_err(sp, msg.as_slice());
+                        continue
+                    }
                 }
             },
             TtSequence(sp, ref seq) => {
@@ -409,12 +411,12 @@ fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
     last
 }
 
-fn is_in_follow(cx: &ExtCtxt, tok: &Token, frag: &str) -> bool {
+fn is_in_follow(_: &ExtCtxt, tok: &Token, frag: &str) -> Result<bool, String> {
     if let &CloseDelim(_) = tok {
-        return true;
+        return Ok(true);
     }
 
-    match frag {
+    Ok(match frag {
         "item" => {
             // since items *must* be followed by either a `;` or a `}`, we can
             // accept anything after them
@@ -453,7 +455,6 @@ fn is_in_follow(cx: &ExtCtxt, tok: &Token, frag: &str) -> bool {
             // harmless
             true
         },
-        _ => cx.bug(format!("unrecognized builtin nonterminal {}",
-                            frag).as_slice()),
-    }
+        _ => return Err(format!("unrecognized builtin nonterminal `{}`", frag)),
+    })
 }