Skip to content

Commit fc8834f

Browse files
committed
Allow struct and enum to contain inner attrs
1 parent 2355b34 commit fc8834f

File tree

1 file changed

+41
-19
lines changed
  • compiler/rustc_parse/src/parser

1 file changed

+41
-19
lines changed

compiler/rustc_parse/src/parser/item.rs

+41-19
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::diagnostics::{dummy_arg, ConsumeClosingDelim, Error};
22
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
3-
use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, TrailingToken};
3+
use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, SeqSep, TrailingToken};
44

55
use rustc_ast::ast::*;
66
use rustc_ast::ptr::P;
@@ -272,14 +272,14 @@ impl<'a> Parser<'a> {
272272
self.parse_type_alias(def())?
273273
} else if self.eat_keyword(kw::Enum) {
274274
// ENUM ITEM
275-
self.parse_item_enum()?
275+
self.parse_item_enum(attrs)?
276276
} else if self.eat_keyword(kw::Struct) {
277277
// STRUCT ITEM
278-
self.parse_item_struct()?
278+
self.parse_item_struct(attrs)?
279279
} else if self.is_kw_followed_by_ident(kw::Union) {
280280
// UNION ITEM
281281
self.bump(); // `union`
282-
self.parse_item_union()?
282+
self.parse_item_union(attrs)?
283283
} else if self.eat_keyword(kw::Macro) {
284284
// MACROS 2.0 ITEM
285285
self.parse_item_decl_macro(lo)?
@@ -1190,13 +1190,20 @@ impl<'a> Parser<'a> {
11901190
}
11911191

11921192
/// Parses an enum declaration.
1193-
fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
1193+
fn parse_item_enum(&mut self, attrs: &mut Vec<Attribute>) -> PResult<'a, ItemInfo> {
11941194
let id = self.parse_ident()?;
11951195
let mut generics = self.parse_generics()?;
11961196
generics.where_clause = self.parse_where_clause()?;
11971197

1198-
let (variants, _) =
1199-
self.parse_delim_comma_seq(token::Brace, |p| p.parse_enum_variant()).map_err(|e| {
1198+
self.expect(&token::OpenDelim(token::Brace))?;
1199+
attrs.append(&mut self.parse_inner_attributes()?);
1200+
let (variants, _) = self
1201+
.parse_seq_to_end(
1202+
&token::CloseDelim(token::Brace),
1203+
SeqSep::trailing_allowed(token::Comma),
1204+
|p| p.parse_enum_variant(),
1205+
)
1206+
.map_err(|e| {
12001207
self.recover_stmt();
12011208
e
12021209
})?;
@@ -1210,7 +1217,7 @@ impl<'a> Parser<'a> {
12101217
self.collect_tokens_trailing_token(
12111218
variant_attrs,
12121219
ForceCollect::No,
1213-
|this, variant_attrs| {
1220+
|this, mut variant_attrs| {
12141221
let vlo = this.token.span;
12151222

12161223
let vis = this.parse_visibility(FollowedByType::No)?;
@@ -1221,7 +1228,8 @@ impl<'a> Parser<'a> {
12211228

12221229
let struct_def = if this.check(&token::OpenDelim(token::Brace)) {
12231230
// Parse a struct variant.
1224-
let (fields, recovered) = this.parse_record_struct_body("struct", false)?;
1231+
let (fields, recovered) =
1232+
this.parse_record_struct_body("struct", false, &mut variant_attrs)?;
12251233
VariantData::Struct(fields, recovered)
12261234
} else if this.check(&token::OpenDelim(token::Paren)) {
12271235
VariantData::Tuple(this.parse_tuple_struct_body()?, DUMMY_NODE_ID)
@@ -1249,7 +1257,7 @@ impl<'a> Parser<'a> {
12491257
}
12501258

12511259
/// Parses `struct Foo { ... }`.
1252-
fn parse_item_struct(&mut self) -> PResult<'a, ItemInfo> {
1260+
fn parse_item_struct(&mut self, attrs: &mut Vec<Attribute>) -> PResult<'a, ItemInfo> {
12531261
let class_name = self.parse_ident()?;
12541262

12551263
let mut generics = self.parse_generics()?;
@@ -1275,17 +1283,23 @@ impl<'a> Parser<'a> {
12751283
VariantData::Unit(DUMMY_NODE_ID)
12761284
} else {
12771285
// If we see: `struct Foo<T> where T: Copy { ... }`
1278-
let (fields, recovered) =
1279-
self.parse_record_struct_body("struct", generics.where_clause.has_where_token)?;
1286+
let (fields, recovered) = self.parse_record_struct_body(
1287+
"struct",
1288+
generics.where_clause.has_where_token,
1289+
attrs,
1290+
)?;
12801291
VariantData::Struct(fields, recovered)
12811292
}
12821293
// No `where` so: `struct Foo<T>;`
12831294
} else if self.eat(&token::Semi) {
12841295
VariantData::Unit(DUMMY_NODE_ID)
12851296
// Record-style struct definition
12861297
} else if self.token == token::OpenDelim(token::Brace) {
1287-
let (fields, recovered) =
1288-
self.parse_record_struct_body("struct", generics.where_clause.has_where_token)?;
1298+
let (fields, recovered) = self.parse_record_struct_body(
1299+
"struct",
1300+
generics.where_clause.has_where_token,
1301+
attrs,
1302+
)?;
12891303
VariantData::Struct(fields, recovered)
12901304
// Tuple-style struct definition with optional where-clause.
12911305
} else if self.token == token::OpenDelim(token::Paren) {
@@ -1308,19 +1322,25 @@ impl<'a> Parser<'a> {
13081322
}
13091323

13101324
/// Parses `union Foo { ... }`.
1311-
fn parse_item_union(&mut self) -> PResult<'a, ItemInfo> {
1325+
fn parse_item_union(&mut self, attrs: &mut Vec<Attribute>) -> PResult<'a, ItemInfo> {
13121326
let class_name = self.parse_ident()?;
13131327

13141328
let mut generics = self.parse_generics()?;
13151329

13161330
let vdata = if self.token.is_keyword(kw::Where) {
13171331
generics.where_clause = self.parse_where_clause()?;
1318-
let (fields, recovered) =
1319-
self.parse_record_struct_body("union", generics.where_clause.has_where_token)?;
1332+
let (fields, recovered) = self.parse_record_struct_body(
1333+
"union",
1334+
generics.where_clause.has_where_token,
1335+
attrs,
1336+
)?;
13201337
VariantData::Struct(fields, recovered)
13211338
} else if self.token == token::OpenDelim(token::Brace) {
1322-
let (fields, recovered) =
1323-
self.parse_record_struct_body("union", generics.where_clause.has_where_token)?;
1339+
let (fields, recovered) = self.parse_record_struct_body(
1340+
"union",
1341+
generics.where_clause.has_where_token,
1342+
attrs,
1343+
)?;
13241344
VariantData::Struct(fields, recovered)
13251345
} else {
13261346
let token_str = super::token_descr(&self.token);
@@ -1337,10 +1357,12 @@ impl<'a> Parser<'a> {
13371357
&mut self,
13381358
adt_ty: &str,
13391359
parsed_where: bool,
1360+
attrs: &mut Vec<Attribute>,
13401361
) -> PResult<'a, (Vec<FieldDef>, /* recovered */ bool)> {
13411362
let mut fields = Vec::new();
13421363
let mut recovered = false;
13431364
if self.eat(&token::OpenDelim(token::Brace)) {
1365+
attrs.append(&mut self.parse_inner_attributes()?);
13441366
while self.token != token::CloseDelim(token::Brace) {
13451367
let field = self.parse_field_def(adt_ty).map_err(|e| {
13461368
self.consume_block(token::Brace, ConsumeClosingDelim::No);

0 commit comments

Comments
 (0)