diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2019-01-21 15:28:51 -0800 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2019-01-21 15:47:23 -0800 |
| commit | 4745b86202f0e96b4c0d0de05220a5ac4b5308ef (patch) | |
| tree | 1c7f7912efac2e75ae727afc4000956438962697 /src/libsyntax/parse | |
| parent | defa61f3fb2612358b57c206c5e16da2751e6deb (diff) | |
| download | rust-4745b86202f0e96b4c0d0de05220a5ac4b5308ef.tar.gz rust-4745b86202f0e96b4c0d0de05220a5ac4b5308ef.zip | |
Accept more invalid code that is close to correct fields
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 22 |
1 files changed, 20 insertions, 2 deletions
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); |
