Skip to content

Commit 62a52ed

Browse files
committed
Implement PlaceExt trait for NeoPlace
1 parent 915d277 commit 62a52ed

File tree

1 file changed

+58
-1
lines changed

1 file changed

+58
-1
lines changed

src/librustc_mir/borrow_check/place_ext.rs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc::hir;
22
use rustc::mir::ProjectionElem;
3-
use rustc::mir::{Mir, Place, PlaceBase, Mutability};
3+
use rustc::mir::{Mir, Place, NeoPlace, PlaceBase, Mutability};
44
use rustc::mir::tcx::PlaceTy;
55
use rustc::ty::{self, TyCtxt};
66
use borrow_check::borrow_set::LocalsStateAtExit;
@@ -76,3 +76,60 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
7676
is_unsafe_place
7777
}
7878
}
79+
80+
impl<'tcx> PlaceExt<'tcx> for NeoPlace<'tcx> {
81+
fn ignore_borrow(
82+
&self,
83+
tcx: TyCtxt<'_, '_, 'tcx>,
84+
mir: &Mir<'tcx>,
85+
locals_state_at_exit: &LocalsStateAtExit,
86+
) -> bool {
87+
let mut is_unsafe_place = match &self.base {
88+
// If a local variable is immutable, then we only need to track borrows to guard
89+
// against two kinds of errors:
90+
// * The variable being dropped while still borrowed (e.g., because the fn returns
91+
// a reference to a local variable)
92+
// * The variable being moved while still borrowed
93+
//
94+
// In particular, the variable cannot be mutated -- the "access checks" will fail --
95+
// so we don't have to worry about mutation while borrowed.
96+
PlaceBase::Local(index) => {
97+
match locals_state_at_exit {
98+
LocalsStateAtExit::AllAreInvalidated => false,
99+
LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => {
100+
let ignore = !has_storage_dead_or_moved.contains(*index) &&
101+
mir.local_decls[*index].mutability == Mutability::Not;
102+
debug!("ignore_borrow: local {:?} => {:?}", index, ignore);
103+
ignore
104+
}
105+
}
106+
},
107+
PlaceBase::Promoted(_) => false,
108+
PlaceBase::Static(static_) => {
109+
tcx.is_static(static_.def_id) == Some(hir::Mutability::MutMutable)
110+
}
111+
};
112+
113+
let mut base_ty = self.base.ty(mir);
114+
for elem in self.elems.iter() {
115+
if let ProjectionElem::Deref = elem {
116+
if let ty::RawPtr(..) | ty::Ref(_, _, hir::MutImmutable) = base_ty.sty {
117+
// For both derefs of raw pointers and `&T`
118+
// references, the original path is `Copy` and
119+
// therefore not significant. In particular,
120+
// there is nothing the user can do to the
121+
// original path that would invalidate the
122+
// newly created reference -- and if there
123+
// were, then the user could have copied the
124+
// original path into a new variable and
125+
// borrowed *that* one, leaving the original
126+
// path unborrowed.
127+
is_unsafe_place = true;
128+
}
129+
}
130+
base_ty = PlaceTy::from(base_ty).projection_ty(tcx, elem).to_ty(tcx);
131+
}
132+
133+
is_unsafe_place
134+
}
135+
}

0 commit comments

Comments
 (0)