|
44 | 44 |
|
45 | 45 | use rustc::mir::visit::Visitor; |
46 | 46 | use rustc::mir::*; |
47 | | -use rustc::ty::{self, TyCtxt}; |
| 47 | +use rustc::ty::TyCtxt; |
48 | 48 |
|
49 | 49 | use rustc_data_structures::indexed_vec::Idx; |
50 | 50 | use rustc_data_structures::unify as ut; |
@@ -178,20 +178,29 @@ impl Visitor<'tcx> for GatherAssignedLocalsVisitor<'_, '_, 'tcx> { |
178 | 178 | match rvalue { |
179 | 179 | Rvalue::Use(op) => self.union_locals_if_needed(local, find_local_in_operand(op)), |
180 | 180 | 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 { |
186 | 196 | 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; |
191 | 200 | } |
192 | 201 | } |
193 | 202 |
|
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)) |
195 | 204 | } |
196 | 205 |
|
197 | 206 | Rvalue::Cast(kind, op, _) => match kind { |
|
0 commit comments