Skip to content

Commit 10fe269

Browse files
committed
Make ignore_borrow iterate instead of recurse
1 parent 27cc0db commit 10fe269

File tree

1 file changed

+33
-35
lines changed

1 file changed

+33
-35
lines changed

src/librustc_mir/borrow_check/place_ext.rs

+33-35
Original file line numberDiff line numberDiff line change
@@ -25,40 +25,36 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
2525
mir: &Mir<'tcx>,
2626
locals_state_at_exit: &LocalsStateAtExit,
2727
) -> bool {
28-
match self {
29-
// If a local variable is immutable, then we only need to track borrows to guard
30-
// against two kinds of errors:
31-
// * The variable being dropped while still borrowed (e.g., because the fn returns
32-
// a reference to a local variable)
33-
// * The variable being moved while still borrowed
34-
//
35-
// In particular, the variable cannot be mutated -- the "access checks" will fail --
36-
// so we don't have to worry about mutation while borrowed.
37-
Place::Base(PlaceBase::Local(index)) => {
38-
match locals_state_at_exit {
39-
LocalsStateAtExit::AllAreInvalidated => false,
40-
LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => {
41-
let ignore = !has_storage_dead_or_moved.contains(*index) &&
42-
mir.local_decls[*index].mutability == Mutability::Not;
43-
debug!("ignore_borrow: local {:?} => {:?}", index, ignore);
44-
ignore
28+
self.iterate(|place_base, place_projection| {
29+
let ignore = match place_base {
30+
// If a local variable is immutable, then we only need to track borrows to guard
31+
// against two kinds of errors:
32+
// * The variable being dropped while still borrowed (e.g., because the fn returns
33+
// a reference to a local variable)
34+
// * The variable being moved while still borrowed
35+
//
36+
// In particular, the variable cannot be mutated -- the "access checks" will fail --
37+
// so we don't have to worry about mutation while borrowed.
38+
PlaceBase::Local(index) => {
39+
match locals_state_at_exit {
40+
LocalsStateAtExit::AllAreInvalidated => false,
41+
LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => {
42+
let ignore = !has_storage_dead_or_moved.contains(*index) &&
43+
mir.local_decls[*index].mutability == Mutability::Not;
44+
debug!("ignore_borrow: local {:?} => {:?}", index, ignore);
45+
ignore
46+
}
4547
}
4648
}
47-
}
48-
Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) =>
49-
false,
50-
Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => {
51-
tcx.is_mutable_static(*def_id)
52-
}
53-
Place::Projection(proj) => match proj.elem {
54-
ProjectionElem::Field(..)
55-
| ProjectionElem::Downcast(..)
56-
| ProjectionElem::Subslice { .. }
57-
| ProjectionElem::ConstantIndex { .. }
58-
| ProjectionElem::Index(_) => proj.base.ignore_borrow(
59-
tcx, mir, locals_state_at_exit),
49+
PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. }) =>
50+
false,
51+
PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. }) => {
52+
tcx.is_mutable_static(*def_id)
53+
}
54+
};
6055

61-
ProjectionElem::Deref => {
56+
for proj in place_projection {
57+
if proj.elem == ProjectionElem::Deref {
6258
let ty = proj.base.ty(mir, tcx).ty;
6359
match ty.sty {
6460
// For both derefs of raw pointers and `&T`
@@ -71,11 +67,13 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
7167
// original path into a new variable and
7268
// borrowed *that* one, leaving the original
7369
// path unborrowed.
74-
ty::RawPtr(..) | ty::Ref(_, _, hir::MutImmutable) => true,
75-
_ => proj.base.ignore_borrow(tcx, mir, locals_state_at_exit),
70+
ty::RawPtr(..) | ty::Ref(_, _, hir::MutImmutable) => return true,
71+
_ => {}
7672
}
7773
}
78-
},
79-
}
74+
}
75+
76+
ignore
77+
})
8078
}
8179
}

0 commit comments

Comments
 (0)