Change:
<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <details<summary<strongBacktrace</strong</summary<p</p</details label A-parser A-macros <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
cc this should probably be gated with your "may eagerly recover" work as well
This code is actually already mentioned in ;)
claim
Yeah, gating this recovery behind a is the correct fix here.
Also very fun that these things can ICE sometimes.
Found these also panic: Since these are highly related to the case, one pull request can fix all of these (maybe).

Discussion:
Ok(Some(if self.token.is_keyword(kw::Let) { self.parse_local_mk(lo, attrs, capture_semi, force_collect)? <del> } else if self.is_kw_followed_by_ident(kw::Mut) { self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::MissingLet)? } else if self.is_kw_followed_by_ident(kw::Auto) { </del> <ins> } else if self.is_kw_followed_by_ident(kw::Mut) && self.may_recover() { self.recover_stmt_local_after_let(lo, attrs, InvalidVariableDeclarationSub::MissingLet)? } else if self.is_kw_followed_by_ident(kw::Auto) && self.may_recover() { </ins> self.bump(); // `auto` <del> self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::UseLetNotAuto)? } else if self.is_kw_followed_by_ident(sym::var) { </del> <ins> self.recover_stmt_local_after_let( lo, attrs, InvalidVariableDeclarationSub::UseLetNotAuto, )? } else if self.is_kw_followed_by_ident(sym::var) && self.may_recover() { </ins> self.bump(); // `var` <del> self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::UseLetNotVar)? </del> <ins> self.recover_stmt_local_after_let( lo, attrs, InvalidVariableDeclarationSub::UseLetNotVar, )? </ins> } else if self.check_path() && !self.token.is_qpath_start() && !self.is_path_start_item() { // We have avoided contextual keywords like `union`, items with `crate` visibility, // or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something

} } <del> fn recover_stmt_local( </del> <ins> fn recover_stmt_local_after_let( </ins> &mut self, lo: Span, attrs: AttrWrapper, subdiagnostic: fn(Span) -> InvalidVariableDeclarationSub, ) -> PResult<'a, Stmt> { <del> let stmt = self.recover_local_after_let(lo, attrs)?; </del> <ins> let stmt = self.collect_tokens_trailing_token(attrs, ForceCollect::Yes, |this, attrs| { let local = this.parse_local(attrs)?; // FIXME - maybe capture semicolon in recovery? Ok(( this.mk_stmt(lo.to(this.prev_token.span), StmtKind::Local(local)), TrailingToken::None, )) })?; </ins> self.sess.emit_err(InvalidVariableDeclaration { span: lo, sub: subdiagnostic(lo) }); Ok(stmt) }

}) } <del> fn recover_local_after_let(&mut self, lo: Span, attrs: AttrWrapper) -> PResult<'a, Stmt> { self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| { let local = this.parse_local(attrs)?; // FIXME - maybe capture semicolon in recovery? Ok(( this.mk_stmt(lo.to(this.prev_token.span), StmtKind::Local(local)), TrailingToken::None, )) }) } </del> /// Parses a local variable declaration. fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P<Local>> { let lo = self.prev_token.span;

<ins> macro_rules! m { ($s:stmt) => {} } m! { mut x } //~^ ERROR expected expression, found keyword `mut` //~| ERROR expected a statement m! { auto x } //~^ ERROR invalid variable declaration m! { var x } //~^ ERROR invalid variable declaration fn main() {} </ins>

<ins> error: expected expression, found keyword `mut` --> $DIR/issue-103529.rs:5:6 | LL | m! { mut x } |      ^^^ expected expression error: expected a statement --> $DIR/issue-103529.rs:5:10 | LL |     ($s:stmt) => {} |      ------- while parsing argument for this `stmt` macro fragment ... LL | m! { mut x } |          ^ error: invalid variable declaration --> $DIR/issue-103529.rs:8:6 | LL | m! { auto x } |      ^^^^ | help: write `let` instead of `auto` to introduce a new variable | LL | m! { let x } |      ~~~ error: invalid variable declaration --> $DIR/issue-103529.rs:10:6 | LL | m! { var x } |      ^^^ | help: write `let` instead of `var` to introduce a new variable | LL | m! { let x } |      ~~~ error: aborting due to 4 previous errors </ins>