about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMasaki Hara <ackie.h.gmai@gmail.com>2017-05-31 19:24:01 +0900
committerMasaki Hara <ackie.h.gmai@gmail.com>2017-05-31 19:24:01 +0900
commit54edfee71a7d2a8f710c578be75c0537a430eaaf (patch)
tree5b27adcc0f2d522fbec89b4a6eb35d073322cccb
parentf89d8d184490ecb3cf91f7b6bb7296d649f931ba (diff)
downloadrust-54edfee71a7d2a8f710c578be75c0537a430eaaf.tar.gz
rust-54edfee71a7d2a8f710c578be75c0537a430eaaf.zip
Parse macros named "default" correctly.
-rw-r--r--src/libsyntax/parse/parser.rs33
-rw-r--r--src/test/run-pass/macro-named-default.rs27
2 files changed, 41 insertions, 19 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 8d7c8c5248b..63fe33b8754 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -698,24 +698,6 @@ impl<'a> Parser<'a> {
         }
     }
 
-    pub fn check_contextual_keyword(&mut self, ident: Ident) -> bool {
-        self.expected_tokens.push(TokenType::Token(token::Ident(ident)));
-        if let token::Ident(ref cur_ident) = self.token {
-            cur_ident.name == ident.name
-        } else {
-            false
-        }
-    }
-
-    pub fn eat_contextual_keyword(&mut self, ident: Ident) -> bool {
-        if self.check_contextual_keyword(ident) {
-            self.bump();
-            true
-        } else {
-            false
-        }
-    }
-
     /// If the given word is not a keyword, signal an error.
     /// If the next token is not the given word, signal an error.
     /// Otherwise, eat it.
@@ -3755,6 +3737,18 @@ impl<'a> Parser<'a> {
         self.look_ahead(1, |t| t.is_ident() && !t.is_any_keyword())
     }
 
+    fn is_defaultness(&self) -> bool {
+        // `pub` is included for better error messages
+        self.token.is_keyword(keywords::Default) &&
+        self.look_ahead(1, |t| t.is_keyword(keywords::Impl) ||
+                        t.is_keyword(keywords::Const) ||
+                        t.is_keyword(keywords::Fn) ||
+                        t.is_keyword(keywords::Unsafe) ||
+                        t.is_keyword(keywords::Extern) ||
+                        t.is_keyword(keywords::Type) ||
+                        t.is_keyword(keywords::Pub))
+    }
+
     fn eat_macro_def(&mut self, attrs: &[Attribute], vis: &Visibility)
                      -> PResult<'a, Option<P<Item>>> {
         let lo = self.span;
@@ -5229,7 +5223,8 @@ impl<'a> Parser<'a> {
 
     /// Parse defaultness: DEFAULT or nothing
     fn parse_defaultness(&mut self) -> PResult<'a, Defaultness> {
-        if self.eat_contextual_keyword(keywords::Default.ident()) {
+        if self.is_defaultness() {
+            self.bump();
             Ok(Defaultness::Default)
         } else {
             Ok(Defaultness::Final)
diff --git a/src/test/run-pass/macro-named-default.rs b/src/test/run-pass/macro-named-default.rs
new file mode 100644
index 00000000000..028d59a19dd
--- /dev/null
+++ b/src/test/run-pass/macro-named-default.rs
@@ -0,0 +1,27 @@
+// Copyright 2017 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.
+
+macro_rules! default {
+    ($($x:tt)*) => { $($x)* }
+}
+
+default! {
+    struct A;
+}
+
+impl A {
+    default! {
+        fn foo(&self) {}
+    }
+}
+
+fn main() {
+    A.foo();
+}