Skip to content

Commit deb53a3

Browse files
committed
walk the bodies "in order" by traversing the crate
Otherwise the errors from borrowck come out in an unpredictable order.
1 parent 7770e9a commit deb53a3

File tree

3 files changed

+50
-23
lines changed

3 files changed

+50
-23
lines changed

src/librustc/dep_graph/visit.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use hir;
1212
use hir::def_id::DefId;
1313
use hir::itemlikevisit::ItemLikeVisitor;
14+
use hir::intravisit::{self, NestedVisitorMap, Visitor};
1415
use ty::TyCtxt;
1516

1617
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>
7879
pub fn visit_all_bodies_in_krate<'a, 'tcx, C>(tcx: TyCtxt<'a, 'tcx, 'tcx>, callback: C)
7980
where C: Fn(/* body_owner */ DefId, /* body id */ hir::BodyId),
8081
{
82+
// NB: we use a visitor here rather than walking the keys of the
83+
// hashmap so as to ensure we visit the bodies "in order".
84+
8185
let krate = tcx.hir.krate();
82-
for body_id in krate.bodies.keys().cloned() {
83-
let body_owner_def_id = tcx.hir.body_owner_def_id(body_id);
84-
callback(body_owner_def_id, body_id);
86+
intravisit::walk_crate(&mut V { tcx, callback }, krate);
87+
88+
struct V<'a, 'tcx: 'a, C> {
89+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
90+
callback: C
91+
}
92+
93+
impl<'a, 'tcx, C> Visitor<'tcx> for V<'a, 'tcx, C>
94+
where C: Fn(/* body_owner */ DefId, /* body id */ hir::BodyId),
95+
{
96+
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
97+
NestedVisitorMap::All(&self.tcx.hir)
98+
}
99+
100+
fn visit_body(&mut self, body: &'tcx hir::Body) {
101+
let body_id = body.id();
102+
let body_owner_def_id = self.tcx.hir.body_owner_def_id(body_id);
103+
(self.callback)(body_owner_def_id, body_id);
104+
105+
intravisit::walk_body(self, body);
106+
}
85107
}
86108
}

src/librustc/hir/map/mod.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -168,43 +168,48 @@ impl<'hir> MapEntry<'hir> {
168168
})
169169
}
170170

171-
fn is_body_owner(self, node_id: NodeId) -> bool {
171+
fn associated_body(self) -> Option<BodyId> {
172172
match self {
173173
EntryItem(_, item) => {
174174
match item.node {
175175
ItemConst(_, body) |
176176
ItemStatic(.., body) |
177-
ItemFn(_, _, _, _, _, body) => body.node_id == node_id,
178-
_ => false
177+
ItemFn(_, _, _, _, _, body) => Some(body),
178+
_ => None,
179179
}
180180
}
181181

182182
EntryTraitItem(_, item) => {
183183
match item.node {
184184
TraitItemKind::Const(_, Some(body)) |
185-
TraitItemKind::Method(_, TraitMethod::Provided(body)) => {
186-
body.node_id == node_id
187-
}
188-
_ => false
185+
TraitItemKind::Method(_, TraitMethod::Provided(body)) => Some(body),
186+
_ => None
189187
}
190188
}
191189

192190
EntryImplItem(_, item) => {
193191
match item.node {
194192
ImplItemKind::Const(_, body) |
195-
ImplItemKind::Method(_, body) => body.node_id == node_id,
196-
_ => false
193+
ImplItemKind::Method(_, body) => Some(body),
194+
_ => None,
197195
}
198196
}
199197

200198
EntryExpr(_, expr) => {
201199
match expr.node {
202-
ExprClosure(.., body, _) => body.node_id == node_id,
203-
_ => false
200+
ExprClosure(.., body, _) => Some(body),
201+
_ => None,
204202
}
205203
}
206204

207-
_ => false
205+
_ => None
206+
}
207+
}
208+
209+
fn is_body_owner(self, node_id: NodeId) -> bool {
210+
match self.associated_body() {
211+
Some(b) => b.node_id == node_id,
212+
None => false,
208213
}
209214
}
210215
}

src/test/ui/span/mut-arg-hint.stderr

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
error: cannot borrow immutable borrowed content `*a` as mutable
2-
--> $DIR/mut-arg-hint.rs:18:5
3-
|
4-
17 | pub fn foo<'a>(mut a: &'a String) {
5-
| ---------- use `&'a mut String` here to make mutable
6-
18 | a.push_str("foo");
7-
| ^ cannot borrow as mutable
8-
91
error: cannot borrow immutable borrowed content `*a` as mutable
102
--> $DIR/mut-arg-hint.rs:13:9
113
|
@@ -14,6 +6,14 @@ error: cannot borrow immutable borrowed content `*a` as mutable
146
13 | a.push_str("bar");
157
| ^ cannot borrow as mutable
168

9+
error: cannot borrow immutable borrowed content `*a` as mutable
10+
--> $DIR/mut-arg-hint.rs:18:5
11+
|
12+
17 | pub fn foo<'a>(mut a: &'a String) {
13+
| ---------- use `&'a mut String` here to make mutable
14+
18 | a.push_str("foo");
15+
| ^ cannot borrow as mutable
16+
1717
error: cannot borrow immutable borrowed content `*a` as mutable
1818
--> $DIR/mut-arg-hint.rs:25:9
1919
|

0 commit comments

Comments
 (0)