mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-10 14:02:57 +00:00
Refactor 'parse_enum_item' to use 'parse_delim_comma_seq'
This commit is contained in:
parent
7d761fe046
commit
5c34a11324
@ -7,7 +7,7 @@ use syntax::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, An
|
||||
use syntax::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind};
|
||||
use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness, Extern, StrLit};
|
||||
use syntax::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
|
||||
use syntax::ast::{Ty, TyKind, Generics, TraitRef, EnumDef, VariantData, StructField};
|
||||
use syntax::ast::{Ty, TyKind, Generics, TraitRef, EnumDef, Variant, VariantData, StructField};
|
||||
use syntax::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, FnSig, SelfKind, Param};
|
||||
use syntax::print::pprust;
|
||||
use syntax::ptr::P;
|
||||
@ -1324,85 +1324,65 @@ impl<'a> Parser<'a> {
|
||||
let id = self.parse_ident()?;
|
||||
let mut generics = self.parse_generics()?;
|
||||
generics.where_clause = self.parse_where_clause()?;
|
||||
self.expect(&token::OpenDelim(token::Brace))?;
|
||||
|
||||
let enum_definition = self.parse_enum_def(&generics).map_err(|e| {
|
||||
let (variants, _) = self.parse_delim_comma_seq(
|
||||
token::Brace,
|
||||
|p| p.parse_enum_item(),
|
||||
).map_err(|e| {
|
||||
self.recover_stmt();
|
||||
self.eat(&token::CloseDelim(token::Brace));
|
||||
e
|
||||
})?;
|
||||
|
||||
let enum_definition = EnumDef {
|
||||
variants: variants.into_iter().filter_map(|v| v).collect(),
|
||||
};
|
||||
Ok((id, ItemKind::Enum(enum_definition, generics), None))
|
||||
}
|
||||
|
||||
/// Parses the part of an enum declaration following the `{`.
|
||||
fn parse_enum_def(&mut self, _generics: &Generics) -> PResult<'a, EnumDef> {
|
||||
let mut variants = Vec::new();
|
||||
// FIXME: Consider using `parse_delim_comma_seq`.
|
||||
// We could then remove eating comma in `recover_nested_adt_item`.
|
||||
while self.token != token::CloseDelim(token::Brace) {
|
||||
let variant_attrs = self.parse_outer_attributes()?;
|
||||
let vlo = self.token.span;
|
||||
fn parse_enum_item(&mut self) -> PResult<'a, Option<Variant>> {
|
||||
let variant_attrs = self.parse_outer_attributes()?;
|
||||
let vlo = self.token.span;
|
||||
|
||||
let vis = self.parse_visibility(FollowedByType::No)?;
|
||||
if !self.recover_nested_adt_item(kw::Enum)? {
|
||||
// Item already parsed, we need to skip this variant.
|
||||
continue
|
||||
}
|
||||
let ident = self.parse_ident()?;
|
||||
|
||||
let struct_def = if self.check(&token::OpenDelim(token::Brace)) {
|
||||
// Parse a struct variant.
|
||||
let (fields, recovered) = self.parse_record_struct_body()?;
|
||||
VariantData::Struct(fields, recovered)
|
||||
} else if self.check(&token::OpenDelim(token::Paren)) {
|
||||
VariantData::Tuple(
|
||||
self.parse_tuple_struct_body()?,
|
||||
DUMMY_NODE_ID,
|
||||
)
|
||||
} else {
|
||||
VariantData::Unit(DUMMY_NODE_ID)
|
||||
};
|
||||
|
||||
let disr_expr = if self.eat(&token::Eq) {
|
||||
Some(AnonConst {
|
||||
id: DUMMY_NODE_ID,
|
||||
value: self.parse_expr()?,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let vr = ast::Variant {
|
||||
ident,
|
||||
vis,
|
||||
id: DUMMY_NODE_ID,
|
||||
attrs: variant_attrs,
|
||||
data: struct_def,
|
||||
disr_expr,
|
||||
span: vlo.to(self.prev_span),
|
||||
is_placeholder: false,
|
||||
};
|
||||
variants.push(vr);
|
||||
|
||||
if !self.eat(&token::Comma) {
|
||||
if self.token.is_ident() && !self.token.is_reserved_ident() {
|
||||
let sp = self.sess.source_map().next_point(self.prev_span);
|
||||
self.struct_span_err(sp, "missing comma")
|
||||
.span_suggestion_short(
|
||||
sp,
|
||||
"missing comma",
|
||||
",".to_owned(),
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
.emit();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let vis = self.parse_visibility(FollowedByType::No)?;
|
||||
if !self.recover_nested_adt_item(kw::Enum)? {
|
||||
return Ok(None)
|
||||
}
|
||||
self.expect(&token::CloseDelim(token::Brace))?;
|
||||
let ident = self.parse_ident()?;
|
||||
|
||||
Ok(ast::EnumDef { variants })
|
||||
let struct_def = if self.check(&token::OpenDelim(token::Brace)) {
|
||||
// Parse a struct variant.
|
||||
let (fields, recovered) = self.parse_record_struct_body()?;
|
||||
VariantData::Struct(fields, recovered)
|
||||
} else if self.check(&token::OpenDelim(token::Paren)) {
|
||||
VariantData::Tuple(
|
||||
self.parse_tuple_struct_body()?,
|
||||
DUMMY_NODE_ID,
|
||||
)
|
||||
} else {
|
||||
VariantData::Unit(DUMMY_NODE_ID)
|
||||
};
|
||||
|
||||
let disr_expr = if self.eat(&token::Eq) {
|
||||
Some(AnonConst {
|
||||
id: DUMMY_NODE_ID,
|
||||
value: self.parse_expr()?,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let vr = ast::Variant {
|
||||
ident,
|
||||
vis,
|
||||
id: DUMMY_NODE_ID,
|
||||
attrs: variant_attrs,
|
||||
data: struct_def,
|
||||
disr_expr,
|
||||
span: vlo.to(self.prev_span),
|
||||
is_placeholder: false,
|
||||
};
|
||||
|
||||
Ok(Some(vr))
|
||||
}
|
||||
|
||||
/// Parses `struct Foo { ... }`.
|
||||
@ -1759,7 +1739,6 @@ impl<'a> Parser<'a> {
|
||||
let kw_token = self.token.clone();
|
||||
let kw_str = pprust::token_to_string(&kw_token);
|
||||
let item = self.parse_item()?;
|
||||
self.eat(&token::Comma);
|
||||
|
||||
self.struct_span_err(
|
||||
kw_token.span,
|
||||
|
@ -805,21 +805,39 @@ impl<'a> Parser<'a> {
|
||||
recovered = true;
|
||||
break;
|
||||
}
|
||||
Err(mut e) => {
|
||||
Err(mut expect_err) => {
|
||||
let sp = self.sess.source_map().next_point(self.prev_span);
|
||||
let token_str = pprust::token_kind_to_string(t);
|
||||
|
||||
// Attempt to keep parsing if it was a similar separator.
|
||||
if let Some(ref tokens) = t.similar_tokens() {
|
||||
if tokens.contains(&self.token.kind) {
|
||||
self.bump();
|
||||
}
|
||||
}
|
||||
e.emit();
|
||||
|
||||
// Attempt to keep parsing if it was an omitted separator.
|
||||
match f(self) {
|
||||
Ok(t) => {
|
||||
// Parsed successfully, therefore most probably the code only
|
||||
// misses a separator.
|
||||
expect_err
|
||||
.span_suggestion_short(
|
||||
sp,
|
||||
&format!("missing `{}`", token_str),
|
||||
token_str,
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
.emit();
|
||||
|
||||
v.push(t);
|
||||
continue;
|
||||
},
|
||||
Err(mut e) => {
|
||||
// Parsing failed, therefore it must be something more serious
|
||||
// than just a missing separator.
|
||||
expect_err.emit();
|
||||
|
||||
e.cancel();
|
||||
break;
|
||||
}
|
||||
|
@ -2,7 +2,10 @@ error: expected one of `)` or `,`, found `label`
|
||||
--> $DIR/expected-comma-found-token.rs:9:5
|
||||
|
|
||||
LL | message="the message"
|
||||
| - expected one of `)` or `,`
|
||||
| -
|
||||
| |
|
||||
| expected one of `)` or `,`
|
||||
| help: missing `,`
|
||||
LL | label="the label"
|
||||
| ^^^^^ unexpected token
|
||||
|
||||
|
@ -2,7 +2,10 @@ error: expected one of `)`, `,`, `@`, or `|`, found `[`
|
||||
--> $DIR/pat-lt-bracket-6.rs:5:19
|
||||
|
|
||||
LL | let Test(&desc[..]) = x;
|
||||
| ^ expected one of `)`, `,`, `@`, or `|`
|
||||
| ^
|
||||
| |
|
||||
| expected one of `)`, `,`, `@`, or `|`
|
||||
| help: missing `,`
|
||||
|
||||
error[E0658]: subslice patterns are unstable
|
||||
--> $DIR/pat-lt-bracket-6.rs:5:20
|
||||
|
@ -2,7 +2,10 @@ error: expected one of `)`, `,`, `@`, or `|`, found `[`
|
||||
--> $DIR/pat-lt-bracket-7.rs:5:16
|
||||
|
|
||||
LL | for Thing(x[]) in foo {}
|
||||
| ^ expected one of `)`, `,`, `@`, or `|`
|
||||
| ^
|
||||
| |
|
||||
| expected one of `)`, `,`, `@`, or `|`
|
||||
| help: missing `,`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/pat-lt-bracket-7.rs:9:30
|
||||
|
@ -1,11 +1,11 @@
|
||||
fn main() {
|
||||
enum Test {
|
||||
Very
|
||||
//~^ ERROR missing comma
|
||||
Bad(usize)
|
||||
//~^ ERROR missing comma
|
||||
Stuff { a: usize }
|
||||
//~^ ERROR missing comma
|
||||
Very //~ HELP missing `,`
|
||||
Bad(usize) //~ HELP missing `,`
|
||||
//~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found `Bad`
|
||||
Stuff { a: usize } //~ HELP missing `,`
|
||||
//~^ ERROR expected one of `,`, `=`, or `}`, found `Stuff`
|
||||
Here
|
||||
//~^ ERROR expected one of `,`, `=`, or `}`, found `Here`
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,37 @@
|
||||
error: missing comma
|
||||
--> $DIR/recover-enum.rs:3:13
|
||||
error: expected one of `(`, `,`, `=`, `{`, or `}`, found `Bad`
|
||||
--> $DIR/recover-enum.rs:4:9
|
||||
|
|
||||
LL | Very
|
||||
| ^ help: missing comma
|
||||
| -
|
||||
| |
|
||||
| expected one of `(`, `,`, `=`, `{`, or `}`
|
||||
| help: missing `,`
|
||||
LL | Bad(usize)
|
||||
| ^^^ unexpected token
|
||||
|
||||
error: missing comma
|
||||
--> $DIR/recover-enum.rs:5:19
|
||||
error: expected one of `,`, `=`, or `}`, found `Stuff`
|
||||
--> $DIR/recover-enum.rs:6:9
|
||||
|
|
||||
LL | Bad(usize)
|
||||
| ^ help: missing comma
|
||||
| -
|
||||
| |
|
||||
| expected one of `,`, `=`, or `}`
|
||||
| help: missing `,`
|
||||
LL |
|
||||
LL | Stuff { a: usize }
|
||||
| ^^^^^ unexpected token
|
||||
|
||||
error: missing comma
|
||||
--> $DIR/recover-enum.rs:7:27
|
||||
error: expected one of `,`, `=`, or `}`, found `Here`
|
||||
--> $DIR/recover-enum.rs:8:9
|
||||
|
|
||||
LL | Stuff { a: usize }
|
||||
| ^ help: missing comma
|
||||
| -
|
||||
| |
|
||||
| expected one of `,`, `=`, or `}`
|
||||
| help: missing `,`
|
||||
LL |
|
||||
LL | Here
|
||||
| ^^^^ unexpected token
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -2,7 +2,10 @@ error: expected one of `,`, `::`, `as`, or `}`, found `.`
|
||||
--> $DIR/similar-tokens.rs:7:10
|
||||
|
|
||||
LL | use x::{A. B};
|
||||
| ^ expected one of `,`, `::`, `as`, or `}`
|
||||
| ^
|
||||
| |
|
||||
| expected one of `,`, `::`, `as`, or `}`
|
||||
| help: missing `,`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,9 @@ error: expected one of `)` or `,`, found `(`
|
||||
--> $DIR/test.rs:4:26
|
||||
|
|
||||
LL | struct S2(pub((foo)) ());
|
||||
| ^ expected one of `)` or `,`
|
||||
| -^ expected one of `)` or `,`
|
||||
| |
|
||||
| help: missing `,`
|
||||
|
||||
error[E0412]: cannot find type `foo` in this scope
|
||||
--> $DIR/test.rs:4:20
|
||||
|
@ -2,7 +2,9 @@ error: expected one of `)` or `,`, found `(`
|
||||
--> $DIR/test2.rs:5:26
|
||||
|
|
||||
LL | struct S3(pub $t ());
|
||||
| ^ expected one of `)` or `,`
|
||||
| -^ expected one of `)` or `,`
|
||||
| |
|
||||
| help: missing `,`
|
||||
...
|
||||
LL | define_struct! { (foo) }
|
||||
| ------------------------ in this macro invocation
|
||||
|
@ -2,7 +2,9 @@ error: expected one of `)` or `,`, found `(`
|
||||
--> $DIR/test3.rs:5:27
|
||||
|
|
||||
LL | struct S3(pub($t) ());
|
||||
| ^ expected one of `)` or `,`
|
||||
| -^ expected one of `)` or `,`
|
||||
| |
|
||||
| help: missing `,`
|
||||
...
|
||||
LL | define_struct! { foo }
|
||||
| ---------------------- in this macro invocation
|
||||
|
Loading…
Reference in New Issue
Block a user