store the visit order in the Crate

This commit is contained in:
Niko Matsakis 2017-02-21 12:23:47 -05:00
parent 1bb1e16e92
commit fab202c0a8
4 changed files with 20 additions and 26 deletions

View File

@ -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);
}
}

View File

@ -196,6 +196,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,
@ -206,6 +207,7 @@ impl<'a> LoweringContext<'a> {
trait_items: self.trait_items,
impl_items: self.impl_items,
bodies: self.bodies,
body_ids: body_ids,
trait_impls: self.trait_impls,
trait_default_impl: self.trait_default_impl,
}
@ -2524,3 +2526,11 @@ impl<'a> LoweringContext<'a> {
}
}
}
fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body>) -> Vec<hir::BodyId> {
// 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
}

View File

@ -412,6 +412,12 @@ pub struct Crate {
pub bodies: BTreeMap<BodyId, Body>,
pub trait_impls: BTreeMap<DefId, Vec<NodeId>>,
pub trait_default_impl: BTreeMap<DefId, NodeId>,
/// 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<BodyId>,
}
impl Crate {

View File

@ -1167,9 +1167,9 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
trait_items: _,
impl_items: _,
bodies: _,
trait_impls: _,
trait_default_impl: _,
body_ids: _,
} = *krate;
visit::Visitor::visit_mod(self, module, span, ast::CRATE_NODE_ID);