walk the bodies "in order" by traversing the crate
Otherwise the errors from borrowck come out in an unpredictable order.
This commit is contained in:
parent
3e9bddad7b
commit
d79ad36cf5
3 changed files with 50 additions and 23 deletions
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
@ -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
|
||||
|
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue