|
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