]> git.lizzy.rs Git - rust.git/commitdiff
fix #102806, suggest use .. to fill in the rest of the fields of Struct
authoryukang <moorekang@gmail.com>
Thu, 13 Oct 2022 15:27:17 +0000 (23:27 +0800)
committeryukang <moorekang@gmail.com>
Fri, 4 Nov 2022 02:35:36 +0000 (10:35 +0800)
compiler/rustc_error_messages/locales/en-US/parser.ftl
compiler/rustc_parse/src/errors.rs
compiler/rustc_parse/src/parser/expr.rs
src/test/ui/parser/issue-102806.rs [new file with mode: 0644]
src/test/ui/parser/issue-102806.stderr [new file with mode: 0644]

index 13c368d1c58501ab6fbd011d3273985e8c29b6d9..455ff34f7247f3a8d632ac6e57c50c46094b91df 100644 (file)
@@ -112,6 +112,9 @@ parser_missing_semicolon_before_array = expected `;`, found `[`
 parser_invalid_block_macro_segment = cannot use a `block` macro fragment here
     .label = the `block` fragment is within this context
 
+parser_expect_dotdot_not_dotdotdot = expected `..`, found `...`
+    .suggestion = use `..` to fill in the rest of the fields
+
 parser_if_expression_missing_then_block = this `if` expression is missing a block after the condition
     .add_then_block = add a block here
     .condition_possibly_unfinished = this binary operation is possibly unfinished
index dc2049028429367100d42c6873efa35e610e0522..b02bd664533736734f0d0e6a0959efc2e95226f2 100644 (file)
@@ -368,6 +368,15 @@ pub(crate) struct MissingSemicolonBeforeArray {
     pub semicolon: Span,
 }
 
+#[derive(Diagnostic)]
+#[diag(parser_expect_dotdot_not_dotdotdot)]
+pub(crate) struct MissingDotDot {
+    #[primary_span]
+    pub token_span: Span,
+    #[suggestion_verbose(applicability = "maybe-incorrect", code = "..")]
+    pub sugg_span: Span,
+}
+
 #[derive(Diagnostic)]
 #[diag(parser_invalid_block_macro_segment)]
 pub(crate) struct InvalidBlockMacroSegment {
index 0eb633f64168711bef38b86a901bfb207ec04e02..7de025e7860dd0fd6637d06595ad45788852066a 100644 (file)
@@ -20,9 +20,9 @@
     InvalidNumLiteralSuffix, LabeledLoopInBreak, LeadingPlusNotSupported, LeftArrowOperator,
     LifetimeInBorrowExpression, MacroInvocationWithQualifiedPath, MalformedLoopLabel,
     MatchArmBodyWithoutBraces, MatchArmBodyWithoutBracesSugg, MissingCommaAfterMatchArm,
-    MissingInInForLoop, MissingInInForLoopSub, MissingSemicolonBeforeArray, NoFieldsForFnCall,
-    NotAsNegationOperator, NotAsNegationOperatorSub, OctalFloatLiteralNotSupported,
-    OuterAttributeNotAllowedOnIfElse, ParenthesesWithStructFields,
+    MissingDotDot, MissingInInForLoop, MissingInInForLoopSub, MissingSemicolonBeforeArray,
+    NoFieldsForFnCall, NotAsNegationOperator, NotAsNegationOperatorSub,
+    OctalFloatLiteralNotSupported, OuterAttributeNotAllowedOnIfElse, ParenthesesWithStructFields,
     RequireColonAfterLabeledExpression, ShiftInterpretedAsGeneric, StructLiteralNotAllowedHere,
     StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator, UnexpectedTokenAfterLabel,
     UnexpectedTokenAfterLabelSugg, WrapExpressionInParentheses,
@@ -2897,6 +2897,21 @@ pub(super) fn parse_struct_fields(
                 }
                 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();
diff --git a/src/test/ui/parser/issue-102806.rs b/src/test/ui/parser/issue-102806.rs
new file mode 100644 (file)
index 0000000..f5513c8
--- /dev/null
@@ -0,0 +1,22 @@
+#![allow(dead_code)]
+
+struct V3 {
+    x: f32,
+    y: f32,
+    z: f32,
+}
+
+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 `..`
+    //~| ERROR missing fields `x` and `y` in initializer of `V3`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-102806.stderr b/src/test/ui/parser/issue-102806.stderr
new file mode 100644 (file)
index 0000000..53a43b5
--- /dev/null
@@ -0,0 +1,51 @@
+error: expected `..`, found `...`
+  --> $DIR/issue-102806.rs:10:26
+   |
+LL |     let _ = V3 { z: 0.0, ...v};
+   |                          ^^^
+   |
+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
+   |
+LL |     let _ = V3 { z: 0.0, ...Default::default() };
+   |                          ^^^
+   |
+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
+   |
+LL |     let _ = V3 { z: 0.0, ...v};
+   |             ^^ missing `x` and `y`
+
+error[E0063]: missing fields `x` and `y` in initializer of `V3`
+  --> $DIR/issue-102806.rs:13:13
+   |
+LL |     let _ = V3 { z: 0.0, ... };
+   |             ^^ missing `x` and `y`
+
+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() };
+   |             ^^ missing `x` and `y`
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0063`.