Skip to content

Commit

Permalink
walk the bodies "in order" by traversing the crate
Browse files Browse the repository at this point in the history
Otherwise the errors from borrowck come out in an unpredictable
order.
  • Loading branch information
nikomatsakis committed Feb 28, 2017
1 parent 3e9bdda commit d79ad36
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 23 deletions.
28 changes: 25 additions & 3 deletions src/librustc/dep_graph/visit.rs
Expand Up @@ -11,6 +11,7 @@
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;
Expand Down Expand Up @@ -78,9 +79,30 @@ 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();
for body_id in krate.bodies.keys().cloned() {
let body_owner_def_id = tcx.hir.body_owner_def_id(body_id);
callback(body_owner_def_id, body_id);
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);
}
}
}
29 changes: 17 additions & 12 deletions src/librustc/hir/map/mod.rs
Expand Up @@ -168,43 +168,48 @@ impl<'hir> MapEntry<'hir> {
})
}

fn is_body_owner(self, node_id: NodeId) -> bool {
fn associated_body(self) -> Option<BodyId> {
match self {
EntryItem(_, item) => {
match item.node {
ItemConst(_, body) |
ItemStatic(.., body) |
ItemFn(_, _, _, _, _, body) => body.node_id == node_id,
_ => false
ItemFn(_, _, _, _, _, body) => Some(body),
_ => None,
}
}

EntryTraitItem(_, item) => {
match item.node {
TraitItemKind::Const(_, Some(body)) |
TraitItemKind::Method(_, TraitMethod::Provided(body)) => {
body.node_id == node_id
}
_ => false
TraitItemKind::Method(_, TraitMethod::Provided(body)) => Some(body),
_ => None
}
}

EntryImplItem(_, item) => {
match item.node {
ImplItemKind::Const(_, body) |
ImplItemKind::Method(_, body) => body.node_id == node_id,
_ => false
ImplItemKind::Method(_, body) => Some(body),
_ => None,
}
}

EntryExpr(_, expr) => {
match expr.node {
ExprClosure(.., body, _) => body.node_id == node_id,
_ => false
ExprClosure(.., body, _) => Some(body),
_ => None,
}
}

_ => false
_ => None
}
}

fn is_body_owner(self, node_id: NodeId) -> bool {
match self.associated_body() {
Some(b) => b.node_id == node_id,
None => false,
}
}
}
Expand Down
16 changes: 8 additions & 8 deletions src/test/ui/span/mut-arg-hint.stderr
@@ -1,11 +1,3 @@
error: cannot borrow immutable borrowed content `*a` as mutable
--> $DIR/mut-arg-hint.rs:18:5
|
17 | pub fn foo<'a>(mut a: &'a String) {
| ---------- use `&'a mut String` here to make mutable
18 | a.push_str("foo");
| ^ cannot borrow as mutable

error: cannot borrow immutable borrowed content `*a` as mutable
--> $DIR/mut-arg-hint.rs:13:9
|
Expand All @@ -14,6 +6,14 @@ error: cannot borrow immutable borrowed content `*a` as mutable
13 | a.push_str("bar");
| ^ cannot borrow as mutable

error: cannot borrow immutable borrowed content `*a` as mutable
--> $DIR/mut-arg-hint.rs:18:5
|
17 | pub fn foo<'a>(mut a: &'a String) {
| ---------- use `&'a mut String` here to make mutable
18 | a.push_str("foo");
| ^ cannot borrow as mutable

error: cannot borrow immutable borrowed content `*a` as mutable
--> $DIR/mut-arg-hint.rs:25:9
|
Expand Down

0 comments on commit d79ad36

Please sign in to comment.