|
1 |
| -use rustc_hir as hir; |
2 |
| -use rustc_hir::def_id::{DefId, LocalDefId}; |
3 |
| -use rustc_hir::intravisit::Visitor; |
| 1 | +use rustc_hir::def_id::LocalDefId; |
4 | 2 | use rustc_middle::query::Providers;
|
5 | 3 | use rustc_middle::ty::{self, TyCtxt};
|
6 | 4 |
|
7 | 5 | fn nested_bodies_within<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx ty::List<LocalDefId> {
|
8 |
| - let body = tcx.hir_body_owned_by(item); |
9 |
| - let mut collector = |
10 |
| - NestedBodiesVisitor { tcx, root_def_id: item.to_def_id(), nested_bodies: vec![] }; |
11 |
| - collector.visit_body(body); |
12 |
| - tcx.mk_local_def_ids(&collector.nested_bodies) |
13 |
| -} |
14 |
| - |
15 |
| -struct NestedBodiesVisitor<'tcx> { |
16 |
| - tcx: TyCtxt<'tcx>, |
17 |
| - root_def_id: DefId, |
18 |
| - nested_bodies: Vec<LocalDefId>, |
19 |
| -} |
20 |
| - |
21 |
| -impl<'tcx> Visitor<'tcx> for NestedBodiesVisitor<'tcx> { |
22 |
| - fn visit_nested_body(&mut self, id: hir::BodyId) { |
23 |
| - let body_def_id = self.tcx.hir_body_owner_def_id(id); |
24 |
| - if self.tcx.typeck_root_def_id(body_def_id.to_def_id()) == self.root_def_id { |
25 |
| - self.nested_bodies.push(body_def_id); |
26 |
| - let body = self.tcx.hir_body(id); |
27 |
| - self.visit_body(body); |
28 |
| - } |
29 |
| - } |
| 6 | + let owner = tcx.local_def_id_to_hir_id(item).owner; |
| 7 | + let children = tcx.mk_local_def_ids_from_iter( |
| 8 | + tcx.hir_owner_nodes(owner) |
| 9 | + .bodies |
| 10 | + .iter() |
| 11 | + .map(|&(_, body)| tcx.hir_body_owner_def_id(body.id())) |
| 12 | + .filter(|&child_item| { |
| 13 | + // Anon consts are not owner IDs, but they may have (e.g.) closures in them. |
| 14 | + // Filter this just down to bodies that share the typeck root. |
| 15 | + child_item != item |
| 16 | + && tcx.typeck_root_def_id(child_item.to_def_id()).expect_local() == item |
| 17 | + }), |
| 18 | + ); |
| 19 | + children |
30 | 20 | }
|
31 | 21 |
|
32 | 22 | pub(super) fn provide(providers: &mut Providers) {
|
|
0 commit comments