diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2023-11-06 23:24:42 +0000 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2023-11-29 18:47:31 +0000 |
| commit | db39068ad7060bf2375535e50aeb3e42d9f939bd (patch) | |
| tree | bd84df8a60528c0ce47ee63b40cf6c0ecf5f81f7 /compiler/rustc_parse/src | |
| parent | 1994abed74b3f39297f49a9caed1513eb12b21b3 (diff) | |
| download | rust-db39068ad7060bf2375535e50aeb3e42d9f939bd.tar.gz rust-db39068ad7060bf2375535e50aeb3e42d9f939bd.zip | |
Change enum parse recovery
Diffstat (limited to 'compiler/rustc_parse/src')
| -rw-r--r-- | compiler/rustc_parse/src/parser/item.rs | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 23886b1208b..5e73472c842 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1415,8 +1415,8 @@ impl<'a> Parser<'a> { self.bump(); (thin_vec![], false) } else { - self.parse_delim_comma_seq(Delimiter::Brace, |p| p.parse_enum_variant()).map_err( - |mut err| { + self.parse_delim_comma_seq(Delimiter::Brace, |p| p.parse_enum_variant(id.span)) + .map_err(|mut err| { err.span_label(id.span, "while parsing this enum"); if self.token == token::Colon { let snapshot = self.create_snapshot_for_diagnostic(); @@ -1436,17 +1436,17 @@ impl<'a> Parser<'a> { } self.restore_snapshot(snapshot); } - self.recover_stmt(); + self.eat_to_tokens(&[&token::CloseDelim(Delimiter::Brace)]); + self.bump(); // } err - }, - )? + })? }; let enum_definition = EnumDef { variants: variants.into_iter().flatten().collect() }; Ok((id, ItemKind::Enum(enum_definition, generics))) } - fn parse_enum_variant(&mut self) -> PResult<'a, Option<Variant>> { + fn parse_enum_variant(&mut self, span: Span) -> PResult<'a, Option<Variant>> { self.recover_diff_marker(); let variant_attrs = self.parse_outer_attributes()?; self.recover_diff_marker(); @@ -1476,10 +1476,37 @@ impl<'a> Parser<'a> { let struct_def = if this.check(&token::OpenDelim(Delimiter::Brace)) { // Parse a struct variant. let (fields, recovered) = - this.parse_record_struct_body("struct", ident.span, false)?; + match this.parse_record_struct_body("struct", ident.span, false) { + Ok((fields, recovered)) => (fields, recovered), + Err(mut err) => { + if this.token == token::Colon { + // We handle `enum` to `struct` suggestion in the caller. + return Err(err); + } + this.eat_to_tokens(&[&token::CloseDelim(Delimiter::Brace)]); + this.bump(); // } + err.span_label(span, "while parsing this enum"); + err.emit(); + (thin_vec![], true) + } + }; VariantData::Struct(fields, recovered) } else if this.check(&token::OpenDelim(Delimiter::Parenthesis)) { - VariantData::Tuple(this.parse_tuple_struct_body()?, DUMMY_NODE_ID) + let body = match this.parse_tuple_struct_body() { + Ok(body) => body, + Err(mut err) => { + if this.token == token::Colon { + // We handle `enum` to `struct` suggestion in the caller. + return Err(err); + } + this.eat_to_tokens(&[&token::CloseDelim(Delimiter::Parenthesis)]); + this.bump(); // ) + err.span_label(span, "while parsing this enum"); + err.emit(); + thin_vec![] + } + }; + VariantData::Tuple(body, DUMMY_NODE_ID) } else { VariantData::Unit(DUMMY_NODE_ID) }; |
