diff --git a/src/librustc/dep_graph/visit.rs b/src/librustc/dep_graph/visit.rs index 0d10049bc1e4e..a34a3591c151d 100644 --- a/src/librustc/dep_graph/visit.rs +++ b/src/librustc/dep_graph/visit.rs @@ -11,7 +11,6 @@ use hir; use hir::def_id::DefId; use hir::itemlikevisit::ItemLikeVisitor; -use hir::intravisit::{self, NestedVisitorMap, Visitor}; use ty::TyCtxt; use super::dep_node::DepNode; @@ -79,30 +78,9 @@ pub fn visit_all_item_likes_in_krate<'a, 'tcx, V, F>(tcx: TyCtxt<'a, 'tcx, 'tcx> pub fn visit_all_bodies_in_krate<'a, 'tcx, C>(tcx: TyCtxt<'a, 'tcx, 'tcx>, callback: C) where C: Fn(/* body_owner */ DefId, /* body id */ hir::BodyId), { - // NB: we use a visitor here rather than walking the keys of the - // hashmap so as to ensure we visit the bodies "in order". - let krate = tcx.hir.krate(); - intravisit::walk_crate(&mut V { tcx, callback }, krate); - - struct V<'a, 'tcx: 'a, C> { - tcx: TyCtxt<'a, 'tcx, 'tcx>, - callback: C - } - - impl<'a, 'tcx, C> Visitor<'tcx> for V<'a, 'tcx, C> - where C: Fn(/* body_owner */ DefId, /* body id */ hir::BodyId), - { - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::All(&self.tcx.hir) - } - - fn visit_body(&mut self, body: &'tcx hir::Body) { - let body_id = body.id(); - let body_owner_def_id = self.tcx.hir.body_owner_def_id(body_id); - (self.callback)(body_owner_def_id, body_id); - - intravisit::walk_body(self, body); - } + for &body_id in &krate.body_ids { + let body_owner_def_id = tcx.hir.body_owner_def_id(body_id); + callback(body_owner_def_id, body_id); } } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index c12de6807b103..77f11c94c2128 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -185,6 +185,7 @@ impl<'a> LoweringContext<'a> { let module = self.lower_mod(&c.module); let attrs = self.lower_attrs(&c.attrs); let exported_macros = c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect(); + let body_ids = body_ids(&self.bodies); hir::Crate { module: module, @@ -195,6 +196,7 @@ impl<'a> LoweringContext<'a> { trait_items: self.trait_items, impl_items: self.impl_items, bodies: self.bodies, + body_ids: body_ids, } } @@ -2408,3 +2410,11 @@ impl<'a> LoweringContext<'a> { } } } + +fn body_ids(bodies: &BTreeMap) -> Vec { + // Sorting by span ensures that we get things in order within a + // file, and also puts the files in a sensible order. + let mut body_ids: Vec<_> = bodies.keys().cloned().collect(); + body_ids.sort_by_key(|b| bodies[b].value.span); + body_ids +} diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 6f03073c803c6..8715c89c6540d 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -410,6 +410,12 @@ pub struct Crate { pub trait_items: BTreeMap, pub impl_items: BTreeMap, pub bodies: BTreeMap, + + /// A list of the body ids written out in the order in which they + /// appear in the crate. If you're going to process all the bodies + /// in the crate, you should iterate over this list rather than the keys + /// of bodies. + pub body_ids: Vec, } impl Crate { diff --git a/src/librustc_incremental/calculate_svh/svh_visitor.rs b/src/librustc_incremental/calculate_svh/svh_visitor.rs index c7512f2971b33..40e534e25e998 100644 --- a/src/librustc_incremental/calculate_svh/svh_visitor.rs +++ b/src/librustc_incremental/calculate_svh/svh_visitor.rs @@ -1166,6 +1166,7 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> { trait_items: _, impl_items: _, bodies: _, + body_ids: _, } = *krate; visit::Visitor::visit_mod(self, module, span, ast::CRATE_NODE_ID);