rustc_ty_utils/
nested_bodies.rs1use rustc_hir as hir;
2use rustc_hir::def_id::{DefId, LocalDefId};
3use rustc_hir::intravisit::Visitor;
4use rustc_middle::query::Providers;
5use rustc_middle::ty::{self, TyCtxt};
6
7fn 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
15struct NestedBodiesVisitor<'tcx> {
16 tcx: TyCtxt<'tcx>,
17 root_def_id: DefId,
18 nested_bodies: Vec<LocalDefId>,
19}
20
21impl<'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 }
30}
31
32pub(super) fn provide(providers: &mut Providers) {
33 *providers = Providers { nested_bodies_within, ..*providers };
34}