diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a2d3595b472..745f2c7dc19 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2695,6 +2695,21 @@ impl<'a> Parser<'a> { 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; match self.parse_field() { Ok(f) => parsed_field = Some(f), @@ -2716,11 +2731,14 @@ impl<'a> Parser<'a> { match self.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)]) { - Ok(()) => if let Some(f) = parsed_field { - // only include the field if there's no parse error + Ok(()) => if let Some(f) = parsed_field.or(recovery_field) { + // only include the field if there's no parse error for the field name fields.push(f); } Err(mut e) => { + if let Some(f) = recovery_field { + fields.push(f); + } e.span_label(struct_sp, "while parsing this struct"); e.emit(); self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore); diff --git a/src/test/ui/parser/removed-syntax-with-1.rs b/src/test/ui/parser/removed-syntax-with-1.rs index add024ea390..2c1e152dcee 100644 --- a/src/test/ui/parser/removed-syntax-with-1.rs +++ b/src/test/ui/parser/removed-syntax-with-1.rs @@ -5,7 +5,6 @@ fn main() { } 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 missing fields `bar`, `foo` in initializer of `main::S` } diff --git a/src/test/ui/parser/removed-syntax-with-1.stderr b/src/test/ui/parser/removed-syntax-with-1.stderr index aae29efa85e..a157873916a 100644 --- a/src/test/ui/parser/removed-syntax-with-1.stderr +++ b/src/test/ui/parser/removed-syntax-with-1.stderr @@ -1,17 +1,10 @@ error: expected one of `,`, `.`, `?`, `}`, or an operator, found `with` --> $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 | | | while parsing this struct -error[E0063]: missing fields `bar`, `foo` in initializer of `main::S` - --> $DIR/removed-syntax-with-1.rs:8:13 - | -LL | let b = S { foo: () with a }; - | ^ missing `bar`, `foo` +error: aborting due to previous error -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0063`.