about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs8
-rw-r--r--src/test/ui/macros/issue-103529.rs13
-rw-r--r--src/test/ui/macros/issue-103529.stderr39
3 files changed, 56 insertions, 4 deletions
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index ff1ddfd97df..b4813250547 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -72,12 +72,12 @@ impl<'a> Parser<'a> {
 
         Ok(Some(if self.token.is_keyword(kw::Let) {
             self.parse_local_mk(lo, attrs, capture_semi, force_collect)?
-        } else if self.is_kw_followed_by_ident(kw::Mut) {
+        } else if self.is_kw_followed_by_ident(kw::Mut) && self.may_recover() {
             self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::MissingLet)?
-        } else if self.is_kw_followed_by_ident(kw::Auto) {
+        } else if self.is_kw_followed_by_ident(kw::Auto) && self.may_recover() {
             self.bump(); // `auto`
             self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::UseLetNotAuto)?
-        } else if self.is_kw_followed_by_ident(sym::var) {
+        } else if self.is_kw_followed_by_ident(sym::var) && self.may_recover() {
             self.bump(); // `var`
             self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::UseLetNotVar)?
         } else if self.check_path() && !self.token.is_qpath_start() && !self.is_path_start_item() {
@@ -244,7 +244,7 @@ impl<'a> Parser<'a> {
     }
 
     fn recover_local_after_let(&mut self, lo: Span, attrs: AttrWrapper) -> PResult<'a, Stmt> {
-        self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
+        self.collect_tokens_trailing_token(attrs, ForceCollect::Yes, |this, attrs| {
             let local = this.parse_local(attrs)?;
             // FIXME - maybe capture semicolon in recovery?
             Ok((
diff --git a/src/test/ui/macros/issue-103529.rs b/src/test/ui/macros/issue-103529.rs
new file mode 100644
index 00000000000..fa05baed7fc
--- /dev/null
+++ b/src/test/ui/macros/issue-103529.rs
@@ -0,0 +1,13 @@
+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() {}
diff --git a/src/test/ui/macros/issue-103529.stderr b/src/test/ui/macros/issue-103529.stderr
new file mode 100644
index 00000000000..61e322afc77
--- /dev/null
+++ b/src/test/ui/macros/issue-103529.stderr
@@ -0,0 +1,39 @@
+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
+