@@ -493,18 +493,7 @@ impl<'hir> Map<'hir> {
493
493
/// crate. If you would prefer to iterate over the bodies
494
494
/// themselves, you can do `self.hir().krate().body_ids.iter()`.
495
495
pub fn body_owners ( self ) -> impl Iterator < Item = LocalDefId > + ' hir {
496
- self . krate ( )
497
- . owners
498
- . iter_enumerated ( )
499
- . flat_map ( move |( owner, owner_info) | {
500
- let bodies = & owner_info. as_owner ( ) ?. nodes . bodies ;
501
- Some ( bodies. iter ( ) . map ( move |& ( local_id, _) | {
502
- let hir_id = HirId { owner, local_id } ;
503
- let body_id = BodyId { hir_id } ;
504
- self . body_owner_def_id ( body_id)
505
- } ) )
506
- } )
507
- . flatten ( )
496
+ self . tcx . hir_crate_items ( ( ) ) . body_owners . iter ( ) . copied ( )
508
497
}
509
498
510
499
pub fn par_body_owners < F : Fn ( LocalDefId ) + Sync + Send > ( self , f : F ) {
@@ -1239,19 +1228,28 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> Module
1239
1228
trait_items : Vec :: default ( ) ,
1240
1229
impl_items : Vec :: default ( ) ,
1241
1230
foreign_items : Vec :: default ( ) ,
1231
+ body_owners : Vec :: default ( ) ,
1242
1232
} ;
1243
1233
1244
1234
let ( hir_mod, span, hir_id) = tcx. hir ( ) . get_module ( module_id) ;
1245
1235
collector. visit_mod ( hir_mod, span, hir_id) ;
1246
1236
1247
- let ModuleCollector { submodules, items, trait_items, impl_items, foreign_items, .. } =
1248
- collector;
1237
+ let ModuleCollector {
1238
+ submodules,
1239
+ items,
1240
+ trait_items,
1241
+ impl_items,
1242
+ foreign_items,
1243
+ body_owners,
1244
+ ..
1245
+ } = collector;
1249
1246
return ModuleItems {
1250
1247
submodules : submodules. into_boxed_slice ( ) ,
1251
1248
items : items. into_boxed_slice ( ) ,
1252
1249
trait_items : trait_items. into_boxed_slice ( ) ,
1253
1250
impl_items : impl_items. into_boxed_slice ( ) ,
1254
1251
foreign_items : foreign_items. into_boxed_slice ( ) ,
1252
+ body_owners : body_owners. into_boxed_slice ( ) ,
1255
1253
} ;
1256
1254
1257
1255
struct ModuleCollector < ' tcx > {
@@ -1261,6 +1259,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> Module
1261
1259
trait_items : Vec < TraitItemId > ,
1262
1260
impl_items : Vec < ImplItemId > ,
1263
1261
foreign_items : Vec < ForeignItemId > ,
1262
+ body_owners : Vec < LocalDefId > ,
1264
1263
}
1265
1264
1266
1265
impl < ' hir > Visitor < ' hir > for ModuleCollector < ' hir > {
@@ -1271,7 +1270,16 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> Module
1271
1270
}
1272
1271
1273
1272
fn visit_item ( & mut self , item : & ' hir Item < ' hir > ) {
1273
+ if associated_body ( Node :: Item ( item) ) . is_some ( ) {
1274
+ self . body_owners . push ( item. def_id ) ;
1275
+ }
1276
+
1274
1277
self . items . push ( item. item_id ( ) ) ;
1278
+
1279
+ if self . tcx . hir ( ) . is_body_owner ( item. def_id ) {
1280
+ self . body_owners . push ( item. def_id ) ;
1281
+ }
1282
+
1275
1283
if let ItemKind :: Mod ( ..) = item. kind {
1276
1284
// If this declares another module, do not recurse inside it.
1277
1285
self . submodules . push ( item. def_id ) ;
@@ -1281,19 +1289,47 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> Module
1281
1289
}
1282
1290
1283
1291
fn visit_trait_item ( & mut self , item : & ' hir TraitItem < ' hir > ) {
1292
+ if associated_body ( Node :: TraitItem ( item) ) . is_some ( ) {
1293
+ self . body_owners . push ( item. def_id ) ;
1294
+ }
1295
+
1284
1296
self . trait_items . push ( item. trait_item_id ( ) ) ;
1285
1297
intravisit:: walk_trait_item ( self , item)
1286
1298
}
1287
1299
1288
1300
fn visit_impl_item ( & mut self , item : & ' hir ImplItem < ' hir > ) {
1301
+ if associated_body ( Node :: ImplItem ( item) ) . is_some ( ) {
1302
+ self . body_owners . push ( item. def_id ) ;
1303
+ }
1304
+
1289
1305
self . impl_items . push ( item. impl_item_id ( ) ) ;
1290
1306
intravisit:: walk_impl_item ( self , item)
1291
1307
}
1292
1308
1293
1309
fn visit_foreign_item ( & mut self , item : & ' hir ForeignItem < ' hir > ) {
1310
+ if associated_body ( Node :: ForeignItem ( item) ) . is_some ( ) {
1311
+ self . body_owners . push ( item. def_id ) ;
1312
+ }
1313
+
1294
1314
self . foreign_items . push ( item. foreign_item_id ( ) ) ;
1295
1315
intravisit:: walk_foreign_item ( self , item)
1296
1316
}
1317
+
1318
+ fn visit_expr ( & mut self , ex : & ' hir Expr < ' hir > ) {
1319
+ if matches ! ( ex. kind, ExprKind :: Closure { .. } )
1320
+ && associated_body ( Node :: Expr ( ex) ) . is_some ( )
1321
+ {
1322
+ self . body_owners . push ( ex. hir_id . owner ) ;
1323
+ }
1324
+ intravisit:: walk_expr ( self , ex)
1325
+ }
1326
+
1327
+ fn visit_anon_const ( & mut self , c : & ' hir AnonConst ) {
1328
+ if associated_body ( Node :: AnonConst ( c) ) . is_some ( ) {
1329
+ self . body_owners . push ( c. hir_id . owner ) ;
1330
+ }
1331
+ intravisit:: walk_anon_const ( self , c)
1332
+ }
1297
1333
}
1298
1334
}
1299
1335
@@ -1305,19 +1341,28 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
1305
1341
trait_items : Vec :: default ( ) ,
1306
1342
impl_items : Vec :: default ( ) ,
1307
1343
foreign_items : Vec :: default ( ) ,
1344
+ body_owners : Vec :: default ( ) ,
1308
1345
} ;
1309
1346
1310
1347
tcx. hir ( ) . walk_toplevel_module ( & mut collector) ;
1311
1348
1312
- let CrateCollector { submodules, items, trait_items, impl_items, foreign_items, .. } =
1313
- collector;
1349
+ let CrateCollector {
1350
+ submodules,
1351
+ items,
1352
+ trait_items,
1353
+ impl_items,
1354
+ foreign_items,
1355
+ body_owners,
1356
+ ..
1357
+ } = collector;
1314
1358
1315
1359
return ModuleItems {
1316
1360
submodules : submodules. into_boxed_slice ( ) ,
1317
1361
items : items. into_boxed_slice ( ) ,
1318
1362
trait_items : trait_items. into_boxed_slice ( ) ,
1319
1363
impl_items : impl_items. into_boxed_slice ( ) ,
1320
1364
foreign_items : foreign_items. into_boxed_slice ( ) ,
1365
+ body_owners : body_owners. into_boxed_slice ( ) ,
1321
1366
} ;
1322
1367
1323
1368
struct CrateCollector < ' tcx > {
@@ -1327,6 +1372,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
1327
1372
trait_items : Vec < TraitItemId > ,
1328
1373
impl_items : Vec < ImplItemId > ,
1329
1374
foreign_items : Vec < ForeignItemId > ,
1375
+ body_owners : Vec < LocalDefId > ,
1330
1376
}
1331
1377
1332
1378
impl < ' hir > Visitor < ' hir > for CrateCollector < ' hir > {
@@ -1337,6 +1383,10 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
1337
1383
}
1338
1384
1339
1385
fn visit_item ( & mut self , item : & ' hir Item < ' hir > ) {
1386
+ if associated_body ( Node :: Item ( item) ) . is_some ( ) {
1387
+ self . body_owners . push ( item. def_id ) ;
1388
+ }
1389
+
1340
1390
self . items . push ( item. item_id ( ) ) ;
1341
1391
intravisit:: walk_item ( self , item)
1342
1392
}
@@ -1347,18 +1397,46 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
1347
1397
}
1348
1398
1349
1399
fn visit_foreign_item ( & mut self , item : & ' hir ForeignItem < ' hir > ) {
1400
+ if associated_body ( Node :: ForeignItem ( item) ) . is_some ( ) {
1401
+ self . body_owners . push ( item. def_id ) ;
1402
+ }
1403
+
1350
1404
self . foreign_items . push ( item. foreign_item_id ( ) ) ;
1351
1405
intravisit:: walk_foreign_item ( self , item)
1352
1406
}
1353
1407
1354
1408
fn visit_trait_item ( & mut self , item : & ' hir TraitItem < ' hir > ) {
1409
+ if associated_body ( Node :: TraitItem ( item) ) . is_some ( ) {
1410
+ self . body_owners . push ( item. def_id ) ;
1411
+ }
1412
+
1355
1413
self . trait_items . push ( item. trait_item_id ( ) ) ;
1356
1414
intravisit:: walk_trait_item ( self , item)
1357
1415
}
1358
1416
1359
1417
fn visit_impl_item ( & mut self , item : & ' hir ImplItem < ' hir > ) {
1418
+ if associated_body ( Node :: ImplItem ( item) ) . is_some ( ) {
1419
+ self . body_owners . push ( item. def_id ) ;
1420
+ }
1421
+
1360
1422
self . impl_items . push ( item. impl_item_id ( ) ) ;
1361
1423
intravisit:: walk_impl_item ( self , item)
1362
1424
}
1425
+
1426
+ fn visit_expr ( & mut self , ex : & ' hir Expr < ' hir > ) {
1427
+ if matches ! ( ex. kind, ExprKind :: Closure { .. } )
1428
+ && associated_body ( Node :: Expr ( ex) ) . is_some ( )
1429
+ {
1430
+ self . body_owners . push ( ex. hir_id . owner ) ;
1431
+ }
1432
+ intravisit:: walk_expr ( self , ex)
1433
+ }
1434
+
1435
+ fn visit_anon_const ( & mut self , c : & ' hir AnonConst ) {
1436
+ if associated_body ( Node :: AnonConst ( c) ) . is_some ( ) {
1437
+ self . body_owners . push ( c. hir_id . owner ) ;
1438
+ }
1439
+ intravisit:: walk_anon_const ( self , c)
1440
+ }
1363
1441
}
1364
1442
}
0 commit comments