Skip to content

Commit ec54720

Browse files
committed
expand: Cleanup attribute collection in invocation collector
1 parent dfb690e commit ec54720

File tree

1 file changed

+39
-141
lines changed

1 file changed

+39
-141
lines changed

compiler/rustc_expand/src/expand.rs

+39-141
Original file line numberDiff line numberDiff line change
@@ -1016,11 +1016,9 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
10161016

10171017
fn collect_attr(
10181018
&mut self,
1019-
attr: Option<ast::Attribute>,
1020-
derives: Vec<Path>,
1019+
(attr, derives, after_derive): (Option<ast::Attribute>, Vec<Path>, bool),
10211020
item: Annotatable,
10221021
kind: AstFragmentKind,
1023-
after_derive: bool,
10241022
) -> AstFragment {
10251023
self.collect(
10261024
kind,
@@ -1048,34 +1046,34 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
10481046
}
10491047

10501048
/// If `item` is an attr invocation, remove and return the macro attribute and derive traits.
1051-
fn classify_item(
1049+
fn take_first_attr(
10521050
&mut self,
10531051
item: &mut impl HasAttrs,
1054-
) -> (Option<ast::Attribute>, Vec<Path>, /* after_derive */ bool) {
1052+
) -> Option<(Option<ast::Attribute>, Vec<Path>, /* after_derive */ bool)> {
10551053
let (mut attr, mut traits, mut after_derive) = (None, Vec::new(), false);
10561054

10571055
item.visit_attrs(|mut attrs| {
10581056
attr = self.find_attr_invoc(&mut attrs, &mut after_derive);
10591057
traits = collect_derives(&mut self.cx, &mut attrs);
10601058
});
10611059

1062-
(attr, traits, after_derive)
1060+
if attr.is_some() || !traits.is_empty() { Some((attr, traits, after_derive)) } else { None }
10631061
}
10641062

1065-
/// Alternative to `classify_item()` that ignores `#[derive]` so invocations fallthrough
1063+
/// Alternative to `take_first_attr()` that ignores `#[derive]` so invocations fallthrough
10661064
/// to the unused-attributes lint (making it an error on statements and expressions
10671065
/// is a breaking change)
1068-
fn classify_nonitem(
1066+
fn take_first_attr_no_derive(
10691067
&mut self,
10701068
nonitem: &mut impl HasAttrs,
1071-
) -> (Option<ast::Attribute>, /* after_derive */ bool) {
1069+
) -> Option<(Option<ast::Attribute>, Vec<Path>, /* after_derive */ bool)> {
10721070
let (mut attr, mut after_derive) = (None, false);
10731071

10741072
nonitem.visit_attrs(|mut attrs| {
10751073
attr = self.find_attr_invoc(&mut attrs, &mut after_derive);
10761074
});
10771075

1078-
(attr, after_derive)
1076+
attr.map(|attr| (Some(attr), Vec::new(), after_derive))
10791077
}
10801078

10811079
fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
@@ -1119,23 +1117,14 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
11191117
visit_clobber(expr.deref_mut(), |mut expr| {
11201118
self.cfg.configure_expr_kind(&mut expr.kind);
11211119

1122-
// ignore derives so they remain unused
1123-
let (attr, after_derive) = self.classify_nonitem(&mut expr);
1124-
1125-
if let Some(ref attr_value) = attr {
1120+
if let Some(attr) = self.take_first_attr_no_derive(&mut expr) {
11261121
// Collect the invoc regardless of whether or not attributes are permitted here
11271122
// expansion will eat the attribute so it won't error later.
1128-
self.cfg.maybe_emit_expr_attr_err(attr_value);
1123+
attr.0.as_ref().map(|attr| self.cfg.maybe_emit_expr_attr_err(attr));
11291124

11301125
// AstFragmentKind::Expr requires the macro to emit an expression.
11311126
return self
1132-
.collect_attr(
1133-
attr,
1134-
vec![],
1135-
Annotatable::Expr(P(expr)),
1136-
AstFragmentKind::Expr,
1137-
after_derive,
1138-
)
1127+
.collect_attr(attr, Annotatable::Expr(P(expr)), AstFragmentKind::Expr)
11391128
.make_expr()
11401129
.into_inner();
11411130
}
@@ -1153,16 +1142,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
11531142
fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> {
11541143
let mut arm = configure!(self, arm);
11551144

1156-
let (attr, traits, after_derive) = self.classify_item(&mut arm);
1157-
if attr.is_some() || !traits.is_empty() {
1145+
if let Some(attr) = self.take_first_attr(&mut arm) {
11581146
return self
1159-
.collect_attr(
1160-
attr,
1161-
traits,
1162-
Annotatable::Arm(arm),
1163-
AstFragmentKind::Arms,
1164-
after_derive,
1165-
)
1147+
.collect_attr(attr, Annotatable::Arm(arm), AstFragmentKind::Arms)
11661148
.make_arms();
11671149
}
11681150

@@ -1172,16 +1154,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
11721154
fn flat_map_field(&mut self, field: ast::Field) -> SmallVec<[ast::Field; 1]> {
11731155
let mut field = configure!(self, field);
11741156

1175-
let (attr, traits, after_derive) = self.classify_item(&mut field);
1176-
if attr.is_some() || !traits.is_empty() {
1157+
if let Some(attr) = self.take_first_attr(&mut field) {
11771158
return self
1178-
.collect_attr(
1179-
attr,
1180-
traits,
1181-
Annotatable::Field(field),
1182-
AstFragmentKind::Fields,
1183-
after_derive,
1184-
)
1159+
.collect_attr(attr, Annotatable::Field(field), AstFragmentKind::Fields)
11851160
.make_fields();
11861161
}
11871162

@@ -1191,16 +1166,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
11911166
fn flat_map_field_pattern(&mut self, fp: ast::FieldPat) -> SmallVec<[ast::FieldPat; 1]> {
11921167
let mut fp = configure!(self, fp);
11931168

1194-
let (attr, traits, after_derive) = self.classify_item(&mut fp);
1195-
if attr.is_some() || !traits.is_empty() {
1169+
if let Some(attr) = self.take_first_attr(&mut fp) {
11961170
return self
1197-
.collect_attr(
1198-
attr,
1199-
traits,
1200-
Annotatable::FieldPat(fp),
1201-
AstFragmentKind::FieldPats,
1202-
after_derive,
1203-
)
1171+
.collect_attr(attr, Annotatable::FieldPat(fp), AstFragmentKind::FieldPats)
12041172
.make_field_patterns();
12051173
}
12061174

@@ -1210,16 +1178,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
12101178
fn flat_map_param(&mut self, p: ast::Param) -> SmallVec<[ast::Param; 1]> {
12111179
let mut p = configure!(self, p);
12121180

1213-
let (attr, traits, after_derive) = self.classify_item(&mut p);
1214-
if attr.is_some() || !traits.is_empty() {
1181+
if let Some(attr) = self.take_first_attr(&mut p) {
12151182
return self
1216-
.collect_attr(
1217-
attr,
1218-
traits,
1219-
Annotatable::Param(p),
1220-
AstFragmentKind::Params,
1221-
after_derive,
1222-
)
1183+
.collect_attr(attr, Annotatable::Param(p), AstFragmentKind::Params)
12231184
.make_params();
12241185
}
12251186

@@ -1229,16 +1190,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
12291190
fn flat_map_struct_field(&mut self, sf: ast::StructField) -> SmallVec<[ast::StructField; 1]> {
12301191
let mut sf = configure!(self, sf);
12311192

1232-
let (attr, traits, after_derive) = self.classify_item(&mut sf);
1233-
if attr.is_some() || !traits.is_empty() {
1193+
if let Some(attr) = self.take_first_attr(&mut sf) {
12341194
return self
1235-
.collect_attr(
1236-
attr,
1237-
traits,
1238-
Annotatable::StructField(sf),
1239-
AstFragmentKind::StructFields,
1240-
after_derive,
1241-
)
1195+
.collect_attr(attr, Annotatable::StructField(sf), AstFragmentKind::StructFields)
12421196
.make_struct_fields();
12431197
}
12441198

@@ -1248,16 +1202,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
12481202
fn flat_map_variant(&mut self, variant: ast::Variant) -> SmallVec<[ast::Variant; 1]> {
12491203
let mut variant = configure!(self, variant);
12501204

1251-
let (attr, traits, after_derive) = self.classify_item(&mut variant);
1252-
if attr.is_some() || !traits.is_empty() {
1205+
if let Some(attr) = self.take_first_attr(&mut variant) {
12531206
return self
1254-
.collect_attr(
1255-
attr,
1256-
traits,
1257-
Annotatable::Variant(variant),
1258-
AstFragmentKind::Variants,
1259-
after_derive,
1260-
)
1207+
.collect_attr(attr, Annotatable::Variant(variant), AstFragmentKind::Variants)
12611208
.make_variants();
12621209
}
12631210

@@ -1269,20 +1216,11 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
12691216
expr.filter_map(|mut expr| {
12701217
self.cfg.configure_expr_kind(&mut expr.kind);
12711218

1272-
// Ignore derives so they remain unused.
1273-
let (attr, after_derive) = self.classify_nonitem(&mut expr);
1274-
1275-
if let Some(ref attr_value) = attr {
1276-
self.cfg.maybe_emit_expr_attr_err(attr_value);
1219+
if let Some(attr) = self.take_first_attr_no_derive(&mut expr) {
1220+
attr.0.as_ref().map(|attr| self.cfg.maybe_emit_expr_attr_err(attr));
12771221

12781222
return self
1279-
.collect_attr(
1280-
attr,
1281-
vec![],
1282-
Annotatable::Expr(P(expr)),
1283-
AstFragmentKind::OptExpr,
1284-
after_derive,
1285-
)
1223+
.collect_attr(attr, Annotatable::Expr(P(expr)), AstFragmentKind::OptExpr)
12861224
.make_opt_expr()
12871225
.map(|expr| expr.into_inner());
12881226
}
@@ -1321,25 +1259,13 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
13211259

13221260
// we'll expand attributes on expressions separately
13231261
if !stmt.is_expr() {
1324-
let (attr, derives, after_derive) = if stmt.is_item() {
1325-
// FIXME: Handle custom attributes on statements (#15701)
1326-
(None, vec![], false)
1327-
} else {
1328-
// ignore derives on non-item statements so it falls through
1329-
// to the unused-attributes lint
1330-
let (attr, after_derive) = self.classify_nonitem(&mut stmt);
1331-
(attr, vec![], after_derive)
1332-
};
1262+
// FIXME: Handle custom attributes on statements (#15701).
1263+
let attr =
1264+
if stmt.is_item() { None } else { self.take_first_attr_no_derive(&mut stmt) };
13331265

1334-
if attr.is_some() || !derives.is_empty() {
1266+
if let Some(attr) = attr {
13351267
return self
1336-
.collect_attr(
1337-
attr,
1338-
derives,
1339-
Annotatable::Stmt(P(stmt)),
1340-
AstFragmentKind::Stmts,
1341-
after_derive,
1342-
)
1268+
.collect_attr(attr, Annotatable::Stmt(P(stmt)), AstFragmentKind::Stmts)
13431269
.make_stmts();
13441270
}
13451271
}
@@ -1379,16 +1305,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
13791305
fn flat_map_item(&mut self, item: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
13801306
let mut item = configure!(self, item);
13811307

1382-
let (attr, traits, after_derive) = self.classify_item(&mut item);
1383-
if attr.is_some() || !traits.is_empty() {
1308+
if let Some(attr) = self.take_first_attr(&mut item) {
13841309
return self
1385-
.collect_attr(
1386-
attr,
1387-
traits,
1388-
Annotatable::Item(item),
1389-
AstFragmentKind::Items,
1390-
after_derive,
1391-
)
1310+
.collect_attr(attr, Annotatable::Item(item), AstFragmentKind::Items)
13921311
.make_items();
13931312
}
13941313

@@ -1482,16 +1401,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
14821401
fn flat_map_trait_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
14831402
let mut item = configure!(self, item);
14841403

1485-
let (attr, traits, after_derive) = self.classify_item(&mut item);
1486-
if attr.is_some() || !traits.is_empty() {
1404+
if let Some(attr) = self.take_first_attr(&mut item) {
14871405
return self
1488-
.collect_attr(
1489-
attr,
1490-
traits,
1491-
Annotatable::TraitItem(item),
1492-
AstFragmentKind::TraitItems,
1493-
after_derive,
1494-
)
1406+
.collect_attr(attr, Annotatable::TraitItem(item), AstFragmentKind::TraitItems)
14951407
.make_trait_items();
14961408
}
14971409

@@ -1512,16 +1424,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
15121424
fn flat_map_impl_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
15131425
let mut item = configure!(self, item);
15141426

1515-
let (attr, traits, after_derive) = self.classify_item(&mut item);
1516-
if attr.is_some() || !traits.is_empty() {
1427+
if let Some(attr) = self.take_first_attr(&mut item) {
15171428
return self
1518-
.collect_attr(
1519-
attr,
1520-
traits,
1521-
Annotatable::ImplItem(item),
1522-
AstFragmentKind::ImplItems,
1523-
after_derive,
1524-
)
1429+
.collect_attr(attr, Annotatable::ImplItem(item), AstFragmentKind::ImplItems)
15251430
.make_impl_items();
15261431
}
15271432

@@ -1562,16 +1467,12 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
15621467
&mut self,
15631468
mut foreign_item: P<ast::ForeignItem>,
15641469
) -> SmallVec<[P<ast::ForeignItem>; 1]> {
1565-
let (attr, traits, after_derive) = self.classify_item(&mut foreign_item);
1566-
1567-
if attr.is_some() || !traits.is_empty() {
1470+
if let Some(attr) = self.take_first_attr(&mut foreign_item) {
15681471
return self
15691472
.collect_attr(
15701473
attr,
1571-
traits,
15721474
Annotatable::ForeignItem(foreign_item),
15731475
AstFragmentKind::ForeignItems,
1574-
after_derive,
15751476
)
15761477
.make_foreign_items();
15771478
}
@@ -1606,15 +1507,12 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
16061507
) -> SmallVec<[ast::GenericParam; 1]> {
16071508
let mut param = configure!(self, param);
16081509

1609-
let (attr, traits, after_derive) = self.classify_item(&mut param);
1610-
if attr.is_some() || !traits.is_empty() {
1510+
if let Some(attr) = self.take_first_attr(&mut param) {
16111511
return self
16121512
.collect_attr(
16131513
attr,
1614-
traits,
16151514
Annotatable::GenericParam(param),
16161515
AstFragmentKind::GenericParams,
1617-
after_derive,
16181516
)
16191517
.make_generic_params();
16201518
}

0 commit comments

Comments
 (0)