@@ -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