Parse ident with allowing recovery when trying to recover in diagnosing

(cherry picked from commit 3713512217)
This commit is contained in:
mu001999 2026-01-17 22:53:08 +08:00 committed by Josh Stone
parent b90149755a
commit c226970869
9 changed files with 102 additions and 22 deletions

View file

@ -2264,7 +2264,7 @@ impl<'a> Parser<'a> {
&& self.look_ahead(1, |t| *t == token::Comma || *t == token::CloseParen)
{
// `fn foo(String s) {}`
let ident = self.parse_ident().unwrap();
let ident = self.parse_ident_common(true).unwrap();
let span = pat.span.with_hi(ident.span.hi());
err.span_suggestion(

View file

@ -408,12 +408,11 @@ impl<'a> Parser<'a> {
let insert_span = ident_span.shrink_to_lo();
let ident = if self.token.is_ident()
&& self.token.is_non_reserved_ident()
&& (!is_const || self.look_ahead(1, |t| *t == token::OpenParen))
&& self.look_ahead(1, |t| {
matches!(t.kind, token::Lt | token::OpenBrace | token::OpenParen)
}) {
self.parse_ident().unwrap()
self.parse_ident_common(true).unwrap()
} else {
return Ok(());
};

View file

@ -469,7 +469,7 @@ impl<'a> Parser<'a> {
self.parse_ident_common(self.may_recover())
}
fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, Ident> {
pub(crate) fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, Ident> {
let (ident, is_raw) = self.ident_or_err(recover)?;
if is_raw == IdentIsRaw::No && ident.is_reserved() {

View file

@ -6,6 +6,7 @@ macro_rules! m {
}
m!(const Self());
//~^ ERROR expected one of `!` or `::`, found `(`
//~^ ERROR expected identifier, found keyword `Self`
//~^^ ERROR missing `fn` or `struct` for function or struct definition
fn main() {}

View file

@ -1,11 +1,22 @@
error: expected one of `!` or `::`, found `(`
--> $DIR/kw-in-const-item-pos-recovery-149692.rs:8:14
error: expected identifier, found keyword `Self`
--> $DIR/kw-in-const-item-pos-recovery-149692.rs:8:10
|
LL | m!(const Self());
| ^^^^ expected identifier, found keyword
error: missing `fn` or `struct` for function or struct definition
--> $DIR/kw-in-const-item-pos-recovery-149692.rs:8:10
|
LL | (const $id:item()) => {}
| -------- while parsing argument for this `item` macro fragment
...
LL | m!(const Self());
| ^ expected one of `!` or `::`
| ^^^^
|
help: if you meant to call a macro, try
|
LL | m!(const Self!());
| +
error: aborting due to 1 previous error
error: aborting due to 2 previous errors

View file

@ -8,12 +8,15 @@ macro_rules! m {
}
m!(Self());
//~^ ERROR expected one of `!` or `::`, found `(`
//~^ ERROR expected identifier, found keyword `Self`
//~^^ ERROR missing `fn` or `struct` for function or struct definition
m!(Self{});
//~^ ERROR expected one of `!` or `::`, found `{`
//~^ ERROR expected identifier, found keyword `Self`
//~^^ ERROR missing `enum` or `struct` for enum or struct definition
m!(crate());
//~^ ERROR expected one of `!` or `::`, found `(`
//~^ ERROR expected identifier, found keyword `crate`
//~^^ ERROR missing `fn` or `struct` for function or struct definition
fn main() {}

View file

@ -1,29 +1,57 @@
error: expected one of `!` or `::`, found `(`
--> $DIR/kw-in-item-pos-recovery-149692.rs:10:8
error: expected identifier, found keyword `Self`
--> $DIR/kw-in-item-pos-recovery-149692.rs:10:4
|
LL | m!(Self());
| ^^^^ expected identifier, found keyword
error: missing `fn` or `struct` for function or struct definition
--> $DIR/kw-in-item-pos-recovery-149692.rs:10:4
|
LL | ($id:item()) => {}
| -------- while parsing argument for this `item` macro fragment
...
LL | m!(Self());
| ^ expected one of `!` or `::`
| ^^^^
|
help: if you meant to call a macro, try
|
LL | m!(Self!());
| +
error: expected one of `!` or `::`, found `{`
--> $DIR/kw-in-item-pos-recovery-149692.rs:13:8
error: expected identifier, found keyword `Self`
--> $DIR/kw-in-item-pos-recovery-149692.rs:14:4
|
LL | m!(Self{});
| ^^^^ expected identifier, found keyword
error: missing `enum` or `struct` for enum or struct definition
--> $DIR/kw-in-item-pos-recovery-149692.rs:14:4
|
LL | ($id:item()) => {}
| -------- while parsing argument for this `item` macro fragment
...
LL | m!(Self{});
| ^ expected one of `!` or `::`
| ^^^^
error: expected one of `!` or `::`, found `(`
--> $DIR/kw-in-item-pos-recovery-149692.rs:16:9
error: expected identifier, found keyword `crate`
--> $DIR/kw-in-item-pos-recovery-149692.rs:18:4
|
LL | m!(crate());
| ^^^^^ expected identifier, found keyword
error: missing `fn` or `struct` for function or struct definition
--> $DIR/kw-in-item-pos-recovery-149692.rs:18:4
|
LL | ($id:item()) => {}
| -------- while parsing argument for this `item` macro fragment
...
LL | m!(crate());
| ^ expected one of `!` or `::`
| ^^^^^
|
help: if you meant to call a macro, try
|
LL | m!(crate!());
| +
error: aborting due to 3 previous errors
error: aborting due to 6 previous errors

View file

@ -0,0 +1,13 @@
//@ edition: 2021
macro_rules! x {
($ty : item) => {};
}
x! {
trait MyTrait { fn bar(c self) }
//~^ ERROR expected identifier, found keyword `self`
//~^^ ERROR expected one of `:`, `@`, or `|`, found keyword `self`
//~^^^ ERROR expected one of `->`, `;`, `where`, or `{`, found `}`
}
fn main() {}

View file

@ -0,0 +1,25 @@
error: expected identifier, found keyword `self`
--> $DIR/kw-in-item-pos-recovery-151238.rs:7:28
|
LL | trait MyTrait { fn bar(c self) }
| ^^^^ expected identifier, found keyword
error: expected one of `:`, `@`, or `|`, found keyword `self`
--> $DIR/kw-in-item-pos-recovery-151238.rs:7:28
|
LL | trait MyTrait { fn bar(c self) }
| --^^^^
| | |
| | expected one of `:`, `@`, or `|`
| help: declare the type after the parameter binding: `<identifier>: <type>`
error: expected one of `->`, `;`, `where`, or `{`, found `}`
--> $DIR/kw-in-item-pos-recovery-151238.rs:7:34
|
LL | trait MyTrait { fn bar(c self) }
| --- ^ expected one of `->`, `;`, `where`, or `{`
| |
| while parsing this `fn`
error: aborting due to 3 previous errors