-
Notifications
You must be signed in to change notification settings - Fork 13.8k
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 struct
s, we should also handle union
s.
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_span
seems a little misnomer here, given that the span begins at theenum
orstruct
keyword, rather than covering the entire item (i.e. including the qualifiers such aspub
). Maybe something likekeyword_span
would work better?