Rollup merge of #103012 - chenyukang:fix-102806, r=davidtwco,compiler-errors

Suggest use .. to fill in the rest of the fields of Struct

Fixes #102806
This commit is contained in:
Matthias Krüger 2022-11-06 08:35:26 +01:00 committed by GitHub
commit 58f5d57b5d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 98 additions and 4 deletions

View 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

View 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(applicability = "maybe-incorrect", code = "..", style = "verbose")]
pub sugg_span: Span,
}
#[derive(Diagnostic)]
#[diag(parser_invalid_block_macro_segment)]
pub(crate) struct InvalidBlockMacroSegment {

View file

@ -20,9 +20,9 @@ use crate::errors::{
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,
@ -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_field_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)) {
@ -3027,6 +3027,18 @@ impl<'a> Parser<'a> {
self.recover_stmt();
}
fn recover_struct_field_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()?;

View file

@ -0,0 +1,25 @@
#![allow(dead_code)]
#[derive(Default)]
struct V3 {
x: f32,
y: f32,
z: f32,
}
fn pz(v: V3) {
let _ = V3 { z: 0.0, ...v};
//~^ ERROR expected `..`
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() {}

View file

@ -0,0 +1,45 @@
error: expected `..`, found `...`
--> $DIR/issue-102806.rs:11: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 `..`, found `...`
--> $DIR/issue-102806.rs:14: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: expected identifier, found `...`
--> $DIR/issue-102806.rs:17:26
|
LL | let _ = V3 { z: 0.0, ... };
| -- ^^^ expected identifier
| |
| while parsing this struct
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 `.`: `..`
error[E0063]: missing fields `x` and `y` in initializer of `V3`
--> $DIR/issue-102806.rs:17:13
|
LL | let _ = V3 { z: 0.0, ... };
| ^^ missing `x` and `y`
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0063`.