Skip to content

Commit 4745b86

Browse files
committed
Accept more invalid code that is close to correct fields
1 parent defa61f commit 4745b86

File tree

3 files changed

+23
-13
lines changed

3 files changed

+23
-13
lines changed

src/libsyntax/parse/parser.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -2695,6 +2695,21 @@ 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() && self.look_ahead(1, |t| *t == token::Colon) {
2701+
// Use in case of error after field-looking code: `S { foo: () with a }`
2702+
let mut ident = ident.clone();
2703+
ident.span = self.span;
2704+
recovery_field = Some(ast::Field {
2705+
ident,
2706+
span: self.span,
2707+
expr: self.mk_expr(self.span, ExprKind::Err, ThinVec::new()),
2708+
is_shorthand: false,
2709+
attrs: ThinVec::new(),
2710+
});
2711+
}
2712+
}
26982713
let mut parsed_field = None;
26992714
match self.parse_field() {
27002715
Ok(f) => parsed_field = Some(f),
@@ -2716,11 +2731,14 @@ impl<'a> Parser<'a> {
27162731

27172732
match self.expect_one_of(&[token::Comma],
27182733
&[token::CloseDelim(token::Brace)]) {
2719-
Ok(()) => if let Some(f) = parsed_field {
2720-
// only include the field if there's no parse error
2734+
Ok(()) => if let Some(f) = parsed_field.or(recovery_field) {
2735+
// only include the field if there's no parse error for the field name
27212736
fields.push(f);
27222737
}
27232738
Err(mut e) => {
2739+
if let Some(f) = recovery_field {
2740+
fields.push(f);
2741+
}
27242742
e.span_label(struct_sp, "while parsing this struct");
27252743
e.emit();
27262744
self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore);

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ fn main() {
55
}
66

77
let a = S { foo: (), bar: () };
8-
let b = S { foo: () with a };
8+
let b = S { foo: () with a, bar: () };
99
//~^ ERROR expected one of `,`, `.`, `?`, `}`, or an operator, found `with`
10-
//~| ERROR missing fields `bar`, `foo` in initializer of `main::S`
1110
}
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,10 @@
11
error: expected one of `,`, `.`, `?`, `}`, or an operator, found `with`
22
--> $DIR/removed-syntax-with-1.rs:8:25
33
|
4-
LL | let b = S { foo: () with a };
4+
LL | let b = S { foo: () with a, bar: () };
55
| - ^^^^ expected one of `,`, `.`, `?`, `}`, or an operator here
66
| |
77
| while parsing this struct
88

9-
error[E0063]: missing fields `bar`, `foo` in initializer of `main::S`
10-
--> $DIR/removed-syntax-with-1.rs:8:13
11-
|
12-
LL | let b = S { foo: () with a };
13-
| ^ missing `bar`, `foo`
14-
15-
error: aborting due to 2 previous errors
9+
error: aborting due to previous error
1610

17-
For more information about this error, try `rustc --explain E0063`.

0 commit comments

Comments
 (0)