Handle macro_rules! as MACRO_CALL

It's a call of the third token is neither IDENT or TRY
This commit is contained in:
Johann Hemmann 2024-01-08 19:40:13 +01:00
parent 2b02df27c5
commit 5916da2c29
5 changed files with 142 additions and 2 deletions

View file

@ -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),

View file

@ -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

View file

@ -0,0 +1,2 @@
macro_rules! ()
macro_rules! []

View file

@ -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"

View file

@ -0,0 +1,7 @@
macro_rules! {}
macro_rules! {};
macro_rules! ();
macro_rules! [];
fn main() {
let foo = macro_rules!();
}