Skip to content

Commit c820980

Browse files
committed
Auto merge of rust-lang#16314 - Urhengulas:macro_rule-as-macro-name, r=Veykril
`macro_rules` as macro name This PR makes RA parse `macro_rules! {}` (note the missing identifier) as a `MACRO_CALL` instead of `MACRO_RULES`. Fixes rust-lang#15969.
2 parents 2b02df2 + 76c67dd commit c820980

File tree

5 files changed

+144
-2
lines changed

5 files changed

+144
-2
lines changed

crates/parser/src/grammar/items.rs

+24-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,21 @@ pub(super) fn item_or_macro(p: &mut Parser<'_>, stop_on_r_curly: bool) {
5858
Err(m) => m,
5959
};
6060

61-
if paths::is_use_path_start(p) {
61+
// test macro_rules_as_macro_name
62+
// macro_rules! {}
63+
// macro_rules! ();
64+
// macro_rules! [];
65+
// fn main() {
66+
// let foo = macro_rules!();
67+
// }
68+
69+
// test_err macro_rules_as_macro_name
70+
// macro_rules! {};
71+
// macro_rules! ()
72+
// macro_rules! []
73+
if paths::is_use_path_start(p)
74+
|| (p.at_contextual_kw(T![macro_rules]) && p.nth_at(1, BANG) && !p.nth_at(2, IDENT))
75+
{
6276
match macro_call(p) {
6377
BlockLike::Block => (),
6478
BlockLike::NotBlock => {
@@ -228,7 +242,15 @@ fn opt_item_without_modifiers(p: &mut Parser<'_>, m: Marker) -> Result<(), Marke
228242
IDENT if p.at_contextual_kw(T![union]) && p.nth(1) == IDENT => adt::union(p, m),
229243

230244
T![macro] => macro_def(p, m),
231-
IDENT if p.at_contextual_kw(T![macro_rules]) && p.nth(1) == BANG => macro_rules(p, m),
245+
// check if current token is "macro_rules" followed by "!" followed by an identifier or "try"
246+
// try is keyword since the 2018 edition and the parser is not edition aware (yet!)
247+
IDENT
248+
if p.at_contextual_kw(T![macro_rules])
249+
&& p.nth_at(1, BANG)
250+
&& (p.nth_at(2, IDENT) || p.nth_at(2, T![try])) =>
251+
{
252+
macro_rules(p, m)
253+
}
232254

233255
T![const] if (la == IDENT || la == T![_] || la == T![mut]) => consts::konst(p, m),
234256
T![static] if (la == IDENT || la == T![_] || la == T![mut]) => consts::static_(p, m),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
SOURCE_FILE
2+
MACRO_CALL
3+
PATH
4+
PATH_SEGMENT
5+
NAME_REF
6+
IDENT "macro_rules"
7+
BANG "!"
8+
WHITESPACE " "
9+
TOKEN_TREE
10+
L_CURLY "{"
11+
R_CURLY "}"
12+
ERROR
13+
SEMICOLON ";"
14+
WHITESPACE "\n"
15+
MACRO_CALL
16+
PATH
17+
PATH_SEGMENT
18+
NAME_REF
19+
IDENT "macro_rules"
20+
BANG "!"
21+
WHITESPACE " "
22+
TOKEN_TREE
23+
L_PAREN "("
24+
R_PAREN ")"
25+
WHITESPACE "\n"
26+
MACRO_CALL
27+
PATH
28+
PATH_SEGMENT
29+
NAME_REF
30+
IDENT "macro_rules"
31+
BANG "!"
32+
WHITESPACE " "
33+
TOKEN_TREE
34+
L_BRACK "["
35+
R_BRACK "]"
36+
WHITESPACE "\n"
37+
error 15: expected an item
38+
error 32: expected SEMICOLON
39+
error 48: expected SEMICOLON
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
macro_rules! {};
2+
macro_rules! ()
3+
macro_rules! []
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
SOURCE_FILE
2+
MACRO_CALL
3+
PATH
4+
PATH_SEGMENT
5+
NAME_REF
6+
IDENT "macro_rules"
7+
BANG "!"
8+
WHITESPACE " "
9+
TOKEN_TREE
10+
L_CURLY "{"
11+
R_CURLY "}"
12+
WHITESPACE "\n"
13+
MACRO_CALL
14+
PATH
15+
PATH_SEGMENT
16+
NAME_REF
17+
IDENT "macro_rules"
18+
BANG "!"
19+
WHITESPACE " "
20+
TOKEN_TREE
21+
L_PAREN "("
22+
R_PAREN ")"
23+
SEMICOLON ";"
24+
WHITESPACE "\n"
25+
MACRO_CALL
26+
PATH
27+
PATH_SEGMENT
28+
NAME_REF
29+
IDENT "macro_rules"
30+
BANG "!"
31+
WHITESPACE " "
32+
TOKEN_TREE
33+
L_BRACK "["
34+
R_BRACK "]"
35+
SEMICOLON ";"
36+
WHITESPACE "\n"
37+
FN
38+
FN_KW "fn"
39+
WHITESPACE " "
40+
NAME
41+
IDENT "main"
42+
PARAM_LIST
43+
L_PAREN "("
44+
R_PAREN ")"
45+
WHITESPACE " "
46+
BLOCK_EXPR
47+
STMT_LIST
48+
L_CURLY "{"
49+
WHITESPACE "\n "
50+
LET_STMT
51+
LET_KW "let"
52+
WHITESPACE " "
53+
IDENT_PAT
54+
NAME
55+
IDENT "foo"
56+
WHITESPACE " "
57+
EQ "="
58+
WHITESPACE " "
59+
MACRO_EXPR
60+
MACRO_CALL
61+
PATH
62+
PATH_SEGMENT
63+
NAME_REF
64+
IDENT "macro_rules"
65+
BANG "!"
66+
TOKEN_TREE
67+
L_PAREN "("
68+
R_PAREN ")"
69+
SEMICOLON ";"
70+
WHITESPACE "\n"
71+
R_CURLY "}"
72+
WHITESPACE "\n"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
macro_rules! {}
2+
macro_rules! ();
3+
macro_rules! [];
4+
fn main() {
5+
let foo = macro_rules!();
6+
}

0 commit comments

Comments
 (0)