mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 15:01:51 +00:00
Change enum parse recovery
This commit is contained in:
parent
1994abed74
commit
db39068ad7
@ -1415,8 +1415,8 @@ impl<'a> Parser<'a> {
|
|||||||
self.bump();
|
self.bump();
|
||||||
(thin_vec![], false)
|
(thin_vec![], false)
|
||||||
} else {
|
} else {
|
||||||
self.parse_delim_comma_seq(Delimiter::Brace, |p| p.parse_enum_variant()).map_err(
|
self.parse_delim_comma_seq(Delimiter::Brace, |p| p.parse_enum_variant(id.span))
|
||||||
|mut err| {
|
.map_err(|mut err| {
|
||||||
err.span_label(id.span, "while parsing this enum");
|
err.span_label(id.span, "while parsing this enum");
|
||||||
if self.token == token::Colon {
|
if self.token == token::Colon {
|
||||||
let snapshot = self.create_snapshot_for_diagnostic();
|
let snapshot = self.create_snapshot_for_diagnostic();
|
||||||
@ -1436,17 +1436,17 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
self.restore_snapshot(snapshot);
|
self.restore_snapshot(snapshot);
|
||||||
}
|
}
|
||||||
self.recover_stmt();
|
self.eat_to_tokens(&[&token::CloseDelim(Delimiter::Brace)]);
|
||||||
|
self.bump(); // }
|
||||||
err
|
err
|
||||||
},
|
})?
|
||||||
)?
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let enum_definition = EnumDef { variants: variants.into_iter().flatten().collect() };
|
let enum_definition = EnumDef { variants: variants.into_iter().flatten().collect() };
|
||||||
Ok((id, ItemKind::Enum(enum_definition, generics)))
|
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();
|
self.recover_diff_marker();
|
||||||
let variant_attrs = self.parse_outer_attributes()?;
|
let variant_attrs = self.parse_outer_attributes()?;
|
||||||
self.recover_diff_marker();
|
self.recover_diff_marker();
|
||||||
@ -1476,10 +1476,37 @@ impl<'a> Parser<'a> {
|
|||||||
let struct_def = if this.check(&token::OpenDelim(Delimiter::Brace)) {
|
let struct_def = if this.check(&token::OpenDelim(Delimiter::Brace)) {
|
||||||
// Parse a struct variant.
|
// Parse a struct variant.
|
||||||
let (fields, recovered) =
|
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)
|
VariantData::Struct(fields, recovered)
|
||||||
} else if this.check(&token::OpenDelim(Delimiter::Parenthesis)) {
|
} 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 {
|
} else {
|
||||||
VariantData::Unit(DUMMY_NODE_ID)
|
VariantData::Unit(DUMMY_NODE_ID)
|
||||||
};
|
};
|
||||||
|
@ -11,8 +11,14 @@ LL | enum e{A((?'a a+?+l))}
|
|||||||
| - ^ expected one of `)`, `+`, or `,`
|
| - ^ expected one of `)`, `+`, or `,`
|
||||||
| |
|
| |
|
||||||
| while parsing this enum
|
| while parsing this enum
|
||||||
|
|
||||||
|
error: expected item, found `)`
|
||||||
|
--> $DIR/issue-68890.rs:1:21
|
||||||
|
|
|
|
||||||
= help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
|
LL | enum e{A((?'a a+?+l))}
|
||||||
|
| ^ expected item
|
||||||
|
|
|
||||||
|
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
@ -13,16 +13,6 @@ LL | enum Test4 {
|
|||||||
| ----- while parsing this enum
|
| ----- while parsing this enum
|
||||||
LL | Nope(i32 {})
|
LL | Nope(i32 {})
|
||||||
| ^ expected one of 7 possible tokens
|
| ^ expected one of 7 possible tokens
|
||||||
|
|
|
||||||
= help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
|
|
||||||
|
|
||||||
error: expected item, found `}`
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/recover-enum2.rs:28:1
|
|
||||||
|
|
|
||||||
LL | }
|
|
||||||
| ^ expected item
|
|
||||||
|
|
|
||||||
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user