@@ -1098,6 +1098,41 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
1098
1098
}
1099
1099
}
1100
1100
1101
+ /// Wraps a call to `noop_visit_*` / `noop_flat_map_*`
1102
+ /// This method assigns a `NodeId`, and sets that `NodeId`
1103
+ /// as our current 'lint node id'. If a macro call is found
1104
+ /// inside this AST node, we will use this AST node's `NodeId`
1105
+ /// to emit lints associated with that macro (allowing
1106
+ /// `#[allow]` / `#[deny]` to be applied close to
1107
+ /// the macro invocation).
1108
+ ///
1109
+ /// Do *not* call this for a macro AST node
1110
+ /// (e.g. `ExprKind::MacCall`) - we cannot emit lints
1111
+ /// at these AST nodes, since they are removed and
1112
+ /// replaced with the result of macro expansion.
1113
+ ///
1114
+ /// All other `NodeId`s are assigned by `visit_id`.
1115
+ /// * `self` is the 'self' parameter for the current method,
1116
+ /// * `id` is a mutable reference to the `NodeId` field
1117
+ /// of the current AST node.
1118
+ /// * `closure` is a closure that executes the
1119
+ /// `noop_visit_*` / `noop_flat_map_*` method
1120
+ /// for the current AST node.
1121
+ macro_rules! assign_id {
1122
+ ( $self: ident, $id: expr, $closure: expr) => { {
1123
+ let old_id = $self. cx. current_expansion. lint_node_id;
1124
+ if $self. monotonic {
1125
+ debug_assert_eq!( * $id, ast:: DUMMY_NODE_ID ) ;
1126
+ let new_id = $self. cx. resolver. next_node_id( ) ;
1127
+ * $id = new_id;
1128
+ $self. cx. current_expansion. lint_node_id = new_id;
1129
+ }
1130
+ let ret = ( $closure) ( ) ;
1131
+ $self. cx. current_expansion. lint_node_id = old_id;
1132
+ ret
1133
+ } } ;
1134
+ }
1135
+
1101
1136
impl < ' a , ' b > MutVisitor for InvocationCollector < ' a , ' b > {
1102
1137
fn visit_expr ( & mut self , expr : & mut P < ast:: Expr > ) {
1103
1138
self . cfg . configure_expr ( expr) ;
@@ -1118,7 +1153,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1118
1153
self . check_attributes ( & expr. attrs ) ;
1119
1154
self . collect_bang ( mac, expr. span , AstFragmentKind :: Expr ) . make_expr ( ) . into_inner ( )
1120
1155
} else {
1121
- ensure_sufficient_stack ( || noop_visit_expr ( & mut expr, self ) ) ;
1156
+ assign_id ! ( self , & mut expr. id, || {
1157
+ ensure_sufficient_stack( || noop_visit_expr( & mut expr, self ) ) ;
1158
+ } ) ;
1122
1159
expr
1123
1160
}
1124
1161
} ) ;
@@ -1133,7 +1170,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1133
1170
. make_arms ( ) ;
1134
1171
}
1135
1172
1136
- noop_flat_map_arm ( arm, self )
1173
+ assign_id ! ( self , & mut arm . id , || noop_flat_map_arm( arm, self ) )
1137
1174
}
1138
1175
1139
1176
fn flat_map_expr_field ( & mut self , field : ast:: ExprField ) -> SmallVec < [ ast:: ExprField ; 1 ] > {
@@ -1145,7 +1182,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1145
1182
. make_expr_fields ( ) ;
1146
1183
}
1147
1184
1148
- noop_flat_map_expr_field ( field, self )
1185
+ assign_id ! ( self , & mut field . id , || noop_flat_map_expr_field( field, self ) )
1149
1186
}
1150
1187
1151
1188
fn flat_map_pat_field ( & mut self , fp : ast:: PatField ) -> SmallVec < [ ast:: PatField ; 1 ] > {
@@ -1157,7 +1194,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1157
1194
. make_pat_fields ( ) ;
1158
1195
}
1159
1196
1160
- noop_flat_map_pat_field ( fp, self )
1197
+ assign_id ! ( self , & mut fp . id , || noop_flat_map_pat_field( fp, self ) )
1161
1198
}
1162
1199
1163
1200
fn flat_map_param ( & mut self , p : ast:: Param ) -> SmallVec < [ ast:: Param ; 1 ] > {
@@ -1169,7 +1206,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1169
1206
. make_params ( ) ;
1170
1207
}
1171
1208
1172
- noop_flat_map_param ( p, self )
1209
+ assign_id ! ( self , & mut p . id , || noop_flat_map_param( p, self ) )
1173
1210
}
1174
1211
1175
1212
fn flat_map_field_def ( & mut self , sf : ast:: FieldDef ) -> SmallVec < [ ast:: FieldDef ; 1 ] > {
@@ -1181,7 +1218,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1181
1218
. make_field_defs ( ) ;
1182
1219
}
1183
1220
1184
- noop_flat_map_field_def ( sf, self )
1221
+ assign_id ! ( self , & mut sf . id , || noop_flat_map_field_def( sf, self ) )
1185
1222
}
1186
1223
1187
1224
fn flat_map_variant ( & mut self , variant : ast:: Variant ) -> SmallVec < [ ast:: Variant ; 1 ] > {
@@ -1193,7 +1230,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1193
1230
. make_variants ( ) ;
1194
1231
}
1195
1232
1196
- noop_flat_map_variant ( variant, self )
1233
+ assign_id ! ( self , & mut variant . id , || noop_flat_map_variant( variant, self ) )
1197
1234
}
1198
1235
1199
1236
fn filter_map_expr ( & mut self , expr : P < ast:: Expr > ) -> Option < P < ast:: Expr > > {
@@ -1214,9 +1251,11 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1214
1251
. make_opt_expr ( )
1215
1252
. map ( |expr| expr. into_inner ( ) )
1216
1253
} else {
1217
- Some ( {
1218
- noop_visit_expr ( & mut expr, self ) ;
1219
- expr
1254
+ assign_id ! ( self , & mut expr. id, || {
1255
+ Some ( {
1256
+ noop_visit_expr( & mut expr, self ) ;
1257
+ expr
1258
+ } )
1220
1259
} )
1221
1260
}
1222
1261
} )
@@ -1225,7 +1264,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1225
1264
fn visit_pat ( & mut self , pat : & mut P < ast:: Pat > ) {
1226
1265
match pat. kind {
1227
1266
PatKind :: MacCall ( _) => { }
1228
- _ => return noop_visit_pat ( pat, self ) ,
1267
+ _ => {
1268
+ return assign_id ! ( self , & mut pat. id, || noop_visit_pat( pat, self ) ) ;
1269
+ }
1229
1270
}
1230
1271
1231
1272
visit_clobber ( pat, |mut pat| match mem:: replace ( & mut pat. kind , PatKind :: Wild ) {
@@ -1278,7 +1319,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1278
1319
& mut self . cx . current_expansion . dir_ownership ,
1279
1320
DirOwnership :: UnownedViaBlock ,
1280
1321
) ;
1281
- noop_visit_block ( block, self ) ;
1322
+ assign_id ! ( self , & mut block . id , || noop_visit_block( block, self ) ) ;
1282
1323
self . cx . current_expansion . dir_ownership = orig_dir_ownership;
1283
1324
}
1284
1325
@@ -1377,7 +1418,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1377
1418
let orig_dir_ownership =
1378
1419
mem:: replace ( & mut self . cx . current_expansion . dir_ownership , dir_ownership) ;
1379
1420
1380
- let result = noop_flat_map_item ( item, self ) ;
1421
+ let result = assign_id ! ( self , & mut item . id , || noop_flat_map_item( item, self ) ) ;
1381
1422
1382
1423
// Restore the module info.
1383
1424
self . cx . current_expansion . dir_ownership = orig_dir_ownership;
@@ -1387,7 +1428,12 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1387
1428
}
1388
1429
_ => {
1389
1430
item. attrs = attrs;
1390
- noop_flat_map_item ( item, self )
1431
+ // The crate root is special - don't assign an ID to it.
1432
+ if !( matches ! ( item. kind, ast:: ItemKind :: Mod ( ..) ) && ident == Ident :: invalid ( ) ) {
1433
+ assign_id ! ( self , & mut item. id, || noop_flat_map_item( item, self ) )
1434
+ } else {
1435
+ noop_flat_map_item ( item, self )
1436
+ }
1391
1437
}
1392
1438
}
1393
1439
}
@@ -1411,7 +1457,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1411
1457
_ => unreachable ! ( ) ,
1412
1458
} )
1413
1459
}
1414
- _ => noop_flat_map_assoc_item ( item, self ) ,
1460
+ _ => {
1461
+ assign_id ! ( self , & mut item. id, || noop_flat_map_assoc_item( item, self ) )
1462
+ }
1415
1463
}
1416
1464
}
1417
1465
@@ -1434,14 +1482,16 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1434
1482
_ => unreachable ! ( ) ,
1435
1483
} )
1436
1484
}
1437
- _ => noop_flat_map_assoc_item ( item, self ) ,
1485
+ _ => {
1486
+ assign_id ! ( self , & mut item. id, || noop_flat_map_assoc_item( item, self ) )
1487
+ }
1438
1488
}
1439
1489
}
1440
1490
1441
1491
fn visit_ty ( & mut self , ty : & mut P < ast:: Ty > ) {
1442
1492
match ty. kind {
1443
1493
ast:: TyKind :: MacCall ( _) => { }
1444
- _ => return noop_visit_ty ( ty, self ) ,
1494
+ _ => return assign_id ! ( self , & mut ty . id , || noop_visit_ty( ty, self ) ) ,
1445
1495
} ;
1446
1496
1447
1497
visit_clobber ( ty, |mut ty| match mem:: replace ( & mut ty. kind , ast:: TyKind :: Err ) {
@@ -1478,7 +1528,12 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1478
1528
_ => unreachable ! ( ) ,
1479
1529
} )
1480
1530
}
1481
- _ => noop_flat_map_foreign_item ( foreign_item, self ) ,
1531
+ _ => {
1532
+ assign_id ! ( self , & mut foreign_item. id, || noop_flat_map_foreign_item(
1533
+ foreign_item,
1534
+ self
1535
+ ) )
1536
+ }
1482
1537
}
1483
1538
}
1484
1539
@@ -1498,13 +1553,14 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1498
1553
. make_generic_params ( ) ;
1499
1554
}
1500
1555
1501
- noop_flat_map_generic_param ( param, self )
1556
+ assign_id ! ( self , & mut param . id , || noop_flat_map_generic_param( param, self ) )
1502
1557
}
1503
1558
1504
1559
fn visit_id ( & mut self , id : & mut ast:: NodeId ) {
1505
- if self . monotonic {
1506
- debug_assert_eq ! ( * id, ast:: DUMMY_NODE_ID ) ;
1507
- * id = self . cx . resolver . next_node_id ( )
1560
+ // We may have already assigned a `NodeId`
1561
+ // by calling `assign_id`
1562
+ if self . monotonic && * id == ast:: DUMMY_NODE_ID {
1563
+ * id = self . cx . resolver . next_node_id ( ) ;
1508
1564
}
1509
1565
}
1510
1566
}
0 commit comments