-
Notifications
You must be signed in to change notification settings - Fork 14k
Suggest using an appropriate keyword for struct and enum
#94996
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -273,11 +273,13 @@ impl<'a> Parser<'a> { | |||||
| // TYPE ITEM | ||||||
| self.parse_type_alias(def())? | ||||||
| } else if self.eat_keyword(kw::Enum) { | ||||||
| let start_span = self.prev_token.span; | ||||||
| // ENUM ITEM | ||||||
| self.parse_item_enum()? | ||||||
| self.parse_item_enum(start_span)? | ||||||
| } else if self.eat_keyword(kw::Struct) { | ||||||
| let start_span = self.prev_token.span; | ||||||
| // STRUCT ITEM | ||||||
| self.parse_item_struct()? | ||||||
| self.parse_item_struct(start_span)? | ||||||
| } else if self.is_kw_followed_by_ident(kw::Union) { | ||||||
| // UNION ITEM | ||||||
| self.bump(); // `union` | ||||||
|
|
@@ -1199,13 +1201,14 @@ impl<'a> Parser<'a> { | |||||
| } | ||||||
|
|
||||||
| /// Parses an enum declaration. | ||||||
| fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> { | ||||||
| fn parse_item_enum(&mut self, start_span: Span) -> PResult<'a, ItemInfo> { | ||||||
| let id = self.parse_ident()?; | ||||||
| let mut generics = self.parse_generics()?; | ||||||
| generics.where_clause = self.parse_where_clause()?; | ||||||
|
|
||||||
| let (variants, _) = | ||||||
| self.parse_delim_comma_seq(token::Brace, |p| p.parse_enum_variant()).map_err(|e| { | ||||||
| let (variants, _) = self | ||||||
| .parse_delim_comma_seq(token::Brace, |p| p.parse_enum_variant(start_span)) | ||||||
| .map_err(|e| { | ||||||
| self.recover_stmt(); | ||||||
| e | ||||||
| })?; | ||||||
|
|
@@ -1214,7 +1217,7 @@ impl<'a> Parser<'a> { | |||||
| Ok((id, ItemKind::Enum(enum_definition, generics))) | ||||||
| } | ||||||
|
|
||||||
| fn parse_enum_variant(&mut self) -> PResult<'a, Option<Variant>> { | ||||||
| fn parse_enum_variant(&mut self, start_span: Span) -> PResult<'a, Option<Variant>> { | ||||||
| let variant_attrs = self.parse_outer_attributes()?; | ||||||
| self.collect_tokens_trailing_token( | ||||||
| variant_attrs, | ||||||
|
|
@@ -1226,11 +1229,36 @@ impl<'a> Parser<'a> { | |||||
| if !this.recover_nested_adt_item(kw::Enum)? { | ||||||
| return Ok((None, TrailingToken::None)); | ||||||
| } | ||||||
| let enum_field_start_span = this.token.span; | ||||||
| let ident = this.parse_field_ident("enum", vlo)?; | ||||||
| if this.token.kind == token::Colon && !start_span.in_derive_expansion() { | ||||||
| let snapshot = this.clone(); | ||||||
| this.bump(); | ||||||
| match this.parse_ty() { | ||||||
| Ok(_) => { | ||||||
| let mut err = this.struct_span_err( | ||||||
| enum_field_start_span.to(this.prev_token.span), | ||||||
| "the enum cannot have a struct field declaration", | ||||||
|
||||||
| "the enum cannot have a struct field declaration", | |
| "expected an `enum` variant, found a field", |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, an union could also make sense here, wouldn't it? While it is comparatively much rarer, looking to define an enum like this may very well be thinking of an union in the first place.
| "consider using `struct` instead of `enum`", | |
| "consider defining a `struct` or an `union` instead of an `enum`", |
Not entirely sure how or if span_suggestion can provide multiple alternative replacements, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might very well be that this suggestion is largely superfluous with the improved error message.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're handling structs, we should also handle unions.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| pub struct NotStruct { | ||
| Variant | ||
| } //~ ERROR expected `:`, found `}` | ||
|
|
||
| pub struct NotStruct { | ||
| field String //~ ERROR expected `:`, found `String` | ||
| } | ||
|
|
||
| pub enum NotEnum { | ||
| field: u8 //~ ERROR the enum cannot have a struct field declaration | ||
| } | ||
|
|
||
| fn main() {} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| error: expected `:`, found `}` | ||
| --> $DIR/suggest-using-appropriate-keyword-for-struct-and-enum.rs:3:1 | ||
| | | ||
| LL | Variant | ||
| | - expected `:` | ||
| LL | } | ||
| | ^ unexpected token | ||
| | | ||
| help: consider using `enum` instead of `struct` | ||
| | | ||
| LL | pub enum NotStruct { | ||
| | ~~~~ | ||
|
||
|
|
||
| error: expected `:`, found `String` | ||
| --> $DIR/suggest-using-appropriate-keyword-for-struct-and-enum.rs:6:11 | ||
| | | ||
| LL | field String | ||
| | ^^^^^^ expected `:` | ||
|
|
||
| error: the enum cannot have a struct field declaration | ||
| --> $DIR/suggest-using-appropriate-keyword-for-struct-and-enum.rs:10:5 | ||
| | | ||
| LL | field: u8 | ||
| | ^^^^^^^^^ | ||
| | | ||
| help: consider using `struct` instead of `enum` | ||
| | | ||
| LL | pub struct NotEnum { | ||
| | ~~~~~~ | ||
|
|
||
| error: aborting due to 3 previous errors | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
start_spanseems a little misnomer here, given that the span begins at theenumorstructkeyword, rather than covering the entire item (i.e. including the qualifiers such aspub). Maybe something likekeyword_spanwould work better?