Skip to content

Commit defa61f

Browse files
committed
Tweak field parse error recovery
1 parent 15bad8b commit defa61f

7 files changed

+20
-55
lines changed

src/libsyntax/parse/parser.rs

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2695,28 +2695,12 @@ impl<'a> Parser<'a> {
26952695
break;
26962696
}
26972697

2698-
let mut recovery_field = None;
2699-
if let token::Ident(ident, _) = self.token {
2700-
if !self.token.is_reserved_ident() {
2701-
let mut ident = ident.clone();
2702-
ident.span = self.span;
2703-
recovery_field = Some(ast::Field {
2704-
ident,
2705-
span: self.span,
2706-
expr: self.mk_expr(self.span, ExprKind::Err, ThinVec::new()),
2707-
is_shorthand: true,
2708-
attrs: ThinVec::new(),
2709-
});
2710-
}
2711-
}
2698+
let mut parsed_field = None;
27122699
match self.parse_field() {
2713-
Ok(f) => fields.push(f),
2700+
Ok(f) => parsed_field = Some(f),
27142701
Err(mut e) => {
27152702
e.span_label(struct_sp, "while parsing this struct");
27162703
e.emit();
2717-
if let Some(f) = recovery_field {
2718-
fields.push(f);
2719-
}
27202704

27212705
// If the next token is a comma, then try to parse
27222706
// what comes next as additional fields, rather than
@@ -2732,7 +2716,10 @@ impl<'a> Parser<'a> {
27322716

27332717
match self.expect_one_of(&[token::Comma],
27342718
&[token::CloseDelim(token::Brace)]) {
2735-
Ok(()) => {}
2719+
Ok(()) => if let Some(f) = parsed_field {
2720+
// only include the field if there's no parse error
2721+
fields.push(f);
2722+
}
27362723
Err(mut e) => {
27372724
e.span_label(struct_sp, "while parsing this struct");
27382725
e.emit();

src/test/ui/issues/issue-52496.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ fn main() {
77
let bar = 1.5f32;
88
let _ = Foo { bar.into(), bat: -1, . };
99
//~^ ERROR expected one of
10-
//~| ERROR mismatched types
11-
//~| ERROR missing field `baz` in initializer of `Foo`
10+
//~| ERROR missing fields `bar`, `baz` in initializer of `Foo`
1211
//~| ERROR expected identifier, found `.`
1312
}

src/test/ui/issues/issue-52496.stderr

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,12 @@ error[E0063]: missing field `bat` in initializer of `Foo`
2626
LL | let _ = Foo { bar: .5, baz: 42 };
2727
| ^^^ missing `bat`
2828

29-
error[E0308]: mismatched types
30-
--> $DIR/issue-52496.rs:8:19
31-
|
32-
LL | let _ = Foo { bar.into(), bat: -1, . };
33-
| ^^^ expected f64, found f32
34-
help: you can cast an `f32` to `f64` in a lossless way
35-
|
36-
LL | let _ = Foo { bar.into().into(), bat: -1, . };
37-
| ^^^^^^^^^^
38-
39-
error[E0063]: missing field `baz` in initializer of `Foo`
29+
error[E0063]: missing fields `bar`, `baz` in initializer of `Foo`
4030
--> $DIR/issue-52496.rs:8:13
4131
|
4232
LL | let _ = Foo { bar.into(), bat: -1, . };
43-
| ^^^ missing `baz`
33+
| ^^^ missing `bar`, `baz`
4434

45-
error: aborting due to 6 previous errors
35+
error: aborting due to 5 previous errors
4636

47-
Some errors occurred: E0063, E0308.
48-
For more information about an error, try `rustc --explain E0063`.
37+
For more information about this error, try `rustc --explain E0063`.

src/test/ui/parser/removed-syntax-with-1.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ fn main() {
77
let a = S { foo: (), bar: () };
88
let b = S { foo: () with a };
99
//~^ ERROR expected one of `,`, `.`, `?`, `}`, or an operator, found `with`
10-
//~| ERROR missing field `bar` in initializer of `main::S`
10+
//~| ERROR missing fields `bar`, `foo` in initializer of `main::S`
1111
}

src/test/ui/parser/removed-syntax-with-1.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ LL | let b = S { foo: () with a };
66
| |
77
| while parsing this struct
88

9-
error[E0063]: missing field `bar` in initializer of `main::S`
9+
error[E0063]: missing fields `bar`, `foo` in initializer of `main::S`
1010
--> $DIR/removed-syntax-with-1.rs:8:13
1111
|
1212
LL | let b = S { foo: () with a };
13-
| ^ missing `bar`
13+
| ^ missing `bar`, `foo`
1414

1515
error: aborting due to 2 previous errors
1616

src/test/ui/parser/removed-syntax-with-2.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,5 @@ fn main() {
77
let a = S { foo: (), bar: () };
88
let b = S { foo: (), with a };
99
//~^ ERROR expected one of `,` or `}`, found `a`
10-
//~| ERROR cannot find value `with` in this scope
11-
//~| ERROR struct `main::S` has no field named `with`
10+
//~| ERROR missing field `bar` in initializer of `main::S`
1211
}

src/test/ui/parser/removed-syntax-with-2.stderr

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,12 @@ LL | let b = S { foo: (), with a };
66
| |
77
| while parsing this struct
88

9-
error[E0425]: cannot find value `with` in this scope
10-
--> $DIR/removed-syntax-with-2.rs:8:26
9+
error[E0063]: missing field `bar` in initializer of `main::S`
10+
--> $DIR/removed-syntax-with-2.rs:8:13
1111
|
1212
LL | let b = S { foo: (), with a };
13-
| ^^^^ not found in this scope
13+
| ^ missing `bar`
1414

15-
error[E0560]: struct `main::S` has no field named `with`
16-
--> $DIR/removed-syntax-with-2.rs:8:26
17-
|
18-
LL | let b = S { foo: (), with a };
19-
| ^^^^ `main::S` does not have this field
20-
|
21-
= note: available fields are: `foo`, `bar`
22-
23-
error: aborting due to 3 previous errors
15+
error: aborting due to 2 previous errors
2416

25-
Some errors occurred: E0425, E0560.
26-
For more information about an error, try `rustc --explain E0425`.
17+
For more information about this error, try `rustc --explain E0063`.

0 commit comments

Comments
 (0)