1
Fork 0

Accept more invalid code that is close to correct fields

This commit is contained in:
Esteban Küber 2019-01-21 15:28:51 -08:00
parent defa61f3fb
commit 4745b86202
3 changed files with 23 additions and 13 deletions

View file

@ -2695,6 +2695,21 @@ impl<'a> Parser<'a> {
break; break;
} }
let mut recovery_field = None;
if let token::Ident(ident, _) = self.token {
if !self.token.is_reserved_ident() && self.look_ahead(1, |t| *t == token::Colon) {
// Use in case of error after field-looking code: `S { foo: () with a }`
let mut ident = ident.clone();
ident.span = self.span;
recovery_field = Some(ast::Field {
ident,
span: self.span,
expr: self.mk_expr(self.span, ExprKind::Err, ThinVec::new()),
is_shorthand: false,
attrs: ThinVec::new(),
});
}
}
let mut parsed_field = None; let mut parsed_field = None;
match self.parse_field() { match self.parse_field() {
Ok(f) => parsed_field = Some(f), Ok(f) => parsed_field = Some(f),
@ -2716,11 +2731,14 @@ impl<'a> Parser<'a> {
match self.expect_one_of(&[token::Comma], match self.expect_one_of(&[token::Comma],
&[token::CloseDelim(token::Brace)]) { &[token::CloseDelim(token::Brace)]) {
Ok(()) => if let Some(f) = parsed_field { Ok(()) => if let Some(f) = parsed_field.or(recovery_field) {
// only include the field if there's no parse error // only include the field if there's no parse error for the field name
fields.push(f); fields.push(f);
} }
Err(mut e) => { Err(mut e) => {
if let Some(f) = recovery_field {
fields.push(f);
}
e.span_label(struct_sp, "while parsing this struct"); e.span_label(struct_sp, "while parsing this struct");
e.emit(); e.emit();
self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore); self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore);

View file

@ -5,7 +5,6 @@ fn main() {
} }
let a = S { foo: (), bar: () }; let a = S { foo: (), bar: () };
let b = S { foo: () with a }; let b = S { foo: () with a, bar: () };
//~^ ERROR expected one of `,`, `.`, `?`, `}`, or an operator, found `with` //~^ ERROR expected one of `,`, `.`, `?`, `}`, or an operator, found `with`
//~| ERROR missing fields `bar`, `foo` in initializer of `main::S`
} }

View file

@ -1,17 +1,10 @@
error: expected one of `,`, `.`, `?`, `}`, or an operator, found `with` error: expected one of `,`, `.`, `?`, `}`, or an operator, found `with`
--> $DIR/removed-syntax-with-1.rs:8:25 --> $DIR/removed-syntax-with-1.rs:8:25
| |
LL | let b = S { foo: () with a }; LL | let b = S { foo: () with a, bar: () };
| - ^^^^ expected one of `,`, `.`, `?`, `}`, or an operator here | - ^^^^ expected one of `,`, `.`, `?`, `}`, or an operator here
| | | |
| while parsing this struct | while parsing this struct
error[E0063]: missing fields `bar`, `foo` in initializer of `main::S` error: aborting due to previous error
--> $DIR/removed-syntax-with-1.rs:8:13
|
LL | let b = S { foo: () with a };
| ^ missing `bar`, `foo`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0063`.