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.rs | 43 |
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 { |