Change:
} } <ins> trait DebugInfoOffsetLocation<'tcx, Bx> { fn deref(&self, bx: &mut Bx) -> Self; fn layout(&self) -> TyAndLayout<'tcx>; fn project_field(&self, bx: &mut Bx, field: mir::Field) -> Self; fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self; } impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx> for PlaceRef<'tcx, Bx::Value> { fn deref(&self, bx: &mut Bx) -> Self { bx.load_operand(*self).deref(bx.cx()) } fn layout(&self) -> TyAndLayout<'tcx> { self.layout } fn project_field(&self, bx: &mut Bx, field: mir::Field) -> Self { PlaceRef::project_field(*self, bx, field.index()) } fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self { self.project_downcast(bx, variant) } } impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx> for TyAndLayout<'tcx> { fn deref(&self, bx: &mut Bx) -> Self { bx.cx().layout_of( self.ty.builtin_deref(true).unwrap_or_else(|| bug!("cannot deref `{}`", self.ty)).ty, ) } fn layout(&self) -> TyAndLayout<'tcx> { *self } fn project_field(&self, bx: &mut Bx, field: mir::Field) -> Self { self.field(bx.cx(), field.index()) } fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self { self.for_variant(bx.cx(), variant) } } struct DebugInfoOffset<T> { /// Offset from the `base` used to calculate the debuginfo offset. direct_offset: Size, /// Each offset in this vector indicates one level of indirection from the base or previous /// indirect offset plus a dereference. indirect_offsets: Vec<Size>, /// The final location debuginfo should point to. result: T, } fn calculate_debuginfo_offset< 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>, L: DebugInfoOffsetLocation<'tcx, Bx>, >( bx: &mut Bx, local: mir::Local, var: &PerLocalVarDebugInfo<'tcx, Bx::DIVariable>, base: L, ) -> DebugInfoOffset<L> { let mut direct_offset = Size::ZERO; // FIXME(eddyb) use smallvec here. let mut indirect_offsets = vec![]; let mut place = base; for elem in &var.projection[..] { match *elem { mir::ProjectionElem::Deref => { indirect_offsets.push(Size::ZERO); place = place.deref(bx); } mir::ProjectionElem::Field(field, _) => { let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset); *offset += place.layout().fields.offset(field.index()); place = place.project_field(bx, field); } mir::ProjectionElem::Downcast(_, variant) => { place = place.downcast(bx, variant); } _ => span_bug!( var.source_info.span, "unsupported var debuginfo place `{:?}`", mir::Place { local, projection: var.projection }, ), } } DebugInfoOffset { direct_offset, indirect_offsets, result: place } } </ins> impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn set_debug_loc(&self, bx: &mut Bx, source_info: mir::SourceInfo) { bx.set_span(source_info.span);

Discussion:
When generating a variable debuginfo, rustc emits an expression describing the address of a source variable. Since , rustc also evaluates this expression. The expression can contain indirections, and it is not always valid to evaluate it. Consider a source variable that is described indirectly in terms of a base local. The source variable will be introduced at the beginning of a function, but at this point the base local might be uninitialized. For example: Note that has and metadata but loaded value is uninitialized. (This leads to end-to-end miscompilation with -Cdebuginfo=2). cc
A variant that demonstrates complete end-to-end miscompilation can be found in
Even without the metadata, this load could violate constraints. So just removing the metadata is not a proper fix. EDIT: Or does this always load from an that doesn't have any other pointers to it yet? Then it should be fine in terms of aliasing.