From 593d1eed8216c4ab33500b323fbd1b3de4ecb34d Mon Sep 17 00:00:00 2001 From: Chris Simpkins Date: Wed, 27 May 2020 14:09:54 -0400 Subject: [PATCH] improve diagnostics suggestion for missing `@` in slice id binding to rest pattern add issue 72373 tests fmt test fix suggestion format Replacement, not insertion of suggested string implement review changes refactor to span_suggestion_verbose, improve suggestion message, change id @ pattern space formatting fmt fix diagnostics spacing between ident and @ refactor reference --- src/librustc_parse/parser/mod.rs | 20 ++++++++++++++++++++ src/test/ui/issues/issue-72373.rs | 9 +++++++++ src/test/ui/issues/issue-72373.stderr | 13 +++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 src/test/ui/issues/issue-72373.rs create mode 100644 src/test/ui/issues/issue-72373.stderr 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 @@ fn parse_seq_to_before_tokens( } } + // 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 +