@@ -39,6 +39,7 @@ pub fn fn_sig<'hir>(node: Node<'hir>) -> Option<&'hir FnSig<'hir>> {
39
39
}
40
40
}
41
41
42
+ #[ inline]
42
43
pub fn associated_body < ' hir > ( node : Node < ' hir > ) -> Option < BodyId > {
43
44
match node {
44
45
Node :: Item ( Item {
@@ -486,35 +487,13 @@ impl<'hir> Map<'hir> {
486
487
/// crate. If you would prefer to iterate over the bodies
487
488
/// themselves, you can do `self.hir().krate().body_ids.iter()`.
488
489
pub fn body_owners ( self ) -> impl Iterator < Item = LocalDefId > + ' hir {
489
- self . krate ( )
490
- . owners
491
- . iter_enumerated ( )
492
- . flat_map ( move |( owner, owner_info) | {
493
- let bodies = & owner_info. as_owner ( ) ?. nodes . bodies ;
494
- Some ( bodies. iter ( ) . map ( move |& ( local_id, _) | {
495
- let hir_id = HirId { owner, local_id } ;
496
- let body_id = BodyId { hir_id } ;
497
- self . body_owner_def_id ( body_id)
498
- } ) )
499
- } )
500
- . flatten ( )
490
+ self . tcx . hir_crate_items ( ( ) ) . body_owners . iter ( ) . copied ( )
501
491
}
502
492
503
493
pub fn par_body_owners < F : Fn ( LocalDefId ) + Sync + Send > ( self , f : F ) {
504
494
use rustc_data_structures:: sync:: { par_iter, ParallelIterator } ;
505
- #[ cfg( parallel_compiler) ]
506
- use rustc_rayon:: iter:: IndexedParallelIterator ;
507
-
508
- par_iter ( & self . krate ( ) . owners . raw ) . enumerate ( ) . for_each ( |( owner, owner_info) | {
509
- let owner = LocalDefId :: new ( owner) ;
510
- if let MaybeOwner :: Owner ( owner_info) = owner_info {
511
- par_iter ( owner_info. nodes . bodies . range ( ..) ) . for_each ( |( local_id, _) | {
512
- let hir_id = HirId { owner, local_id : * local_id } ;
513
- let body_id = BodyId { hir_id } ;
514
- f ( self . body_owner_def_id ( body_id) )
515
- } )
516
- }
517
- } ) ;
495
+
496
+ par_iter ( & self . tcx . hir_crate_items ( ( ) ) . body_owners [ ..] ) . for_each ( |& def_id| f ( def_id) ) ;
518
497
}
519
498
520
499
pub fn ty_param_owner ( self , def_id : LocalDefId ) -> LocalDefId {
@@ -1283,133 +1262,145 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
1283
1262
}
1284
1263
1285
1264
pub ( super ) fn hir_module_items ( tcx : TyCtxt < ' _ > , module_id : LocalDefId ) -> ModuleItems {
1286
- let mut collector = ModuleCollector {
1287
- tcx,
1288
- submodules : Vec :: default ( ) ,
1289
- items : Vec :: default ( ) ,
1290
- trait_items : Vec :: default ( ) ,
1291
- impl_items : Vec :: default ( ) ,
1292
- foreign_items : Vec :: default ( ) ,
1293
- } ;
1265
+ let mut collector = ItemCollector :: new ( tcx, false ) ;
1294
1266
1295
1267
let ( hir_mod, span, hir_id) = tcx. hir ( ) . get_module ( module_id) ;
1296
1268
collector. visit_mod ( hir_mod, span, hir_id) ;
1297
1269
1298
- let ModuleCollector { submodules, items, trait_items, impl_items, foreign_items, .. } =
1299
- collector;
1270
+ let ItemCollector {
1271
+ submodules,
1272
+ items,
1273
+ trait_items,
1274
+ impl_items,
1275
+ foreign_items,
1276
+ body_owners,
1277
+ ..
1278
+ } = collector;
1300
1279
return ModuleItems {
1301
1280
submodules : submodules. into_boxed_slice ( ) ,
1302
1281
items : items. into_boxed_slice ( ) ,
1303
1282
trait_items : trait_items. into_boxed_slice ( ) ,
1304
1283
impl_items : impl_items. into_boxed_slice ( ) ,
1305
1284
foreign_items : foreign_items. into_boxed_slice ( ) ,
1285
+ body_owners : body_owners. into_boxed_slice ( ) ,
1306
1286
} ;
1307
-
1308
- struct ModuleCollector < ' tcx > {
1309
- tcx : TyCtxt < ' tcx > ,
1310
- submodules : Vec < LocalDefId > ,
1311
- items : Vec < ItemId > ,
1312
- trait_items : Vec < TraitItemId > ,
1313
- impl_items : Vec < ImplItemId > ,
1314
- foreign_items : Vec < ForeignItemId > ,
1315
- }
1316
-
1317
- impl < ' hir > Visitor < ' hir > for ModuleCollector < ' hir > {
1318
- type NestedFilter = nested_filter:: All ;
1319
-
1320
- fn nested_visit_map ( & mut self ) -> Self :: Map {
1321
- self . tcx . hir ( )
1322
- }
1323
-
1324
- fn visit_item ( & mut self , item : & ' hir Item < ' hir > ) {
1325
- self . items . push ( item. item_id ( ) ) ;
1326
- if let ItemKind :: Mod ( ..) = item. kind {
1327
- // If this declares another module, do not recurse inside it.
1328
- self . submodules . push ( item. def_id ) ;
1329
- } else {
1330
- intravisit:: walk_item ( self , item)
1331
- }
1332
- }
1333
-
1334
- fn visit_trait_item ( & mut self , item : & ' hir TraitItem < ' hir > ) {
1335
- self . trait_items . push ( item. trait_item_id ( ) ) ;
1336
- intravisit:: walk_trait_item ( self , item)
1337
- }
1338
-
1339
- fn visit_impl_item ( & mut self , item : & ' hir ImplItem < ' hir > ) {
1340
- self . impl_items . push ( item. impl_item_id ( ) ) ;
1341
- intravisit:: walk_impl_item ( self , item)
1342
- }
1343
-
1344
- fn visit_foreign_item ( & mut self , item : & ' hir ForeignItem < ' hir > ) {
1345
- self . foreign_items . push ( item. foreign_item_id ( ) ) ;
1346
- intravisit:: walk_foreign_item ( self , item)
1347
- }
1348
- }
1349
1287
}
1350
1288
1351
1289
pub ( crate ) fn hir_crate_items ( tcx : TyCtxt < ' _ > , _: ( ) ) -> ModuleItems {
1352
- let mut collector = CrateCollector {
1353
- tcx,
1354
- submodules : Vec :: default ( ) ,
1355
- items : Vec :: default ( ) ,
1356
- trait_items : Vec :: default ( ) ,
1357
- impl_items : Vec :: default ( ) ,
1358
- foreign_items : Vec :: default ( ) ,
1359
- } ;
1290
+ let mut collector = ItemCollector :: new ( tcx, true ) ;
1360
1291
1292
+ // A "crate collector" and "module collector" start at a
1293
+ // module item (the former starts at the crate root) but only
1294
+ // the former needs to collect it. ItemCollector does not do this for us.
1295
+ collector. submodules . push ( CRATE_DEF_ID ) ;
1361
1296
tcx. hir ( ) . walk_toplevel_module ( & mut collector) ;
1362
1297
1363
- let CrateCollector { submodules, items, trait_items, impl_items, foreign_items, .. } =
1364
- collector;
1298
+ let ItemCollector {
1299
+ submodules,
1300
+ items,
1301
+ trait_items,
1302
+ impl_items,
1303
+ foreign_items,
1304
+ body_owners,
1305
+ ..
1306
+ } = collector;
1365
1307
1366
1308
return ModuleItems {
1367
1309
submodules : submodules. into_boxed_slice ( ) ,
1368
1310
items : items. into_boxed_slice ( ) ,
1369
1311
trait_items : trait_items. into_boxed_slice ( ) ,
1370
1312
impl_items : impl_items. into_boxed_slice ( ) ,
1371
1313
foreign_items : foreign_items. into_boxed_slice ( ) ,
1314
+ body_owners : body_owners. into_boxed_slice ( ) ,
1372
1315
} ;
1316
+ }
1373
1317
1374
- struct CrateCollector < ' tcx > {
1375
- tcx : TyCtxt < ' tcx > ,
1376
- submodules : Vec < LocalDefId > ,
1377
- items : Vec < ItemId > ,
1378
- trait_items : Vec < TraitItemId > ,
1379
- impl_items : Vec < ImplItemId > ,
1380
- foreign_items : Vec < ForeignItemId > ,
1318
+ struct ItemCollector < ' tcx > {
1319
+ // When true, it collects all items in the create,
1320
+ // otherwise it collects items in some module.
1321
+ crate_collector : bool ,
1322
+ tcx : TyCtxt < ' tcx > ,
1323
+ submodules : Vec < LocalDefId > ,
1324
+ items : Vec < ItemId > ,
1325
+ trait_items : Vec < TraitItemId > ,
1326
+ impl_items : Vec < ImplItemId > ,
1327
+ foreign_items : Vec < ForeignItemId > ,
1328
+ body_owners : Vec < LocalDefId > ,
1329
+ }
1330
+
1331
+ impl < ' tcx > ItemCollector < ' tcx > {
1332
+ fn new ( tcx : TyCtxt < ' tcx > , crate_collector : bool ) -> ItemCollector < ' tcx > {
1333
+ ItemCollector {
1334
+ crate_collector,
1335
+ tcx,
1336
+ submodules : Vec :: default ( ) ,
1337
+ items : Vec :: default ( ) ,
1338
+ trait_items : Vec :: default ( ) ,
1339
+ impl_items : Vec :: default ( ) ,
1340
+ foreign_items : Vec :: default ( ) ,
1341
+ body_owners : Vec :: default ( ) ,
1342
+ }
1381
1343
}
1344
+ }
1345
+
1346
+ impl < ' hir > Visitor < ' hir > for ItemCollector < ' hir > {
1347
+ type NestedFilter = nested_filter:: All ;
1382
1348
1383
- impl < ' hir > Visitor < ' hir > for CrateCollector < ' hir > {
1384
- type NestedFilter = nested_filter:: All ;
1349
+ fn nested_visit_map ( & mut self ) -> Self :: Map {
1350
+ self . tcx . hir ( )
1351
+ }
1385
1352
1386
- fn nested_visit_map ( & mut self ) -> Self :: Map {
1387
- self . tcx . hir ( )
1353
+ fn visit_item ( & mut self , item : & ' hir Item < ' hir > ) {
1354
+ if associated_body ( Node :: Item ( item) ) . is_some ( ) {
1355
+ self . body_owners . push ( item. def_id ) ;
1388
1356
}
1389
1357
1390
- fn visit_item ( & mut self , item : & ' hir Item < ' hir > ) {
1391
- self . items . push ( item. item_id ( ) ) ;
1358
+ self . items . push ( item. item_id ( ) ) ;
1359
+
1360
+ // Items that are modules are handled here instead of in visit_mod.
1361
+ if let ItemKind :: Mod ( module) = & item. kind {
1362
+ self . submodules . push ( item. def_id ) ;
1363
+ // A module collector does not recurse inside nested modules.
1364
+ if self . crate_collector {
1365
+ intravisit:: walk_mod ( self , module, item. hir_id ( ) ) ;
1366
+ }
1367
+ } else {
1392
1368
intravisit:: walk_item ( self , item)
1393
1369
}
1370
+ }
1394
1371
1395
- fn visit_mod ( & mut self , m : & ' hir Mod < ' hir > , _s : Span , n : HirId ) {
1396
- self . submodules . push ( n. owner ) ;
1397
- intravisit:: walk_mod ( self , m, n) ;
1398
- }
1372
+ fn visit_foreign_item ( & mut self , item : & ' hir ForeignItem < ' hir > ) {
1373
+ self . foreign_items . push ( item. foreign_item_id ( ) ) ;
1374
+ intravisit:: walk_foreign_item ( self , item)
1375
+ }
1376
+
1377
+ fn visit_anon_const ( & mut self , c : & ' hir AnonConst ) {
1378
+ self . body_owners . push ( self . tcx . hir ( ) . local_def_id ( c. hir_id ) ) ;
1379
+ intravisit:: walk_anon_const ( self , c)
1380
+ }
1399
1381
1400
- fn visit_foreign_item ( & mut self , item : & ' hir ForeignItem < ' hir > ) {
1401
- self . foreign_items . push ( item . foreign_item_id ( ) ) ;
1402
- intravisit :: walk_foreign_item ( self , item )
1382
+ fn visit_expr ( & mut self , ex : & ' hir Expr < ' hir > ) {
1383
+ if matches ! ( ex . kind , ExprKind :: Closure { .. } ) {
1384
+ self . body_owners . push ( self . tcx . hir ( ) . local_def_id ( ex . hir_id ) ) ;
1403
1385
}
1386
+ intravisit:: walk_expr ( self , ex)
1387
+ }
1404
1388
1405
- fn visit_trait_item ( & mut self , item : & ' hir TraitItem < ' hir > ) {
1406
- self . trait_items . push ( item. trait_item_id ( ) ) ;
1407
- intravisit :: walk_trait_item ( self , item)
1389
+ fn visit_trait_item ( & mut self , item : & ' hir TraitItem < ' hir > ) {
1390
+ if associated_body ( Node :: TraitItem ( item) ) . is_some ( ) {
1391
+ self . body_owners . push ( item. def_id ) ;
1408
1392
}
1409
1393
1410
- fn visit_impl_item ( & mut self , item : & ' hir ImplItem < ' hir > ) {
1411
- self . impl_items . push ( item. impl_item_id ( ) ) ;
1412
- intravisit:: walk_impl_item ( self , item)
1394
+ self . trait_items . push ( item. trait_item_id ( ) ) ;
1395
+ intravisit:: walk_trait_item ( self , item)
1396
+ }
1397
+
1398
+ fn visit_impl_item ( & mut self , item : & ' hir ImplItem < ' hir > ) {
1399
+ if associated_body ( Node :: ImplItem ( item) ) . is_some ( ) {
1400
+ self . body_owners . push ( item. def_id ) ;
1413
1401
}
1402
+
1403
+ self . impl_items . push ( item. impl_item_id ( ) ) ;
1404
+ intravisit:: walk_impl_item ( self , item)
1414
1405
}
1415
1406
}
0 commit comments