@@ -39,6 +39,7 @@ pub fn fn_sig<'hir>(node: Node<'hir>) -> Option<&'hir FnSig<'hir>> {
3939 }
4040}
4141
42+ #[ inline]
4243pub fn associated_body < ' hir > ( node : Node < ' hir > ) -> Option < BodyId > {
4344 match node {
4445 Node :: Item ( Item {
@@ -486,35 +487,13 @@ impl<'hir> Map<'hir> {
486487 /// crate. If you would prefer to iterate over the bodies
487488 /// themselves, you can do `self.hir().krate().body_ids.iter()`.
488489 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 ( )
501491 }
502492
503493 pub fn par_body_owners < F : Fn ( LocalDefId ) + Sync + Send > ( self , f : F ) {
504494 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) ) ;
518497 }
519498
520499 pub fn ty_param_owner ( self , def_id : LocalDefId ) -> LocalDefId {
@@ -1283,133 +1262,145 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
12831262}
12841263
12851264pub ( 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 ) ;
12941266
12951267 let ( hir_mod, span, hir_id) = tcx. hir ( ) . get_module ( module_id) ;
12961268 collector. visit_mod ( hir_mod, span, hir_id) ;
12971269
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;
13001279 return ModuleItems {
13011280 submodules : submodules. into_boxed_slice ( ) ,
13021281 items : items. into_boxed_slice ( ) ,
13031282 trait_items : trait_items. into_boxed_slice ( ) ,
13041283 impl_items : impl_items. into_boxed_slice ( ) ,
13051284 foreign_items : foreign_items. into_boxed_slice ( ) ,
1285+ body_owners : body_owners. into_boxed_slice ( ) ,
13061286 } ;
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- }
13491287}
13501288
13511289pub ( 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 ) ;
13601291
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 ) ;
13611296 tcx. hir ( ) . walk_toplevel_module ( & mut collector) ;
13621297
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;
13651307
13661308 return ModuleItems {
13671309 submodules : submodules. into_boxed_slice ( ) ,
13681310 items : items. into_boxed_slice ( ) ,
13691311 trait_items : trait_items. into_boxed_slice ( ) ,
13701312 impl_items : impl_items. into_boxed_slice ( ) ,
13711313 foreign_items : foreign_items. into_boxed_slice ( ) ,
1314+ body_owners : body_owners. into_boxed_slice ( ) ,
13721315 } ;
1316+ }
13731317
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+ }
13811343 }
1344+ }
1345+
1346+ impl < ' hir > Visitor < ' hir > for ItemCollector < ' hir > {
1347+ type NestedFilter = nested_filter:: All ;
13821348
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+ }
13851352
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 ) ;
13881356 }
13891357
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 {
13921368 intravisit:: walk_item ( self , item)
13931369 }
1370+ }
13941371
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+ }
13991381
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 ) ) ;
14031385 }
1386+ intravisit:: walk_expr ( self , ex)
1387+ }
14041388
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 ) ;
14081392 }
14091393
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 ) ;
14131401 }
1402+
1403+ self . impl_items . push ( item. impl_item_id ( ) ) ;
1404+ intravisit:: walk_impl_item ( self , item)
14141405 }
14151406}
0 commit comments