@@ -47,6 +47,7 @@ macro_rules! ast_fragments {
47
47
) => {
48
48
/// A fragment of AST that can be produced by a single macro expansion.
49
49
/// Can also serve as an input and intermediate result for macro expansion operations.
50
+ #[ derive( Debug ) ]
50
51
pub enum AstFragment {
51
52
OptExpr ( Option <P <ast:: Expr >>) ,
52
53
$( $Kind( $AstTy) , ) *
@@ -88,7 +89,7 @@ macro_rules! ast_fragments {
88
89
macro _repeating( $flat_map_ast_elt) { }
89
90
placeholder( AstFragmentKind :: $Kind, * id, None ) . $make_ast( )
90
91
} ) ) , ) ?) *
91
- _ => panic!( "unexpected AST fragment kind" )
92
+ _ => panic!( "unexpected AST fragment kind: {:?}" , self )
92
93
}
93
94
}
94
95
@@ -483,12 +484,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
483
484
InvocationRes :: DeriveContainer ( _exts) => {
484
485
// FIXME: Consider using the derive resolutions (`_exts`) immediately,
485
486
// instead of enqueuing the derives to be resolved again later.
486
- let ( derives, item) = match invoc. kind {
487
+ let ( mut derives, item) = match invoc. kind {
487
488
InvocationKind :: DeriveContainer { derives, item } => ( derives, item) ,
488
489
_ => unreachable ! ( ) ,
489
490
} ;
490
491
if !item. derive_allowed ( ) {
491
- self . error_derive_forbidden_on_non_adt ( & derives, & item) ;
492
+ self . error_derive_forbidden_on_non_adt ( & mut derives, & item) ;
492
493
}
493
494
494
495
let mut item = self . fully_configure ( item) ;
@@ -539,7 +540,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
539
540
fragment_with_placeholders
540
541
}
541
542
542
- fn error_derive_forbidden_on_non_adt ( & self , derives : & [ Path ] , item : & Annotatable ) {
543
+ fn error_derive_forbidden_on_non_adt ( & self , derives : & mut Vec < Path > , item : & Annotatable ) {
543
544
let attr = self . cx . sess . find_by_name ( item. attrs ( ) , sym:: derive) ;
544
545
let span = attr. map_or ( item. span ( ) , |attr| attr. span ) ;
545
546
let mut err = struct_span_err ! (
@@ -560,6 +561,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
560
561
) ;
561
562
}
562
563
err. emit ( ) ;
564
+ * derives = Vec :: new ( ) ;
563
565
}
564
566
565
567
fn resolve_imports ( & mut self ) {
@@ -1097,22 +1099,6 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
1097
1099
( attr, traits, after_derive)
1098
1100
}
1099
1101
1100
- /// Alternative to `classify_item()` that ignores `#[derive]` so invocations fallthrough
1101
- /// to the unused-attributes lint (making it an error on statements and expressions
1102
- /// is a breaking change)
1103
- fn classify_nonitem (
1104
- & mut self ,
1105
- nonitem : & mut impl HasAttrs ,
1106
- ) -> ( Option < ast:: Attribute > , /* after_derive */ bool ) {
1107
- let ( mut attr, mut after_derive) = ( None , false ) ;
1108
-
1109
- nonitem. visit_attrs ( |mut attrs| {
1110
- attr = self . find_attr_invoc ( & mut attrs, & mut after_derive) ;
1111
- } ) ;
1112
-
1113
- ( attr, after_derive)
1114
- }
1115
-
1116
1102
fn configure < T : HasAttrs > ( & mut self , node : T ) -> Option < T > {
1117
1103
self . cfg . configure ( node)
1118
1104
}
@@ -1154,19 +1140,20 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1154
1140
visit_clobber ( expr. deref_mut ( ) , |mut expr| {
1155
1141
self . cfg . configure_expr_kind ( & mut expr. kind ) ;
1156
1142
1157
- // ignore derives so they remain unused
1158
- let ( attr, after_derive) = self . classify_nonitem ( & mut expr) ;
1143
+ let ( attr, derives, after_derive) = self . classify_item ( & mut expr) ;
1159
1144
1160
- if let Some ( ref attr_value) = attr {
1161
- // Collect the invoc regardless of whether or not attributes are permitted here
1162
- // expansion will eat the attribute so it won't error later.
1163
- self . cfg . maybe_emit_expr_attr_err ( attr_value) ;
1145
+ if attr. is_some ( ) || !derives. is_empty ( ) {
1146
+ if let Some ( attr) = & attr {
1147
+ // Collect the invoc regardless of whether or not attributes are permitted here
1148
+ // expansion will eat the attribute so it won't error later.
1149
+ self . cfg . maybe_emit_expr_attr_err ( & attr) ;
1150
+ }
1164
1151
1165
1152
// AstFragmentKind::Expr requires the macro to emit an expression.
1166
1153
return self
1167
1154
. collect_attr (
1168
1155
attr,
1169
- vec ! [ ] ,
1156
+ derives ,
1170
1157
Annotatable :: Expr ( P ( expr) ) ,
1171
1158
AstFragmentKind :: Expr ,
1172
1159
after_derive,
@@ -1304,16 +1291,17 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1304
1291
expr. filter_map ( |mut expr| {
1305
1292
self . cfg . configure_expr_kind ( & mut expr. kind ) ;
1306
1293
1307
- // Ignore derives so they remain unused.
1308
- let ( attr, after_derive) = self . classify_nonitem ( & mut expr) ;
1294
+ let ( attr, derives, after_derive) = self . classify_item ( & mut expr) ;
1309
1295
1310
- if let Some ( ref attr_value) = attr {
1311
- self . cfg . maybe_emit_expr_attr_err ( attr_value) ;
1296
+ if attr. is_some ( ) || !derives. is_empty ( ) {
1297
+ if let Some ( attr) = & attr {
1298
+ self . cfg . maybe_emit_expr_attr_err ( attr) ;
1299
+ }
1312
1300
1313
1301
return self
1314
1302
. collect_attr (
1315
1303
attr,
1316
- vec ! [ ] ,
1304
+ derives ,
1317
1305
Annotatable :: Expr ( P ( expr) ) ,
1318
1306
AstFragmentKind :: OptExpr ,
1319
1307
after_derive,
@@ -1361,9 +1349,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1361
1349
( None , vec ! [ ] , false )
1362
1350
} else {
1363
1351
// ignore derives on non-item statements so it falls through
1364
- // to the unused-attributes lint
1365
- let ( attr, after_derive) = self . classify_nonitem ( & mut stmt) ;
1366
- ( attr, vec ! [ ] , after_derive)
1352
+ self . classify_item ( & mut stmt)
1367
1353
} ;
1368
1354
1369
1355
if attr. is_some ( ) || !derives. is_empty ( ) {
0 commit comments