@@ -1098,6 +1098,41 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
10981098 }
10991099}
11001100
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+
11011136impl < ' a , ' b > MutVisitor for InvocationCollector < ' a , ' b > {
11021137 fn visit_expr ( & mut self , expr : & mut P < ast:: Expr > ) {
11031138 self . cfg . configure_expr ( expr) ;
@@ -1118,7 +1153,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
11181153 self . check_attributes ( & expr. attrs ) ;
11191154 self . collect_bang ( mac, expr. span , AstFragmentKind :: Expr ) . make_expr ( ) . into_inner ( )
11201155 } 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+ } ) ;
11221159 expr
11231160 }
11241161 } ) ;
@@ -1133,7 +1170,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
11331170 . make_arms ( ) ;
11341171 }
11351172
1136- noop_flat_map_arm ( arm, self )
1173+ assign_id ! ( self , & mut arm . id , || noop_flat_map_arm( arm, self ) )
11371174 }
11381175
11391176 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> {
11451182 . make_expr_fields ( ) ;
11461183 }
11471184
1148- noop_flat_map_expr_field ( field, self )
1185+ assign_id ! ( self , & mut field . id , || noop_flat_map_expr_field( field, self ) )
11491186 }
11501187
11511188 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> {
11571194 . make_pat_fields ( ) ;
11581195 }
11591196
1160- noop_flat_map_pat_field ( fp, self )
1197+ assign_id ! ( self , & mut fp . id , || noop_flat_map_pat_field( fp, self ) )
11611198 }
11621199
11631200 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> {
11691206 . make_params ( ) ;
11701207 }
11711208
1172- noop_flat_map_param ( p, self )
1209+ assign_id ! ( self , & mut p . id , || noop_flat_map_param( p, self ) )
11731210 }
11741211
11751212 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> {
11811218 . make_field_defs ( ) ;
11821219 }
11831220
1184- noop_flat_map_field_def ( sf, self )
1221+ assign_id ! ( self , & mut sf . id , || noop_flat_map_field_def( sf, self ) )
11851222 }
11861223
11871224 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> {
11931230 . make_variants ( ) ;
11941231 }
11951232
1196- noop_flat_map_variant ( variant, self )
1233+ assign_id ! ( self , & mut variant . id , || noop_flat_map_variant( variant, self ) )
11971234 }
11981235
11991236 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> {
12141251 . make_opt_expr ( )
12151252 . map ( |expr| expr. into_inner ( ) )
12161253 } 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+ } )
12201259 } )
12211260 }
12221261 } )
@@ -1225,7 +1264,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
12251264 fn visit_pat ( & mut self , pat : & mut P < ast:: Pat > ) {
12261265 match pat. kind {
12271266 PatKind :: MacCall ( _) => { }
1228- _ => return noop_visit_pat ( pat, self ) ,
1267+ _ => {
1268+ return assign_id ! ( self , & mut pat. id, || noop_visit_pat( pat, self ) ) ;
1269+ }
12291270 }
12301271
12311272 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> {
12781319 & mut self . cx . current_expansion . dir_ownership ,
12791320 DirOwnership :: UnownedViaBlock ,
12801321 ) ;
1281- noop_visit_block ( block, self ) ;
1322+ assign_id ! ( self , & mut block . id , || noop_visit_block( block, self ) ) ;
12821323 self . cx . current_expansion . dir_ownership = orig_dir_ownership;
12831324 }
12841325
@@ -1377,7 +1418,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
13771418 let orig_dir_ownership =
13781419 mem:: replace ( & mut self . cx . current_expansion . dir_ownership , dir_ownership) ;
13791420
1380- let result = noop_flat_map_item ( item, self ) ;
1421+ let result = assign_id ! ( self , & mut item . id , || noop_flat_map_item( item, self ) ) ;
13811422
13821423 // Restore the module info.
13831424 self . cx . current_expansion . dir_ownership = orig_dir_ownership;
@@ -1387,7 +1428,12 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
13871428 }
13881429 _ => {
13891430 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+ }
13911437 }
13921438 }
13931439 }
@@ -1411,7 +1457,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
14111457 _ => unreachable ! ( ) ,
14121458 } )
14131459 }
1414- _ => noop_flat_map_assoc_item ( item, self ) ,
1460+ _ => {
1461+ assign_id ! ( self , & mut item. id, || noop_flat_map_assoc_item( item, self ) )
1462+ }
14151463 }
14161464 }
14171465
@@ -1434,14 +1482,16 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
14341482 _ => unreachable ! ( ) ,
14351483 } )
14361484 }
1437- _ => noop_flat_map_assoc_item ( item, self ) ,
1485+ _ => {
1486+ assign_id ! ( self , & mut item. id, || noop_flat_map_assoc_item( item, self ) )
1487+ }
14381488 }
14391489 }
14401490
14411491 fn visit_ty ( & mut self , ty : & mut P < ast:: Ty > ) {
14421492 match ty. kind {
14431493 ast:: TyKind :: MacCall ( _) => { }
1444- _ => return noop_visit_ty ( ty, self ) ,
1494+ _ => return assign_id ! ( self , & mut ty . id , || noop_visit_ty( ty, self ) ) ,
14451495 } ;
14461496
14471497 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> {
14781528 _ => unreachable ! ( ) ,
14791529 } )
14801530 }
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+ }
14821537 }
14831538 }
14841539
@@ -1498,13 +1553,14 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
14981553 . make_generic_params ( ) ;
14991554 }
15001555
1501- noop_flat_map_generic_param ( param, self )
1556+ assign_id ! ( self , & mut param . id , || noop_flat_map_generic_param( param, self ) )
15021557 }
15031558
15041559 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 ( ) ;
15081564 }
15091565 }
15101566}
0 commit comments