mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Don’t report missing fields in struct exprs with syntax errors.
This prevents spurious errors when a field is intended to be present
but a preceding syntax error caused it not to be parsed. For example,
StructName { foo: 1 bar: 2 }
will not successfully parse a field `bar`, and we will report the syntax
error but not the missing field.
This commit is contained in:
@@ -2202,7 +2202,16 @@ fn check_expr_struct_fields(
|
||||
};
|
||||
self.typeck_results.borrow_mut().fru_field_types_mut().insert(expr.hir_id, fru_tys);
|
||||
}
|
||||
rustc_hir::StructTailExpr::None | rustc_hir::StructTailExpr::NoneWithError(_) => {
|
||||
rustc_hir::StructTailExpr::NoneWithError(ErrorGuaranteed { .. }) => {
|
||||
// If parsing the struct recovered from a syntax error, do not report missing
|
||||
// fields. This prevents spurious errors when a field is intended to be present
|
||||
// but a preceding syntax error caused it not to be parsed. For example, if a
|
||||
// struct type `StructName` has fields `foo` and `bar`, then
|
||||
// StructName { foo(), bar: 2 }
|
||||
// will not successfully parse a field `foo`, but we will not mention that,
|
||||
// since the syntax error has already been reported.
|
||||
}
|
||||
rustc_hir::StructTailExpr::None => {
|
||||
if adt_kind != AdtKind::Union
|
||||
&& !remaining_fields.is_empty()
|
||||
//~ non_exhaustive already reported, which will only happen for extern modules
|
||||
|
||||
@@ -16,7 +16,6 @@ fn pz(v: V3) {
|
||||
|
||||
let _ = V3 { z: 0.0, ... };
|
||||
//~^ ERROR expected identifier
|
||||
//~| ERROR missing fields `x` and `y` in initializer of `V3`
|
||||
|
||||
let V3 { z: val, ... } = v;
|
||||
//~^ ERROR expected field pattern
|
||||
|
||||
@@ -31,7 +31,7 @@ LL | let _ = V3 { z: 0.0, ... };
|
||||
| while parsing this struct
|
||||
|
||||
error: expected field pattern, found `...`
|
||||
--> $DIR/issue-102806.rs:21:22
|
||||
--> $DIR/issue-102806.rs:20:22
|
||||
|
|
||||
LL | let V3 { z: val, ... } = v;
|
||||
| ^^^
|
||||
@@ -42,12 +42,5 @@ LL - let V3 { z: val, ... } = v;
|
||||
LL + let V3 { z: val, .. } = v;
|
||||
|
|
||||
|
||||
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 4 previous errors
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0063`.
|
||||
|
||||
@@ -7,6 +7,5 @@ fn main() {
|
||||
let bar = 1.5f32;
|
||||
let _ = Foo { bar.into(), bat: -1, . };
|
||||
//~^ ERROR expected one of
|
||||
//~| ERROR missing fields `bar` and `baz` in initializer of `Foo`
|
||||
//~| ERROR expected identifier, found `.`
|
||||
}
|
||||
|
||||
@@ -37,12 +37,6 @@ error[E0063]: missing field `bat` in initializer of `Foo`
|
||||
LL | let _ = Foo { bar: .5, baz: 42 };
|
||||
| ^^^ missing `bat`
|
||||
|
||||
error[E0063]: missing fields `bar` and `baz` in initializer of `Foo`
|
||||
--> $DIR/issue-52496.rs:8:13
|
||||
|
|
||||
LL | let _ = Foo { bar.into(), bat: -1, . };
|
||||
| ^^^ missing `bar` and `baz`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0063`.
|
||||
|
||||
@@ -7,5 +7,4 @@ struct S {
|
||||
let a = S { foo: (), bar: () };
|
||||
let b = S { foo: (), with a };
|
||||
//~^ ERROR expected one of `,`, `:`, or `}`, found `a`
|
||||
//~| ERROR missing field `bar` in initializer of `S`
|
||||
}
|
||||
|
||||
@@ -7,12 +7,5 @@ LL | let b = S { foo: (), with a };
|
||||
| | while parsing this struct field
|
||||
| while parsing this struct
|
||||
|
||||
error[E0063]: missing field `bar` in initializer of `S`
|
||||
--> $DIR/removed-syntax-with-2.rs:8:13
|
||||
|
|
||||
LL | let b = S { foo: (), with a };
|
||||
| ^ missing `bar`
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0063`.
|
||||
|
||||
@@ -5,5 +5,4 @@ fn main() {
|
||||
//~^ ERROR expected identifier, found `0`
|
||||
//~| ERROR expected identifier, found `1`
|
||||
//~| ERROR expected identifier, found `2`
|
||||
//~| ERROR missing fields `0`, `1` and `2` in initializer of `Rgb`
|
||||
}
|
||||
|
||||
@@ -22,12 +22,5 @@ LL | let _ = Rgb { 0, 1, 2 };
|
||||
| |
|
||||
| while parsing this struct
|
||||
|
||||
error[E0063]: missing fields `0`, `1` and `2` in initializer of `Rgb`
|
||||
--> $DIR/struct-field-numeric-shorthand.rs:4:13
|
||||
|
|
||||
LL | let _ = Rgb { 0, 1, 2 };
|
||||
| ^^^ missing `0`, `1` and `2`
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0063`.
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
// Check that a syntax error inside a struct literal does not also report missing fields,
|
||||
// because the field might be present but hidden by the syntax error.
|
||||
//
|
||||
// The stderr for this test should contain ONLY one syntax error per struct literal,
|
||||
// and not any errors about missing fields.
|
||||
|
||||
struct Foo { a: isize, b: isize }
|
||||
|
||||
fn make_a() -> isize { 1234 }
|
||||
|
||||
fn expr_wrong_separator() {
|
||||
let f = Foo { a: make_a(); b: 2 }; //~ ERROR found `;`
|
||||
}
|
||||
|
||||
fn expr_missing_separator() {
|
||||
let f = Foo { a: make_a() b: 2 }; //~ ERROR found `b`
|
||||
}
|
||||
|
||||
fn expr_rest_trailing_comma() {
|
||||
let f = Foo { a: make_a(), ..todo!(), }; //~ ERROR cannot use a comma
|
||||
}
|
||||
|
||||
fn expr_missing_field_name() {
|
||||
let f = Foo { make_a(), b: 2, }; //~ ERROR found `(`
|
||||
}
|
||||
|
||||
fn pat_wrong_separator(Foo { a; b }: Foo) { //~ ERROR expected `,`
|
||||
let _ = (a, b);
|
||||
}
|
||||
|
||||
fn pat_missing_separator(Foo { a b }: Foo) { //~ ERROR expected `,`
|
||||
let _ = (a, b);
|
||||
}
|
||||
|
||||
fn pat_rest_trailing_comma(Foo { a, .., }: Foo) { //~ ERROR expected `}`, found `,`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,74 @@
|
||||
error: expected one of `,`, `.`, `?`, `}`, or an operator, found `;`
|
||||
--> $DIR/syntax-error-not-missing-field.rs:12:30
|
||||
|
|
||||
LL | let f = Foo { a: make_a(); b: 2 };
|
||||
| --- ^
|
||||
| | |
|
||||
| | expected one of `,`, `.`, `?`, `}`, or an operator
|
||||
| | help: try adding a comma: `,`
|
||||
| while parsing this struct
|
||||
|
||||
error: expected one of `,`, `.`, `?`, `}`, or an operator, found `b`
|
||||
--> $DIR/syntax-error-not-missing-field.rs:16:31
|
||||
|
|
||||
LL | let f = Foo { a: make_a() b: 2 };
|
||||
| --- -^ expected one of `,`, `.`, `?`, `}`, or an operator
|
||||
| | |
|
||||
| | help: try adding a comma: `,`
|
||||
| while parsing this struct
|
||||
|
||||
error: cannot use a comma after the base struct
|
||||
--> $DIR/syntax-error-not-missing-field.rs:20:32
|
||||
|
|
||||
LL | let f = Foo { a: make_a(), ..todo!(), };
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: the base struct must always be the last field
|
||||
help: remove this comma
|
||||
|
|
||||
LL - let f = Foo { a: make_a(), ..todo!(), };
|
||||
LL + let f = Foo { a: make_a(), ..todo!() };
|
||||
|
|
||||
|
||||
error: expected one of `,`, `:`, or `}`, found `(`
|
||||
--> $DIR/syntax-error-not-missing-field.rs:24:25
|
||||
|
|
||||
LL | let f = Foo { make_a(), b: 2, };
|
||||
| --- ------^ expected one of `,`, `:`, or `}`
|
||||
| | |
|
||||
| | while parsing this struct field
|
||||
| while parsing this struct
|
||||
|
|
||||
help: try naming a field
|
||||
|
|
||||
LL | let f = Foo { make_a: make_a(), b: 2, };
|
||||
| +++++++
|
||||
|
||||
error: expected `,`
|
||||
--> $DIR/syntax-error-not-missing-field.rs:27:31
|
||||
|
|
||||
LL | fn pat_wrong_separator(Foo { a; b }: Foo) {
|
||||
| --- ^
|
||||
| |
|
||||
| while parsing the fields for this pattern
|
||||
|
||||
error: expected `,`
|
||||
--> $DIR/syntax-error-not-missing-field.rs:31:34
|
||||
|
|
||||
LL | fn pat_missing_separator(Foo { a b }: Foo) {
|
||||
| --- ^
|
||||
| |
|
||||
| while parsing the fields for this pattern
|
||||
|
||||
error: expected `}`, found `,`
|
||||
--> $DIR/syntax-error-not-missing-field.rs:35:39
|
||||
|
|
||||
LL | fn pat_rest_trailing_comma(Foo { a, .., }: Foo) {
|
||||
| --^
|
||||
| | |
|
||||
| | expected `}`
|
||||
| | help: remove this comma
|
||||
| `..` must be at the end and cannot have a trailing comma
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
@@ -7,7 +7,6 @@ pub struct Foo {
|
||||
|
||||
fn main() {
|
||||
let _ = Foo {
|
||||
//~^ ERROR missing field
|
||||
first: true,
|
||||
second: 25
|
||||
//~^ ERROR expected one of
|
||||
|
||||
@@ -7,7 +7,6 @@ pub struct Foo {
|
||||
|
||||
fn main() {
|
||||
let _ = Foo {
|
||||
//~^ ERROR missing field
|
||||
first: true
|
||||
second: 25
|
||||
//~^ ERROR expected one of
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
error: expected one of `,`, `.`, `?`, `}`, or an operator, found `second`
|
||||
--> $DIR/struct-initializer-comma.rs:12:9
|
||||
--> $DIR/struct-initializer-comma.rs:11:9
|
||||
|
|
||||
LL | let _ = Foo {
|
||||
| --- while parsing this struct
|
||||
LL |
|
||||
LL | first: true
|
||||
| -
|
||||
| |
|
||||
@@ -12,12 +11,5 @@ LL | first: true
|
||||
LL | second: 25
|
||||
| ^^^^^^ unexpected token
|
||||
|
||||
error[E0063]: missing field `second` in initializer of `Foo`
|
||||
--> $DIR/struct-initializer-comma.rs:9:13
|
||||
|
|
||||
LL | let _ = Foo {
|
||||
| ^^^ missing `second`
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0063`.
|
||||
|
||||
Reference in New Issue
Block a user