Accept more invalid code that is close to correct fields
This commit is contained in:
parent
defa61f3fb
commit
4745b86202
3 changed files with 23 additions and 13 deletions
|
@ -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);
|
||||||
|
|
|
@ -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`
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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`.
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue