From 936fa6f67fb9b91c78d8e7eb3fda38d76790f4d3 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 4 Aug 2018 09:26:30 +0200 Subject: [PATCH] generalize the Deref case and simplify the code --- .../borrow_check/nll/escaping_locals.rs | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/escaping_locals.rs b/src/librustc_mir/borrow_check/nll/escaping_locals.rs index 56ee35714f2..40bb810b4a7 100644 --- a/src/librustc_mir/borrow_check/nll/escaping_locals.rs +++ b/src/librustc_mir/borrow_check/nll/escaping_locals.rs @@ -44,7 +44,7 @@ use rustc::mir::visit::Visitor; use rustc::mir::*; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::TyCtxt; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::unify as ut; @@ -178,20 +178,29 @@ fn visit_assign( match rvalue { Rvalue::Use(op) => self.union_locals_if_needed(local, find_local_in_operand(op)), Rvalue::Ref(_, _, place) => { - // Special case: if you have `X = &*Y` where `Y` is a - // reference, then the outlives relationships should - // ensure that all regions in `Y` are constrained by - // regions in `X`. - if let Place::Projection(proj) = place { + // Special case: if you have `X = &*Y` (or `X = &**Y` + // etc), then the outlives relationships will ensure + // that all regions in `Y` are constrained by regions + // in `X` -- this is because the lifetimes of the + // references we deref through are required to outlive + // the borrow lifetime (which appears in `X`). + // + // (We don't actually need to check the type of `Y`: + // since `ProjectionElem::Deref` represents a built-in + // deref and not an overloaded deref, if the thing we + // deref through is not a reference, then it must be a + // `Box` or `*const`, in which case it contains no + // references.) + let mut place_ref = place; + while let Place::Projection(proj) = place_ref { if let ProjectionElem::Deref = proj.elem { - if let ty::TyRef(..) = proj.base.ty(self.mir, self.tcx).to_ty(self.tcx).sty - { - self.union_locals_if_needed(local, find_local_in_place(&proj.base)); - } + place_ref = &proj.base; + } else { + break; } } - self.union_locals_if_needed(local, find_local_in_place(place)) + self.union_locals_if_needed(local, find_local_in_place(place_ref)) } Rvalue::Cast(kind, op, _) => match kind { -- 2.44.0