Skip to content

Commit 936fa6f

Browse files
committed
generalize the Deref case and simplify the code
1 parent e7d8d65 commit 936fa6f

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

src/librustc_mir/borrow_check/nll/escaping_locals.rs

+20-11
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
4545
use rustc::mir::visit::Visitor;
4646
use rustc::mir::*;
47-
use rustc::ty::{self, TyCtxt};
47+
use rustc::ty::TyCtxt;
4848

4949
use rustc_data_structures::indexed_vec::Idx;
5050
use rustc_data_structures::unify as ut;
@@ -178,20 +178,29 @@ impl Visitor<'tcx> for GatherAssignedLocalsVisitor<'_, '_, 'tcx> {
178178
match rvalue {
179179
Rvalue::Use(op) => self.union_locals_if_needed(local, find_local_in_operand(op)),
180180
Rvalue::Ref(_, _, place) => {
181-
// Special case: if you have `X = &*Y` where `Y` is a
182-
// reference, then the outlives relationships should
183-
// ensure that all regions in `Y` are constrained by
184-
// regions in `X`.
185-
if let Place::Projection(proj) = place {
181+
// Special case: if you have `X = &*Y` (or `X = &**Y`
182+
// etc), then the outlives relationships will ensure
183+
// that all regions in `Y` are constrained by regions
184+
// in `X` -- this is because the lifetimes of the
185+
// references we deref through are required to outlive
186+
// the borrow lifetime (which appears in `X`).
187+
//
188+
// (We don't actually need to check the type of `Y`:
189+
// since `ProjectionElem::Deref` represents a built-in
190+
// deref and not an overloaded deref, if the thing we
191+
// deref through is not a reference, then it must be a
192+
// `Box` or `*const`, in which case it contains no
193+
// references.)
194+
let mut place_ref = place;
195+
while let Place::Projection(proj) = place_ref {
186196
if let ProjectionElem::Deref = proj.elem {
187-
if let ty::TyRef(..) = proj.base.ty(self.mir, self.tcx).to_ty(self.tcx).sty
188-
{
189-
self.union_locals_if_needed(local, find_local_in_place(&proj.base));
190-
}
197+
place_ref = &proj.base;
198+
} else {
199+
break;
191200
}
192201
}
193202

194-
self.union_locals_if_needed(local, find_local_in_place(place))
203+
self.union_locals_if_needed(local, find_local_in_place(place_ref))
195204
}
196205

197206
Rvalue::Cast(kind, op, _) => match kind {

0 commit comments

Comments
 (0)