]> git.lizzy.rs Git - rust.git/commitdiff
Recover _ as .. in field pattern
authorMichael Goulet <michael@errs.io>
Sun, 15 Jan 2023 21:31:04 +0000 (21:31 +0000)
committerMichael Goulet <michael@errs.io>
Thu, 2 Feb 2023 06:10:02 +0000 (06:10 +0000)
compiler/rustc_error_messages/locales/en-US/parse.ftl
compiler/rustc_parse/src/errors.rs
compiler/rustc_parse/src/parser/pat.rs
tests/ui/did_you_mean/issue-46718-struct-pattern-dotdotdot.stderr
tests/ui/parser/issue-102806.stderr
tests/ui/parser/issues/issue-63135.stderr
tests/ui/structs-enums/struct-enum-ignoring-field-with-underscore.rs
tests/ui/structs-enums/struct-enum-ignoring-field-with-underscore.stderr

index 21cf4bd789c7e8ecf3bc4548b77314359a85c6a5..6752f05b044ee211bbfcf78d7d84e80885b9a1ce 100644 (file)
@@ -535,8 +535,8 @@ parse_dot_dot_dot_range_to_pattern_not_allowed = range-to patterns with `...` ar
 
 parse_enum_pattern_instead_of_identifier = expected identifier, found enum pattern
 
-parse_dot_dot_dot_for_remaining_fields = expected field pattern, found `...`
-    .suggestion = to omit remaining fields, use one fewer `.`
+parse_dot_dot_dot_for_remaining_fields = expected field pattern, found `{$token_str}`
+    .suggestion = to omit remaining fields, use `..`
 
 parse_expected_comma_after_pattern_field = expected `,`
 
index 145611923ff16a127f4668b9ce999b542d9eda2b..20da8ce5b6e76a0965874007c86cf4b60f615dba 100644 (file)
@@ -1,3 +1,5 @@
+use std::borrow::Cow;
+
 use rustc_ast::token::Token;
 use rustc_ast::{Path, Visibility};
 use rustc_errors::{fluent, AddToDiagnostic, Applicability, EmissionGuarantee, IntoDiagnostic};
@@ -1802,8 +1804,9 @@ pub(crate) struct EnumPatternInsteadOfIdentifier {
 #[diag(parse_dot_dot_dot_for_remaining_fields)]
 pub(crate) struct DotDotDotForRemainingFields {
     #[primary_span]
-    #[suggestion(code = "..", applicability = "machine-applicable")]
+    #[suggestion(code = "..", style = "verbose", applicability = "machine-applicable")]
     pub span: Span,
+    pub token_str: Cow<'static, str>,
 }
 
 #[derive(Diagnostic)]
index 88c75fd81e7582b2a4d72a471fd55ac97df7e486..c982d7f99a91be44f1f519b58bc33d9a846a6acd 100644 (file)
@@ -963,12 +963,15 @@ fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<PatField>, bool)> {
             }
             ate_comma = false;
 
