Skip to content

Commit 1e25882

Browse files
committed
fix #102806, suggest use .. to fill in the rest of the fields of Struct
1 parent 6718ea1 commit 1e25882

File tree

5 files changed

+103
-3
lines changed

5 files changed

+103
-3
lines changed

compiler/rustc_error_messages/locales/en-US/parser.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ parser_missing_semicolon_before_array = expected `;`, found `[`
112112
parser_invalid_block_macro_segment = cannot use a `block` macro fragment here
113113
.label = the `block` fragment is within this context
114114
115+
parser_expect_dotdot_not_dotdotdot = expected `..`, found `...`
116+
.suggestion = use `..` to fill in the rest of the fields
117+
115118
parser_if_expression_missing_then_block = this `if` expression is missing a block after the condition
116119
.add_then_block = add a block here
117120
.condition_possibly_unfinished = this binary operation is possibly unfinished

compiler/rustc_parse/src/errors.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,15 @@ pub(crate) struct MissingSemicolonBeforeArray {
368368
pub semicolon: Span,
369369
}
370370

371+
#[derive(Diagnostic)]
372+
#[diag(parser_expect_dotdot_not_dotdotdot)]
373+
pub(crate) struct MissingDotDot {
374+
#[primary_span]
375+
pub token_span: Span,
376+
#[suggestion_verbose(applicability = "maybe-incorrect", code = "..")]
377+
pub sugg_span: Span,
378+
}
379+
371380
#[derive(Diagnostic)]
372381
#[diag(parser_invalid_block_macro_segment)]
373382
pub(crate) struct InvalidBlockMacroSegment {

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ use crate::errors::{
2020
InvalidNumLiteralSuffix, LabeledLoopInBreak, LeadingPlusNotSupported, LeftArrowOperator,
2121
LifetimeInBorrowExpression, MacroInvocationWithQualifiedPath, MalformedLoopLabel,
2222
MatchArmBodyWithoutBraces, MatchArmBodyWithoutBracesSugg, MissingCommaAfterMatchArm,
23-
MissingInInForLoop, MissingInInForLoopSub, MissingSemicolonBeforeArray, NoFieldsForFnCall,
24-
NotAsNegationOperator, NotAsNegationOperatorSub, OctalFloatLiteralNotSupported,
25-
OuterAttributeNotAllowedOnIfElse, ParenthesesWithStructFields,
23+
MissingDotDot, MissingInInForLoop, MissingInInForLoopSub, MissingSemicolonBeforeArray,
24+
NoFieldsForFnCall, NotAsNegationOperator, NotAsNegationOperatorSub,
25+
OctalFloatLiteralNotSupported, OuterAttributeNotAllowedOnIfElse, ParenthesesWithStructFields,
2626
RequireColonAfterLabeledExpression, ShiftInterpretedAsGeneric, StructLiteralNotAllowedHere,
2727
StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator, UnexpectedTokenAfterLabel,
2828
UnexpectedTokenAfterLabelSugg, WrapExpressionInParentheses,
@@ -2897,6 +2897,21 @@ impl<'a> Parser<'a> {
28972897
}
28982898
self.recover_struct_comma_after_dotdot(exp_span);
28992899
break;
2900+
} else if self.token == token::DotDotDot {
2901+
// suggest `..v` instead of `...v`
2902+
let snapshot = self.create_snapshot_for_diagnostic();
2903+
let span = self.token.span;
2904+
self.bump();
2905+
match self.parse_expr() {
2906+
Ok(_p) => {
2907+
self.sess.emit_err(MissingDotDot { token_span: span, sugg_span: span });
2908+
break;
2909+
}
2910+
Err(inner_err) => {
2911+
inner_err.cancel();
2912+
self.restore_snapshot(snapshot);
2913+
}
2914+
}
29002915
}
29012916

29022917
let recovery_field = self.find_struct_error_after_field_looking_code();

src/test/ui/parser/issue-102806.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#![allow(dead_code)]
2+
3+
struct V3 {
4+
x: f32,
5+
y: f32,
6+
z: f32,
7+
}
8+
9+
fn pz(v: V3) {
10+
let _ = V3 { z: 0.0, ...v};
11+
//~^ ERROR expected `..`
12+
//~| ERROR missing fields `x` and `y` in initializer of `V3`
13+
let _ = V3 { z: 0.0, ... };
14+
//~^ expected identifier
15+
//~| ERROR missing fields `x` and `y` in initializer of `V3`
16+
17+
let _ = V3 { z: 0.0, ...Default::default() };
18+
//~^ ERROR expected `..`
19+
//~| ERROR missing fields `x` and `y` in initializer of `V3`
20+
}
21+
22+
fn main() {}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
error: expected `..`, found `...`
2+
--> $DIR/issue-102806.rs:10:26
3+
|
4+
LL | let _ = V3 { z: 0.0, ...v};
5+
| ^^^
6+
|
7+
help: use `..` to fill in the rest of the fields
8+
|
9+
LL | let _ = V3 { z: 0.0, ..v};
10+
| ~~
11+
12+
error: expected identifier, found `...`
13+
--> $DIR/issue-102806.rs:13:26
14+
|
15+
LL | let _ = V3 { z: 0.0, ... };
16+
| -- ^^^ expected identifier
17+
| |
18+
| while parsing this struct
19+
20+
error: expected `..`, found `...`
21+
--> $DIR/issue-102806.rs:17:26
22+
|
23+
LL | let _ = V3 { z: 0.0, ...Default::default() };
24+
| ^^^
25+
|
26+
help: use `..` to fill in the rest of the fields
27+
|
28+
LL | let _ = V3 { z: 0.0, ..Default::default() };
29+
| ~~
30+
31+
error[E0063]: missing fields `x` and `y` in initializer of `V3`
32+
--> $DIR/issue-102806.rs:10:13
33+
|
34+
LL | let _ = V3 { z: 0.0, ...v};
35+
| ^^ missing `x` and `y`
36+
37+
error[E0063]: missing fields `x` and `y` in initializer of `V3`
38+
--> $DIR/issue-102806.rs:13:13
39+
|
40+
LL | let _ = V3 { z: 0.0, ... };
41+
| ^^ missing `x` and `y`
42+
43+
error[E0063]: missing fields `x` and `y` in initializer of `V3`
44+
--> $DIR/issue-102806.rs:17:13
45+
|
46+
LL | let _ = V3 { z: 0.0, ...Default::default() };
47+
| ^^ missing `x` and `y`
48+
49+
error: aborting due to 6 previous errors
50+
51+
For more information about this error, try `rustc --explain E0063`.

0 commit comments

Comments
 (0)