about summary refs log tree commit diff
diff options
context:
space:
mode:
authoryukang <moorekang@gmail.com>2022-10-14 06:52:23 +0800
committeryukang <moorekang@gmail.com>2022-11-04 19:32:32 +0800
commit4b77e730b5c9e5126abf12ccca5e36f2a2c66868 (patch)
treec6ba20116cf2f207af73d2e528c7ab11966a0289
parent1e25882944aabcf0c871182b887cd4ffe9c7b330 (diff)
downloadrust-4b77e730b5c9e5126abf12ccca5e36f2a2c66868.tar.gz
rust-4b77e730b5c9e5126abf12ccca5e36f2a2c66868.zip
fake a base to suppress later extra error message
-rw-r--r--compiler/rustc_parse/src/errors.rs2
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs29
-rw-r--r--src/test/ui/parser/issue-102806.rs11
-rw-r--r--src/test/ui/parser/issue-102806.stderr34
4 files changed, 35 insertions, 41 deletions
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index b02bd664533..0924c853715 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -373,7 +373,7 @@ pub(crate) struct MissingSemicolonBeforeArray {
 pub(crate) struct MissingDotDot {
     #[primary_span]
     pub token_span: Span,
-    #[suggestion_verbose(applicability = "maybe-incorrect", code = "..")]
+    #[suggestion(applicability = "maybe-incorrect", code = "..", style = "verbose")]
     pub sugg_span: Span,
 }
 
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 7de025e7860..338e6a8e289 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2880,7 +2880,7 @@ impl<'a> Parser<'a> {
         };
 
         while self.token != token::CloseDelim(close_delim) {
-            if self.eat(&token::DotDot) {
+            if self.eat(&token::DotDot) || self.recover_struct_fileds_dots(close_delim) {
                 let exp_span = self.prev_token.span;
                 // We permit `.. }` on the left-hand side of a destructuring assignment.
                 if self.check(&token::CloseDelim(close_delim)) {
@@ -2897,21 +2897,6 @@ impl<'a> Parser<'a> {
                 }
                 self.recover_struct_comma_after_dotdot(exp_span);
                 break;
-            } else if self.token == token::DotDotDot {
-                // suggest `..v` instead of `...v`
-                let snapshot = self.create_snapshot_for_diagnostic();
-                let span = self.token.span;
-                self.bump();
-                match self.parse_expr() {
-                    Ok(_p) => {
-                        self.sess.emit_err(MissingDotDot { token_span: span, sugg_span: span });
-                        break;
-                    }
-                    Err(inner_err) => {
-                        inner_err.cancel();
-                        self.restore_snapshot(snapshot);
-                    }
-                }
             }
 
             let recovery_field = self.find_struct_error_after_field_looking_code();
@@ -3042,6 +3027,18 @@ impl<'a> Parser<'a> {
         self.recover_stmt();
     }
 
+    fn recover_struct_fileds_dots(&mut self, close_delim: Delimiter) -> bool {
+        if !self.look_ahead(1, |t| *t == token::CloseDelim(close_delim))
+            && self.eat(&token::DotDotDot)
+        {
+            // recover from typo of `...`, suggest `..`
+            let span = self.prev_token.span;
+            self.sess.emit_err(MissingDotDot { token_span: span, sugg_span: span });
+            return true;
+        }
+        false
+    }
+
     /// Parses `ident (COLON expr)?`.
     fn parse_expr_field(&mut self) -> PResult<'a, ExprField> {
         let attrs = self.parse_outer_attributes()?;
diff --git a/src/test/ui/parser/issue-102806.rs b/src/test/ui/parser/issue-102806.rs
index f5513c87a92..ba297bdc967 100644
--- a/src/test/ui/parser/issue-102806.rs
+++ b/src/test/ui/parser/issue-102806.rs
@@ -1,5 +1,6 @@
 #![allow(dead_code)]
 
+#[derive(Default)]
 struct V3 {
     x: f32,
     y: f32,
@@ -9,14 +10,16 @@ struct V3 {
 fn pz(v: V3) {
     let _ = V3 { z: 0.0, ...v};
     //~^ ERROR expected `..`
-    //~| ERROR missing fields `x` and `y` in initializer of `V3`
-    let _ = V3 { z: 0.0, ... };
-    //~^ expected identifier
-    //~| ERROR missing fields `x` and `y` in initializer of `V3`
 
     let _ = V3 { z: 0.0, ...Default::default() };
     //~^ ERROR expected `..`
+
+    let _ = V3 { z: 0.0, ... };
+    //~^ expected identifier
     //~| ERROR missing fields `x` and `y` in initializer of `V3`
+
+    let V3 { z: val, ... } = v;
+    //~^ ERROR expected field pattern
 }
 
 fn main() {}
diff --git a/src/test/ui/parser/issue-102806.stderr b/src/test/ui/parser/issue-102806.stderr
index 53a43b53961..6872b8bc0af 100644
--- a/src/test/ui/parser/issue-102806.stderr
+++ b/src/test/ui/parser/issue-102806.stderr
@@ -1,5 +1,5 @@
 error: expected `..`, found `...`
-  --> $DIR/issue-102806.rs:10:26
+  --> $DIR/issue-102806.rs:11:26
    |
 LL |     let _ = V3 { z: 0.0, ...v};
    |                          ^^^
@@ -9,16 +9,8 @@ help: use `..` to fill in the rest of the fields
 LL |     let _ = V3 { z: 0.0, ..v};
    |                          ~~
 
-error: expected identifier, found `...`
-  --> $DIR/issue-102806.rs:13:26
-   |
-LL |     let _ = V3 { z: 0.0, ... };
-   |             --           ^^^ expected identifier
-   |             |
-   |             while parsing this struct
-
 error: expected `..`, found `...`
-  --> $DIR/issue-102806.rs:17:26
+  --> $DIR/issue-102806.rs:14:26
    |
 LL |     let _ = V3 { z: 0.0, ...Default::default() };
    |                          ^^^
@@ -28,24 +20,26 @@ help: use `..` to fill in the rest of the fields
 LL |     let _ = V3 { z: 0.0, ..Default::default() };
    |                          ~~
 
-error[E0063]: missing fields `x` and `y` in initializer of `V3`
-  --> $DIR/issue-102806.rs:10:13
+error: expected identifier, found `...`
+  --> $DIR/issue-102806.rs:17:26
    |
-LL |     let _ = V3 { z: 0.0, ...v};
-   |             ^^ missing `x` and `y`
+LL |     let _ = V3 { z: 0.0, ... };
+   |             --           ^^^ expected identifier
+   |             |
+   |             while parsing this struct
 
-error[E0063]: missing fields `x` and `y` in initializer of `V3`
-  --> $DIR/issue-102806.rs:13:13
+error: expected field pattern, found `...`
+  --> $DIR/issue-102806.rs:21:22
    |
-LL |     let _ = V3 { z: 0.0, ... };
-   |             ^^ missing `x` and `y`
+LL |     let V3 { z: val, ... } = v;
+   |                      ^^^ help: to omit remaining fields, use one fewer `.`: `..`
 
 error[E0063]: missing fields `x` and `y` in initializer of `V3`
   --> $DIR/issue-102806.rs:17:13
    |
-LL |     let _ = V3 { z: 0.0, ...Default::default() };
+LL |     let _ = V3 { z: 0.0, ... };
    |             ^^ missing `x` and `y`
 
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0063`.