Skip to content

Commit 692c665

Browse files
Rollup merge of rust-lang#150590 - ident-kw-ice, r=petrochenkov
Don't try to recover keyword as non-keyword identifier Fixes rust-lang#149692. On beta after rust-lang#146978, we ICE on ```rs macro_rules! m { ($id:item()) => {} } m!(Self()); ``` where `Self` in the macro invocation is a keyword not a "normal" identifier, while attempting to recover an missing keyword before an identifier. Except, `Self` *is* a keyword, so trying to parse that as a non-reserved identifier expectedly fails. I suspect rust-lang#146978 merely unmasked a possible code path to hit this case; this logic has been so for a good while. Previously, on stable, the error message looks something like ```rs error: expected identifier, found keyword `Self` --> src/lib.rs:5:4 | 5 | m!(Self()); | ^^^^ expected identifier, found keyword error: missing `fn` or `struct` for function or struct definition --> src/lib.rs:5:4 | 2 | ($id:item()) => {} | -------- while parsing argument for this `item` macro fragment ... 5 | m!(Self()); | ^^^^ | help: if you meant to call a macro, try | 5 | m!(Self!()); | + ``` I considered restoring this diagnostic, but I'm not super convinced it's worth the complexity (and to me, it's not super clear what the user actually intended here).
2 parents 4311238 + 79c4727 commit 692c665

5 files changed

Lines changed: 71 additions & 0 deletions

File tree

compiler/rustc_parse/src/parser/item.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ impl<'a> Parser<'a> {
408408
let insert_span = ident_span.shrink_to_lo();
409409

410410
let ident = if self.token.is_ident()
411+
&& self.token.is_non_reserved_ident()
411412
&& (!is_const || self.look_ahead(1, |t| *t == token::OpenParen))
412413
&& self.look_ahead(1, |t| {
413414
matches!(t.kind, token::Lt | token::OpenBrace | token::OpenParen)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//! More test coverage for <https://github.com/rust-lang/rust/issues/149692>; this test is
2+
//! specifically for `const` items.
3+
4+
macro_rules! m {
5+
(const $id:item()) => {}
6+
}
7+
8+
m!(const Self());
9+
//~^ ERROR expected one of `!` or `::`, found `(`
10+
11+
fn main() {}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: expected one of `!` or `::`, found `(`
2+
--> $DIR/kw-in-const-item-pos-recovery-149692.rs:8:14
3+
|
4+
LL | (const $id:item()) => {}
5+
| -------- while parsing argument for this `item` macro fragment
6+
...
7+
LL | m!(const Self());
8+
| ^ expected one of `!` or `::`
9+
10+
error: aborting due to 1 previous error
11+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//! Regression test for a diagnostic ICE where we tried to recover a keyword as the identifier when
2+
//! we are already trying to recover a missing keyword before item.
3+
//!
4+
//! See <https://github.com/rust-lang/rust/issues/149692>.
5+
6+
macro_rules! m {
7+
($id:item()) => {}
8+
}
9+
10+
m!(Self());
11+
//~^ ERROR expected one of `!` or `::`, found `(`
12+
13+
m!(Self{});
14+
//~^ ERROR expected one of `!` or `::`, found `{`
15+
16+
m!(crate());
17+
//~^ ERROR expected one of `!` or `::`, found `(`
18+
19+
fn main() {}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error: expected one of `!` or `::`, found `(`
2+
--> $DIR/kw-in-item-pos-recovery-149692.rs:10:8
3+
|
4+
LL | ($id:item()) => {}
5+
| -------- while parsing argument for this `item` macro fragment
6+
...
7+
LL | m!(Self());
8+
| ^ expected one of `!` or `::`
9+
10+
error: expected one of `!` or `::`, found `{`
11+
--> $DIR/kw-in-item-pos-recovery-149692.rs:13:8
12+
|
13+
LL | ($id:item()) => {}
14+
| -------- while parsing argument for this `item` macro fragment
15+
...
16+
LL | m!(Self{});
17+
| ^ expected one of `!` or `::`
18+
19+
error: expected one of `!` or `::`, found `(`
20+
--> $DIR/kw-in-item-pos-recovery-149692.rs:16:9
21+
|
22+
LL | ($id:item()) => {}
23+
| -------- while parsing argument for this `item` macro fragment
24+
...
25+
LL | m!(crate());
26+
| ^ expected one of `!` or `::`
27+
28+
error: aborting due to 3 previous errors
29+

0 commit comments

Comments
 (0)