diff options
| author | Mark Simulacrum <mark.simulacrum@gmail.com> | 2017-05-31 10:52:50 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-05-31 10:52:50 -0600 |
| commit | 7f286a8e38258402c6e8e564864ac0132fac2004 (patch) | |
| tree | 8c4084d31f5b5c2cbc0d4fcf7d32fe9f3f6a932f | |
| parent | 0c339ffbc0ef8130c339181e20032f5d1fbb6c76 (diff) | |
| parent | b670930933fd8af2316364d4e15e6a22983cf78d (diff) | |
Rollup merge of #42330 - qnighy:macro-named-default, r=petrochenkov
Parse macros named "default" correctly. Fixes #42292.
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 42 | ||||
| -rw-r--r-- | src/test/run-pass/macro-named-default.rs | 27 |
2 files changed, 50 insertions, 19 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 8d7c8c5248b..936a2e8b2e1 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,28 @@ 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_defaultness(&mut self) -> bool { + let is_defaultness = self.is_defaultness(); + if is_defaultness { + self.bump() + } else { + self.expected_tokens.push(TokenType::Keyword(keywords::Default)); + } + is_defaultness + } + fn eat_macro_def(&mut self, attrs: &[Attribute], vis: &Visibility) -> PResult<'a, Option<P<Item>>> { let lo = self.span; @@ -5229,7 +5233,7 @@ 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.eat_defaultness() { 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(); +} |
