diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index 549608bf7ee5f..bb6a13ed15a52 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -154,62 +154,51 @@ impl<'mir, 'a: 'mir, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> context: PlaceContext, location: Location) { debug!("visit_place(place={:?}, context={:?})", place, context); - let mut context = context; let cx = self.fx.cx; - place.iterate(|place_base, place_projections| { - for proj in place_projections { - // Allow uses of projections that are ZSTs or from scalar fields. - let is_consume = match context { - PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) | - PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => true, - _ => false - }; - if is_consume { - let base_ty = proj.base.ty(self.fx.mir, cx.tcx()); - let base_ty = self.fx.monomorphize(&base_ty); - - // ZSTs don't require any actual memory access. - let elem_ty = base_ty - .projection_ty(cx.tcx(), &proj.elem) - .ty; - let elem_ty = self.fx.monomorphize(&elem_ty); - if cx.layout_of(elem_ty).is_zst() { - return; - } - - if let mir::ProjectionElem::Field(..) = proj.elem { - let layout = cx.layout_of(base_ty.ty); - if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) { - // Recurse with the same context, instead of `Projection`, - // potentially stopping at non-operand projections, - // which would trigger `not_ssa` on locals. - continue; - } - } + if let mir::Place::Projection(ref proj) = *place { + // Allow uses of projections that are ZSTs or from scalar fields. + let is_consume = match context { + PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) | + PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => true, + _ => false + }; + if is_consume { + let base_ty = proj.base.ty(self.fx.mir, cx.tcx()); + let base_ty = self.fx.monomorphize(&base_ty); + + // ZSTs don't require any actual memory access. + let elem_ty = base_ty + .projection_ty(cx.tcx(), &proj.elem) + .ty; + let elem_ty = self.fx.monomorphize(&elem_ty); + if cx.layout_of(elem_ty).is_zst() { + return; } - // A deref projection only reads the pointer, never needs the place. - if let mir::ProjectionElem::Deref = proj.elem { - return self.visit_place( - &proj.base, - PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy), - location - ); + if let mir::ProjectionElem::Field(..) = proj.elem { + let layout = cx.layout_of(base_ty.ty); + if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) { + // Recurse with the same context, instead of `Projection`, + // potentially stopping at non-operand projections, + // which would trigger `not_ssa` on locals. + self.visit_place(&proj.base, context, location); + return; + } } - - context = if context.is_mutating_use() { - PlaceContext::MutatingUse(MutatingUseContext::Projection) - } else { - PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) - }; } - // Default base visit behavior - if let mir::PlaceBase::Local(local) = place_base { - self.visit_local(local, context, location); + // A deref projection only reads the pointer, never needs the place. + if let mir::ProjectionElem::Deref = proj.elem { + return self.visit_place( + &proj.base, + PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy), + location + ); } - }); + } + + self.super_place(place, context, location); } fn visit_local(&mut self,