From 5916da2c29d7e0f12057a44702c12cb40edb38f8 Mon Sep 17 00:00:00 2001 From: Johann Hemmann Date: Mon, 8 Jan 2024 19:40:13 +0100 Subject: [PATCH 1/2] Handle `macro_rules!` as MACRO_CALL It's a call of the third token is neither IDENT or TRY --- crates/parser/src/grammar/items.rs | 26 +++++- .../err/0026_macro_rules_as_macro_name.rast | 25 ++++++ .../err/0026_macro_rules_as_macro_name.rs | 2 + .../ok/0208_macro_rules_as_macro_name.rast | 84 +++++++++++++++++++ .../ok/0208_macro_rules_as_macro_name.rs | 7 ++ 5 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rast create mode 100644 crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rs create mode 100644 crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rast create mode 100644 crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rs diff --git a/crates/parser/src/grammar/items.rs b/crates/parser/src/grammar/items.rs index 34fd3420f1..5050cad5e8 100644 --- a/crates/parser/src/grammar/items.rs +++ b/crates/parser/src/grammar/items.rs @@ -58,7 +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) { + // test macro_rules_as_macro_name + // macro_rules! {} + // macro_rules! {}; + // macro_rules! (); + // macro_rules! []; + // fn main() { + // let foo = macro_rules!(); + // } + + // test_err macro_rules_as_macro_name + // macro_rules! () + // macro_rules! [] + if paths::is_use_path_start(p) + || (p.at_contextual_kw(T![macro_rules]) && p.nth_at(1, BANG) && !p.nth_at(2, IDENT)) + { match macro_call(p) { BlockLike::Block => (), BlockLike::NotBlock => { @@ -228,7 +242,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), diff --git a/crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rast b/crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rast new file mode 100644 index 0000000000..d5ab611629 --- /dev/null +++ b/crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rast @@ -0,0 +1,25 @@ +SOURCE_FILE + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "macro_rules" + BANG "!" + WHITESPACE " " + TOKEN_TREE + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "macro_rules" + BANG "!" + WHITESPACE " " + TOKEN_TREE + L_BRACK "[" + R_BRACK "]" + WHITESPACE "\n" +error 15: expected SEMICOLON +error 31: expected SEMICOLON diff --git a/crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rs b/crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rs new file mode 100644 index 0000000000..be633aa699 --- /dev/null +++ b/crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rs @@ -0,0 +1,2 @@ +macro_rules! () +macro_rules! [] diff --git a/crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rast b/crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rast new file mode 100644 index 0000000000..c3e0f8a5e0 --- /dev/null +++ b/crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rast @@ -0,0 +1,84 @@ +SOURCE_FILE + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "macro_rules" + BANG "!" + WHITESPACE " " + TOKEN_TREE + L_CURLY "{" + R_CURLY "}" + WHITESPACE "\n" + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "macro_rules" + BANG "!" + WHITESPACE " " + TOKEN_TREE + L_CURLY "{" + R_CURLY "}" + SEMICOLON ";" + WHITESPACE "\n" + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "macro_rules" + BANG "!" + WHITESPACE " " + TOKEN_TREE + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "macro_rules" + BANG "!" + WHITESPACE " " + TOKEN_TREE + L_BRACK "[" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n" + FN + FN_KW "fn" + WHITESPACE " " + NAME + IDENT "main" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + WHITESPACE "\n " + LET_STMT + LET_KW "let" + WHITESPACE " " + IDENT_PAT + NAME + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + MACRO_EXPR + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "macro_rules" + BANG "!" + TOKEN_TREE + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + R_CURLY "}" + WHITESPACE "\n" diff --git a/crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rs b/crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rs new file mode 100644 index 0000000000..2ab949b636 --- /dev/null +++ b/crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rs @@ -0,0 +1,7 @@ +macro_rules! {} +macro_rules! {}; +macro_rules! (); +macro_rules! []; +fn main() { + let foo = macro_rules!(); +} From 76c67dd2291a662b40b9867c0f6bb564e5783889 Mon Sep 17 00:00:00 2001 From: Johann Hemmann Date: Wed, 17 Jan 2024 12:24:18 +0100 Subject: [PATCH 2/2] Fix test --- crates/parser/src/grammar/items.rs | 2 +- .../err/0026_macro_rules_as_macro_name.rast | 18 ++++++++++++++++-- .../err/0026_macro_rules_as_macro_name.rs | 1 + .../ok/0208_macro_rules_as_macro_name.rast | 12 ------------ .../ok/0208_macro_rules_as_macro_name.rs | 1 - 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/crates/parser/src/grammar/items.rs b/crates/parser/src/grammar/items.rs index 5050cad5e8..7934761705 100644 --- a/crates/parser/src/grammar/items.rs +++ b/crates/parser/src/grammar/items.rs @@ -60,7 +60,6 @@ pub(super) fn item_or_macro(p: &mut Parser<'_>, stop_on_r_curly: bool) { // test macro_rules_as_macro_name // macro_rules! {} - // macro_rules! {}; // macro_rules! (); // macro_rules! []; // fn main() { @@ -68,6 +67,7 @@ pub(super) fn item_or_macro(p: &mut Parser<'_>, stop_on_r_curly: bool) { // } // test_err macro_rules_as_macro_name + // macro_rules! {}; // macro_rules! () // macro_rules! [] if paths::is_use_path_start(p) diff --git a/crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rast b/crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rast index d5ab611629..79d428a41c 100644 --- a/crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rast +++ b/crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rast @@ -1,4 +1,17 @@ SOURCE_FILE + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "macro_rules" + BANG "!" + WHITESPACE " " + TOKEN_TREE + L_CURLY "{" + R_CURLY "}" + ERROR + SEMICOLON ";" + WHITESPACE "\n" MACRO_CALL PATH PATH_SEGMENT @@ -21,5 +34,6 @@ SOURCE_FILE L_BRACK "[" R_BRACK "]" WHITESPACE "\n" -error 15: expected SEMICOLON -error 31: expected SEMICOLON +error 15: expected an item +error 32: expected SEMICOLON +error 48: expected SEMICOLON diff --git a/crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rs b/crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rs index be633aa699..e8d402443d 100644 --- a/crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rs +++ b/crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rs @@ -1,2 +1,3 @@ +macro_rules! {}; macro_rules! () macro_rules! [] diff --git a/crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rast b/crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rast index c3e0f8a5e0..b997250ab4 100644 --- a/crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rast +++ b/crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rast @@ -10,18 +10,6 @@ SOURCE_FILE L_CURLY "{" R_CURLY "}" WHITESPACE "\n" - MACRO_CALL - PATH - PATH_SEGMENT - NAME_REF - IDENT "macro_rules" - BANG "!" - WHITESPACE " " - TOKEN_TREE - L_CURLY "{" - R_CURLY "}" - SEMICOLON ";" - WHITESPACE "\n" MACRO_CALL PATH PATH_SEGMENT diff --git a/crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rs b/crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rs index 2ab949b636..4c2ea378cb 100644 --- a/crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rs +++ b/crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rs @@ -1,5 +1,4 @@ macro_rules! {} -macro_rules! {}; macro_rules! (); macro_rules! []; fn main() {