about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_parse/parser/mod.rs20
-rw-r--r--src/test/ui/issues/issue-72373.rs9
-rw-r--r--src/test/ui/issues/issue-72373.stderr13
3 files changed, 42 insertions, 0 deletions
diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs
index b21524cb9bd..c00b6084829 100644
--- a/src/librustc_parse/parser/mod.rs
+++ b/src/librustc_parse/parser/mod.rs
@@ -672,6 +672,26 @@ impl<'a> Parser<'a> {
                                 }
                             }
 
+                            // If this was a missing `@` in a binding pattern
+                            // bail with a suggestion
+                            // https://github.com/rust-lang/rust/issues/72373
+                            if self.prev_token.is_ident() && &self.token.kind == &token::DotDot {
+                                let msg = format!(
+                                    "if you meant to bind the contents of \
+                                    the rest of the array pattern into `{}`, use `@`",
+                                    pprust::token_to_string(&self.prev_token)
+                                );
+                                expect_err
+                                    .span_suggestion_verbose(
+                                        self.prev_token.span.shrink_to_hi().until(self.token.span),
+                                        &msg,
+                                        " @ ".to_string(),
+                                        Applicability::MaybeIncorrect,
+                                    )
+                                    .emit();
+                                break;
+                            }
+
                             // Attempt to keep parsing if it was an omitted separator.
                             match f(self) {
                                 Ok(t) => {
diff --git a/src/test/ui/issues/issue-72373.rs b/src/test/ui/issues/issue-72373.rs
new file mode 100644
index 00000000000..4da6061c27f
--- /dev/null
+++ b/src/test/ui/issues/issue-72373.rs
@@ -0,0 +1,9 @@
+fn foo(c: &[u32], n: u32) -> u32 {
+    match *c {
+        [h, ..] if h > n => 0,
+        [h, ..] if h == n => 1,
+        [h, ref ts..] => foo(c, n - h) + foo(ts, n),
+        //~^ ERROR expected one of `,`, `@`, `]`, or `|`, found `..`
+        [] => 0,
+    }
+}
diff --git a/src/test/ui/issues/issue-72373.stderr b/src/test/ui/issues/issue-72373.stderr
new file mode 100644
index 00000000000..dfde8624814
--- /dev/null
+++ b/src/test/ui/issues/issue-72373.stderr
@@ -0,0 +1,13 @@
+error: expected one of `,`, `@`, `]`, or `|`, found `..`
+  --> $DIR/issue-72373.rs:5:19
+   |
+LL |         [h, ref ts..] => foo(c, n - h) + foo(ts, n),
+   |                   ^^ expected one of `,`, `@`, `]`, or `|`
+   |
+help: if you meant to bind the contents of the rest of the array pattern into `ts`, use `@`
+   |
+LL |         [h, ref ts @ ..] => foo(c, n - h) + foo(ts, n),
+   |                    ^
+
+error: aborting due to previous error
+