Skip to main content

rustc_ty_utils/
nested_bodies.rs

1use rustc_hir as hir;
2use rustc_hir::def_id::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 = NestedBodiesVisitor { tcx, root_def_id: item, nested_bodies: ::alloc::vec::Vec::new()vec![] };
10    collector.visit_body(body);
11    tcx.mk_local_def_ids(&collector.nested_bodies)
12}
13
14struct NestedBodiesVisitor<'tcx> {
15    tcx: TyCtxt<'tcx>,
16    root_def_id: LocalDefId,
17    nested_bodies: Vec<LocalDefId>,
18}
19
20impl<'tcx> Visitor<'tcx> for NestedBodiesVisitor<'tcx> {
21    fn visit_nested_body(&mut self, id: hir::BodyId) {
22        let body_def_id = self.tcx.hir_body_owner_def_id(id);
23        if self.tcx.typeck_root_def_id_local(body_def_id) == self.root_def_id {
24            // We visit nested bodies before adding the current body. This
25            // means that nested bodies are always stored before their parent.
26            let body = self.tcx.hir_body(id);
27            self.visit_body(body);
28            self.nested_bodies.push(body_def_id);
29        }
30    }
31}
32
33pub(super) fn provide(providers: &mut Providers) {
34    *providers = Providers { nested_bodies_within, ..*providers };
35}