diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2017-02-20 21:18:16 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2017-02-28 08:43:47 -0500 |
| commit | d79ad36cf5c8f11e37001a090abae5ff94fbab1b (patch) | |
| tree | 7e60d68c0ba3a3abaa286963ca41c9b60b4aa1f7 | |
| parent | 3e9bddad7bcd2b1bb4e5d534c271c6005739ab9c (diff) | |
| download | rust-d79ad36cf5c8f11e37001a090abae5ff94fbab1b.tar.gz rust-d79ad36cf5c8f11e37001a090abae5ff94fbab1b.zip | |
walk the bodies "in order" by traversing the crate
Otherwise the errors from borrowck come out in an unpredictable order.
| -rw-r--r-- | src/librustc/dep_graph/visit.rs | 28 | ||||
| -rw-r--r-- | src/librustc/hir/map/mod.rs | 29 | ||||
| -rw-r--r-- | src/test/ui/span/mut-arg-hint.stderr | 16 |
3 files changed, 50 insertions, 23 deletions
diff --git a/src/librustc/dep_graph/visit.rs b/src/librustc/dep_graph/visit.rs index f807437750d..0d10049bc1e 100644 --- a/src/librustc/dep_graph/visit.rs +++ b/src/librustc/dep_graph/visit.rs @@ -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); + } } } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 20b4d8d8a8f..5d074903b2b 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -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, } } } diff --git a/src/test/ui/span/mut-arg-hint.stderr b/src/test/ui/span/mut-arg-hint.stderr index e4ed0622147..01364c07144 100644 --- a/src/test/ui/span/mut-arg-hint.stderr +++ b/src/test/ui/span/mut-arg-hint.stderr @@ -1,12 +1,4 @@ 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 | 12 | fn foo(mut a: &String) { @@ -15,6 +7,14 @@ error: cannot borrow immutable borrowed content `*a` as mutable | ^ 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 | 24 | pub fn foo(mut a: &String) { |
