Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/parser/src/grammar/items.rs')
-rw-r--r--crates/parser/src/grammar/items.rs43
1 files changed, 32 insertions, 11 deletions
diff --git a/crates/parser/src/grammar/items.rs b/crates/parser/src/grammar/items.rs
index 34fd3420f1..caf2a005a7 100644
--- a/crates/parser/src/grammar/items.rs
+++ b/crates/parser/src/grammar/items.rs
@@ -58,14 +58,21 @@ pub(super) fn item_or_macro(p: &mut Parser<'_>, stop_on_r_curly: bool) {
Err(m) => m,
};
- if paths::is_use_path_start(p) {
- match macro_call(p) {
- BlockLike::Block => (),
- BlockLike::NotBlock => {
- p.expect(T![;]);
- }
- }
- m.complete(p, MACRO_CALL);
+ // test macro_rules_as_macro_name
+ // macro_rules! {}
+ // macro_rules! ();
+ // macro_rules! [];
+ // fn main() {
+ // let foo = macro_rules!();
+ // }
+
+ // test_err macro_rules_as_macro_name
+ // macro_rules! {};
+ // macro_rules! ()
+ // macro_rules! []
+ let no_ident = p.at_contextual_kw(T![macro_rules]) && p.nth_at(1, BANG) && !p.nth_at(2, IDENT);
+ if paths::is_use_path_start(p) || no_ident {
+ macro_call(p, m);
return;
}
@@ -228,7 +235,15 @@ fn opt_item_without_modifiers(p: &mut Parser<'_>, m: Marker) -> Result<(), Marke
IDENT if p.at_contextual_kw(T![union]) && p.nth(1) == IDENT => adt::union(p, m),
T![macro] => macro_def(p, m),
- IDENT if p.at_contextual_kw(T![macro_rules]) && p.nth(1) == BANG => macro_rules(p, m),
+ // check if current token is "macro_rules" followed by "!" followed by an identifier or "try"
+ // try is keyword since the 2018 edition and the parser is not edition aware (yet!)
+ IDENT
+ if p.at_contextual_kw(T![macro_rules])
+ && p.nth_at(1, BANG)
+ && (p.nth_at(2, IDENT) || p.nth_at(2, T![try])) =>
+ {
+ macro_rules(p, m)
+ }
T![const] if (la == IDENT || la == T![_] || la == T![mut]) => consts::konst(p, m),
T![static] if (la == IDENT || la == T![_] || la == T![mut]) => consts::static_(p, m),
@@ -414,10 +429,16 @@ fn fn_(p: &mut Parser<'_>, m: Marker) {
m.complete(p, FN);
}
-fn macro_call(p: &mut Parser<'_>) -> BlockLike {
+fn macro_call(p: &mut Parser<'_>, m: Marker) {
assert!(paths::is_use_path_start(p));
paths::use_path(p);
- macro_call_after_excl(p)
+ match macro_call_after_excl(p) {
+ BlockLike::Block => (),
+ BlockLike::NotBlock => {
+ p.expect(T![;]);
+ }
+ }
+ m.complete(p, MACRO_CALL);
}
pub(super) fn macro_call_after_excl(p: &mut Parser<'_>) -> BlockLike {