-            if self.check(&token::DotDot) || self.token == token::DotDotDot {
+            if self.check(&token::DotDot)
+                || self.check_noexpect(&token::DotDotDot)
+                || self.check_keyword(kw::Underscore)
+            {
                 etc = true;
                 let mut etc_sp = self.token.span;
 
-                self.recover_one_fewer_dotdot();
-                self.bump(); // `..` || `...`
+                self.recover_bad_dot_dot();
+                self.bump(); // `..` || `...` || `_`
 
                 if self.token == token::CloseDelim(Delimiter::Brace) {
                     etc_span = Some(etc_sp);
@@ -1061,14 +1064,15 @@ fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<PatField>, bool)> {
         Ok((fields, etc))
     }
 
-    /// Recover on `...` as if it were `..` to avoid further errors.
+    /// Recover on `...` or `_` as if it were `..` to avoid further errors.
     /// See issue #46718.
-    fn recover_one_fewer_dotdot(&self) {
-        if self.token != token::DotDotDot {
+    fn recover_bad_dot_dot(&self) {
+        if self.token == token::DotDot {
             return;
         }
 
-        self.sess.emit_err(DotDotDotForRemainingFields { span: self.token.span });
+        let token_str = pprust::token_to_string(&self.token);
+        self.sess.emit_err(DotDotDotForRemainingFields { span: self.token.span, token_str });
     }
 
     fn parse_pat_field(&mut self, lo: Span, attrs: AttrVec) -> PResult<'a, PatField> {
index bfe1ed32859b928fb4886a9f05a17bfc8332cdb4..589b2c3784926dc5a35ef647a26f02be58708b96 100644 (file)
@@ -2,7 +2,12 @@ error: expected field pattern, found `...`
   --> $DIR/issue-46718-struct-pattern-dotdotdot.rs:11:55
    |
 LL |             PersonalityInventory { expressivity: exp, ... } => exp
-   |                                                       ^^^ help: to omit remaining fields, use one fewer `.`: `..`
+   |                                                       ^^^
+   |
+help: to omit remaining fields, use `..`
+   |
+LL |             PersonalityInventory { expressivity: exp, .. } => exp
+   |                                                       ~~
 
 error: aborting due to previous error
 
index 6872b8bc0afec880c9f4e66f23ca63381d8fa5bf..ba8174a823b2a30991c0179edbc664a6c8f4e202 100644 (file)
@@ -32,7 +32,12 @@ error: expected field pattern, found `...`
   --> $DIR/issue-102806.rs:21:22
    |
 LL |     let V3 { z: val, ... } = v;
-   |                      ^^^ help: to omit remaining fields, use one fewer `.`: `..`
+   |                      ^^^
+   |
+help: to omit remaining fields, use `..`
+   |
+LL |     let V3 { z: val, .. } = v;
+   |                      ~~
 
 error[E0063]: missing fields `x` and `y` in initializer of `V3`
   --> $DIR/issue-102806.rs:17:13
index 80e9ac5bedf13292da7a83650e3de4311a7e4953..e0dc356d5467bb996d9c9db592bf4dc0859e411d 100644 (file)
@@ -20,7 +20,12 @@ error: expected field pattern, found `...`
   --> $DIR/issue-63135.rs:3:8
    |
 LL | fn i(n{...,f #
-   |        ^^^ help: to omit remaining fields, use one fewer `.`: `..`
+   |        ^^^
+   |
+help: to omit remaining fields, use `..`
+   |
+LL | fn i(n{..,f #
+   |        ~~
 
 error: expected `}`, found `,`
   --> $DIR/issue-63135.rs:3:11
index c30b8a1e1f1a7c3bd74f599c7f7e3feae8d87e5f..b569993c6143edeff75e58bcf35395ba12bcee61 100644 (file)
@@ -7,6 +7,5 @@ fn main() {
     let foo = Some(Foo::Other);
 
     if let Some(Foo::Bar {_}) = foo {}
-    //~^ ERROR expected identifier, found reserved identifier `_`
-    //~| ERROR pattern does not mention field `bar` [E0027]
+    //~^ ERROR expected field pattern, found `_`
 }
index 16f751444a558c6d67cd2a567e32d3747b031ddf..2f3a150e5cba92566aadd814edcbad3e2fb000a4 100644 (file)
@@ -1,24 +1,13 @@
-error: expected identifier, found reserved identifier `_`
+error: expected field pattern, found `_`
   --> $DIR/struct-enum-ignoring-field-with-underscore.rs:9:27
    |
 LL |     if let Some(Foo::Bar {_}) = foo {}
-   |                           ^ expected identifier, found reserved identifier
-
-error[E0027]: pattern does not mention field `bar`
-  --> $DIR/struct-enum-ignoring-field-with-underscore.rs:9:17
-   |
-LL |     if let Some(Foo::Bar {_}) = foo {}
-   |                 ^^^^^^^^^^^^ missing field `bar`
-   |
-help: include the missing field in the pattern
+   |                           ^
    |
-LL |     if let Some(Foo::Bar {_, bar }) = foo {}
-   |                            ~~~~~~~
-help: if you don't care about this missing field, you can explicitly ignore it
+help: to omit remaining fields, use `..`
    |
-LL |     if let Some(Foo::Bar {_, .. }) = foo {}
-   |                            ~~~~~~
+LL |     if let Some(Foo::Bar {..}) = foo {}
+   |                           ~~
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0027`.