about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorWesley Wiser <wwiser@gmail.com>2020-05-30 15:02:32 -0400
committerWesley Wiser <wwiser@gmail.com>2020-12-06 20:48:25 -0500
commit01aec8d18556be5e8d498c2f331b9015b7befde2 (patch)
tree319bf10bc8a93fda56f200deedadf76c7a534b8e /compiler
parentb776d1c3e3db8befabb123ebb1e46c3531eaed46 (diff)
downloadrust-01aec8d18556be5e8d498c2f331b9015b7befde2.tar.gz
rust-01aec8d18556be5e8d498c2f331b9015b7befde2.zip
[mir-opt] Allow debuginfo to be generated for a constant or a Place
Prior to this commit, debuginfo was always generated by mapping a name
to a Place. This has the side-effect that `SimplifyLocals` cannot remove
locals that are only used for debuginfo because their other uses have
been const-propagated.

To allow these locals to be removed, we now allow debuginfo to point to
a constant value. The `ConstProp` pass detects when debuginfo points to
a local with a known constant value and replaces it with the value. This
allows the later `SimplifyLocals` pass to remove the local.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/constant.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs105
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs21
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs16
-rw-r--r--compiler/rustc_mir/src/borrow_check/mod.rs26
-rw-r--r--compiler/rustc_mir/src/transform/const_debuginfo.rs98
-rw-r--r--compiler/rustc_mir/src/transform/mod.rs2
-rw-r--r--compiler/rustc_mir/src/transform/simplify_try.rs41
-rw-r--r--compiler/rustc_mir/src/util/graphviz.rs2
-rw-r--r--compiler/rustc_mir/src/util/pretty.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs6
14 files changed, 255 insertions, 79 deletions
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 96484034da7..31e43893ac8 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -1409,10 +1409,11 @@ fn generator_layout_and_saved_local_names(
 
     let state_arg = mir::Local::new(1);
     for var in &body.var_debug_info {
-        if var.place.local != state_arg {
+        let place = if let mir::VarDebugInfoContents::Place(p) = var.value { p } else { continue };
+        if place.local != state_arg {
             continue;
         }
-        match var.place.projection[..] {
+        match place.projection[..] {
             [
                 // Deref of the `Pin<&mut Self>` state argument.
                 mir::ProjectionElem::Field(..),
diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs
index c8001b8daf0..3a85c268e0e 100644
--- a/compiler/rustc_codegen_ssa/src/mir/constant.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs
@@ -11,7 +11,7 @@ use super::FunctionCx;
 
 impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     pub fn eval_mir_constant_to_operand(
-        &mut self,
+        &self,
         bx: &mut Bx,
         constant: &mir::Constant<'tcx>,
     ) -> Result<OperandRef<'tcx, Bx::Value>, ErrorHandled> {
@@ -21,7 +21,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     }
 
     pub fn eval_mir_constant(
-        &mut self,
+        &self,
         constant: &mir::Constant<'tcx>,
     ) -> Result<ConstValue<'tcx>, ErrorHandled> {
         match self.monomorphize(constant.literal).val {
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index c4191a4e23d..d5b2cbaa558 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -8,7 +8,7 @@ use rustc_span::symbol::{kw, Symbol};
 use rustc_span::{BytePos, Span};
 use rustc_target::abi::{LayoutOf, Size};
 
-use super::operand::OperandValue;
+use super::operand::{OperandRef, OperandValue};
 use super::place::PlaceRef;
 use super::{FunctionCx, LocalRef};
 
@@ -116,6 +116,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         span
     }
 
+    fn spill_operand_to_stack(
+        operand: &OperandRef<'tcx, Bx::Value>,
+        name: Option<String>,
+        bx: &mut Bx,
+    ) -> PlaceRef<'tcx, Bx::Value> {
+        // "Spill" the value onto the stack, for debuginfo,
+        // without forcing non-debuginfo uses of the local
+        // to also load from the stack every single time.
+        // FIXME(#68817) use `llvm.dbg.value` instead,
+        // at least for the cases which LLVM handles correctly.
+        let spill_slot = PlaceRef::alloca(bx, operand.layout);
+        if let Some(name) = name {
+            bx.set_var_name(spill_slot.llval, &(name + ".dbg.spill"));
+        }
+        operand.val.store(bx, spill_slot);
+        spill_slot
+    }
+
     /// Apply debuginfo and/or name, after creating the `alloca` for a local,
     /// or initializing the local with an operand (whichever applies).
     pub fn debug_introduce_local(&self, bx: &mut Bx, local: mir::Local) {
@@ -226,17 +244,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     return;
                 }
 
-                // "Spill" the value onto the stack, for debuginfo,
-                // without forcing non-debuginfo uses of the local
-                // to also load from the stack every single time.
-                // FIXME(#68817) use `llvm.dbg.value` instead,
-                // at least for the cases which LLVM handles correctly.
-                let spill_slot = PlaceRef::alloca(bx, operand.layout);
-                if let Some(name) = name {
-                    bx.set_var_name(spill_slot.llval, &(name + ".dbg.spill"));
-                }
-                operand.val.store(bx, spill_slot);
-                spill_slot
+                Self::spill_operand_to_stack(operand, name, bx)
             }
 
             LocalRef::Place(place) => *place,
@@ -308,6 +316,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     /// Partition all `VarDebugInfo` in `self.mir`, by their base `Local`.
     pub fn compute_per_local_var_debug_info(
         &self,
+        bx: &mut Bx,
     ) -> Option<IndexVec<mir::Local, Vec<PerLocalVarDebugInfo<'tcx, Bx::DIVariable>>>> {
         let full_debug_info = self.cx.sess().opts.debuginfo == DebugInfo::Full;
 
@@ -322,31 +331,63 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             } else {
                 None
             };
+
             let dbg_var = dbg_scope_and_span.map(|(dbg_scope, _, span)| {
-                let place = var.place;
-                let var_ty = self.monomorphized_place_ty(place.as_ref());
-                let var_kind = if self.mir.local_kind(place.local) == mir::LocalKind::Arg
-                    && place.projection.is_empty()
-                    && var.source_info.scope == mir::OUTERMOST_SOURCE_SCOPE
-                {
-                    let arg_index = place.local.index() - 1;
-
-                    // FIXME(eddyb) shouldn't `ArgumentVariable` indices be
-                    // offset in closures to account for the hidden environment?
-                    // Also, is this `+ 1` needed at all?
-                    VariableKind::ArgumentVariable(arg_index + 1)
-                } else {
-                    VariableKind::LocalVariable
+                let (var_ty, var_kind) = match var.value {
+                    mir::VarDebugInfoContents::Place(place) => {
+                        let var_ty = self.monomorphized_place_ty(place.as_ref());
+                        let var_kind = if self.mir.local_kind(place.local) == mir::LocalKind::Arg
+                            && place.projection.is_empty()
+                            && var.source_info.scope == mir::OUTERMOST_SOURCE_SCOPE
+                        {
+                            let arg_index = place.local.index() - 1;
+
+                            // FIXME(eddyb) shouldn't `ArgumentVariable` indices be
+                            // offset in closures to account for the hidden environment?
+                            // Also, is this `+ 1` needed at all?
+                            VariableKind::ArgumentVariable(arg_index + 1)
+                        } else {
+                            VariableKind::LocalVariable
+                        };
+                        (var_ty, var_kind)
+                    }
+                    mir::VarDebugInfoContents::Const(c) => {
+                        let ty = self.monomorphize(c.literal.ty);
+                        (ty, VariableKind::LocalVariable)
+                    }
                 };
+
                 self.cx.create_dbg_var(var.name, var_ty, dbg_scope, var_kind, span)
             });
 
-            per_local[var.place.local].push(PerLocalVarDebugInfo {
-                name: var.name,
-                source_info: var.source_info,
-                dbg_var,
-                projection: var.place.projection,
-            });
+            match var.value {
+                mir::VarDebugInfoContents::Place(place) => {
+                    per_local[place.local].push(PerLocalVarDebugInfo {
+                        name: var.name,
+                        source_info: var.source_info,
+                        dbg_var,
+                        projection: place.projection,
+                    });
+                }
+                mir::VarDebugInfoContents::Const(c) => {
+                    if let Some(dbg_var) = dbg_var {
+                        let dbg_loc = match self.dbg_loc(var.source_info) {
+                            Some(dbg_loc) => dbg_loc,
+                            None => continue,
+                        };
+
+                        if let Ok(operand) = self.eval_mir_constant_to_operand(bx, &c) {
+                            let base = Self::spill_operand_to_stack(
+                                &operand,
+                                Some(var.name.to_string()),
+                                bx,
+                            );
+
+                            bx.dbg_var_addr(dbg_var, dbg_loc, base.llval, Size::ZERO, &[]);
+                        }
+                    }
+                }
+            }
         }
         Some(per_local)
     }
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 640f805d5e8..285140060be 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -186,7 +186,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         caller_location: None,
     };
 
-    fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info();
+    fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut bx);
 
     for const_ in &mir.required_consts {
         if let Err(err) = fx.eval_mir_constant(const_) {
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 814f91b0431..b54930e8d59 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1060,6 +1060,23 @@ impl<'tcx> LocalDecl<'tcx> {
     }
 }
 
+#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
+pub enum VarDebugInfoContents<'tcx> {
+    /// NOTE(eddyb) There's an unenforced invariant that this `Place` is
+    /// based on a `Local`, not a `Static`, and contains no indexing.
+    Place(Place<'tcx>),
+    Const(Constant<'tcx>),
+}
+
+impl<'tcx> Debug for VarDebugInfoContents<'tcx> {
+    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
+        match self {
+            VarDebugInfoContents::Const(c) => write!(fmt, "{}", c),
+            VarDebugInfoContents::Place(p) => write!(fmt, "{:?}", p),
+        }
+    }
+}
+
 /// Debug information pertaining to a user variable.
 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
 pub struct VarDebugInfo<'tcx> {
@@ -1071,9 +1088,7 @@ pub struct VarDebugInfo<'tcx> {
     pub source_info: SourceInfo,
 
     /// Where the data for this user variable is to be found.
-    /// NOTE(eddyb) There's an unenforced invariant that this `Place` is
-    /// based on a `Local`, not a `Static`, and contains no indexing.
-    pub place: Place<'tcx>,
+    pub value: VarDebugInfoContents<'tcx>,
 }
 
 ///////////////////////////////////////////////////////////////////////////
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 7538818b8af..e281010eb06 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -829,16 +829,20 @@ macro_rules! make_mir_visitor {
                 let VarDebugInfo {
                     name: _,
                     source_info,
-                    place,
+                    value,
                 } = var_debug_info;
 
                 self.visit_source_info(source_info);
                 let location = START_BLOCK.start_location();
-                self.visit_place(
-                    place,
-                    PlaceContext::NonUse(NonUseContext::VarDebugInfo),
-                    location,
-                );
+                match value {
+                    VarDebugInfoContents::Const(c) => self.visit_constant(c, location),
+                    VarDebugInfoContents::Place(place) =>
+                        self.visit_place(
+                            place,
+                            PlaceContext::NonUse(NonUseContext::VarDebugInfo),
+                            location
+                        ),
+                }
             }
 
             fn super_source_scope(&mut self,
diff --git a/compiler/rustc_mir/src/borrow_check/mod.rs b/compiler/rustc_mir/src/borrow_check/mod.rs
index de54c5582e0..3a6316b1ed3 100644
--- a/compiler/rustc_mir/src/borrow_check/mod.rs
+++ b/compiler/rustc_mir/src/borrow_check/mod.rs
@@ -11,7 +11,7 @@ use rustc_index::vec::IndexVec;
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_middle::mir::{
     traversal, Body, ClearCrossCrate, Local, Location, Mutability, Operand, Place, PlaceElem,
-    PlaceRef,
+    PlaceRef, VarDebugInfoContents,
 };
 use rustc_middle::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
 use rustc_middle::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
@@ -133,19 +133,21 @@ fn do_mir_borrowck<'a, 'tcx>(
 
     let mut local_names = IndexVec::from_elem(None, &input_body.local_decls);
     for var_debug_info in &input_body.var_debug_info {
-        if let Some(local) = var_debug_info.place.as_local() {
-            if let Some(prev_name) = local_names[local] {
-                if var_debug_info.name != prev_name {
-                    span_bug!(
-                        var_debug_info.source_info.span,
-                        "local {:?} has many names (`{}` vs `{}`)",
-                        local,
-                        prev_name,
-                        var_debug_info.name
-                    );
+        if let VarDebugInfoContents::Place(place) = var_debug_info.value {
+            if let Some(local) = place.as_local() {
+                if let Some(prev_name) = local_names[local] {
+                    if var_debug_info.name != prev_name {
+                        span_bug!(
+                            var_debug_info.source_info.span,
+                            "local {:?} has many names (`{}` vs `{}`)",
+                            local,
+                            prev_name,
+                            var_debug_info.name
+                        );
+                    }
                 }
+                local_names[local] = Some(var_debug_info.name);
             }
-            local_names[local] = Some(var_debug_info.name);
         }
     }
 
diff --git a/compiler/rustc_mir/src/transform/const_debuginfo.rs b/compiler/rustc_mir/src/transform/const_debuginfo.rs
new file mode 100644
index 00000000000..ed2c48b3568
--- /dev/null
+++ b/compiler/rustc_mir/src/transform/const_debuginfo.rs
@@ -0,0 +1,98 @@
+//! Finds locals which are assigned once to a const and unused except for debuginfo and converts
+//! their debuginfo to use the const directly, allowing the local to be removed.
+
+use rustc_middle::{
+    mir::{
+        visit::{PlaceContext, Visitor},
+        Body, Constant, Local, Location, Operand, Rvalue, StatementKind, VarDebugInfoContents,
+    },
+    ty::TyCtxt,
+};
+
+use crate::transform::MirPass;
+use rustc_index::{bit_set::BitSet, vec::IndexVec};
+
+pub struct ConstDebugInfo;
+
+impl<'tcx> MirPass<'tcx> for ConstDebugInfo {
+    fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+        trace!("running ConstDebugInfo on {:?}", body.source);
+
+        for (local, constant) in find_optimization_oportunities(body) {
+            for debuginfo in &mut body.var_debug_info {
+                if let VarDebugInfoContents::Place(p) = debuginfo.value {
+                    if p.local == local && p.projection.is_empty() {
+                        trace!(
+                            "changing debug info for {:?} from place {:?} to constant {:?}",
+                            debuginfo.name,
+                            p,
+                            constant
+                        );
+                        debuginfo.value = VarDebugInfoContents::Const(constant);
+                    }
+                }
+            }
+        }
+    }
+}
+
+struct LocalUseVisitor {
+    local_mutating_uses: IndexVec<Local, u8>,
+    local_assignment_locations: IndexVec<Local, Option<Location>>,
+}
+
+fn find_optimization_oportunities<'tcx>(body: &Body<'tcx>) -> Vec<(Local, Constant<'tcx>)> {
+    let mut visitor = LocalUseVisitor {
+        local_mutating_uses: IndexVec::from_elem(0, &body.local_decls),
+        local_assignment_locations: IndexVec::from_elem(None, &body.local_decls),
+    };
+
+    visitor.visit_body(body);
+
+    let mut locals_to_debuginfo = BitSet::new_empty(body.local_decls.len());
+    for debuginfo in &body.var_debug_info {
+        if let VarDebugInfoContents::Place(p) = debuginfo.value {
+            if let Some(l) = p.as_local() {
+                locals_to_debuginfo.insert(l);
+            }
+        }
+    }
+
+    let mut eligable_locals = Vec::new();
+    for (local, mutating_uses) in visitor.local_mutating_uses.drain_enumerated(..) {
+        if mutating_uses != 1 || !locals_to_debuginfo.contains(local) {
+            continue;
+        }
+
+        if let Some(location) = visitor.local_assignment_locations[local] {
+            let bb = &body[location.block];
+
+            // The value is assigned as the result of a call, not a constant
+            if bb.statements.len() == location.statement_index {
+                continue;
+            }
+
+            if let StatementKind::Assign(box (p, Rvalue::Use(Operand::Constant(box c)))) =
+                &bb.statements[location.statement_index].kind
+            {
+                if let Some(local) = p.as_local() {
+                    eligable_locals.push((local, *c));
+                }
+            }
+        }
+    }
+
+    eligable_locals
+}
+
+impl<'tcx> Visitor<'tcx> for LocalUseVisitor {
+    fn visit_local(&mut self, local: &Local, context: PlaceContext, location: Location) {
+        if context.is_mutating_use() {
+            self.local_mutating_uses[*local] = self.local_mutating_uses[*local].saturating_add(1);
+
+            if context.is_place_assignment() {
+                self.local_assignment_locations[*local] = Some(location);
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs
index e86d11e248f..809e29fb982 100644
--- a/compiler/rustc_mir/src/transform/mod.rs
+++ b/compiler/rustc_mir/src/transform/mod.rs
@@ -21,6 +21,7 @@ pub mod check_consts;
 pub mod check_packed_ref;
 pub mod check_unsafety;
 pub mod cleanup_post_borrowck;
+pub mod const_debuginfo;
 pub mod const_prop;
 pub mod coverage;
 pub mod deaggregator;
@@ -408,6 +409,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         &remove_noop_landing_pads::RemoveNoopLandingPads,
         &simplify::SimplifyCfg::new("final"),
         &nrvo::RenameReturnPlace,
+        &const_debuginfo::ConstDebugInfo,
         &simplify::SimplifyLocals,
         &multiple_return_terminators::MultipleReturnTerminators,
     ];
diff --git a/compiler/rustc_mir/src/transform/simplify_try.rs b/compiler/rustc_mir/src/transform/simplify_try.rs
index 27bb1def726..bea95bf43d2 100644
--- a/compiler/rustc_mir/src/transform/simplify_try.rs
+++ b/compiler/rustc_mir/src/transform/simplify_try.rs
@@ -246,14 +246,19 @@ fn get_arm_identity_info<'a, 'tcx>(
         tmp_assigned_vars.insert(*r);
     }
 
-    let dbg_info_to_adjust: Vec<_> =
-        debug_info
-            .iter()
-            .enumerate()
-            .filter_map(|(i, var_info)| {
-                if tmp_assigned_vars.contains(var_info.place.local) { Some(i) } else { None }
-            })
-            .collect();
+    let dbg_info_to_adjust: Vec<_> = debug_info
+        .iter()
+        .enumerate()
+        .filter_map(|(i, var_info)| {
+            if let VarDebugInfoContents::Place(p) = var_info.value {
+                if tmp_assigned_vars.contains(p.local) {
+                    return Some(i);
+                }
+            }
+
+            None
+        })
+        .collect();
 
     Some(ArmIdentityInfo {
         local_temp_0: local_tmp_s0,
@@ -340,9 +345,11 @@ fn optimization_applies<'tcx>(
     // Check that debug info only points to full Locals and not projections.
     for dbg_idx in &opt_info.dbg_info_to_adjust {
         let dbg_info = &var_debug_info[*dbg_idx];
-        if !dbg_info.place.projection.is_empty() {
-            trace!("NO: debug info for {:?} had a projection {:?}", dbg_info.name, dbg_info.place);
-            return false;
+        if let VarDebugInfoContents::Place(p) = dbg_info.value {
+            if !p.projection.is_empty() {
+                trace!("NO: debug info for {:?} had a projection {:?}", dbg_info.name, p);
+                return false;
+            }
         }
     }
 
@@ -423,9 +430,15 @@ impl<'tcx> MirPass<'tcx> for SimplifyArmIdentity {
                 // Fix the debug info to point to the right local
                 for dbg_index in opt_info.dbg_info_to_adjust {
                     let dbg_info = &mut debug_info[dbg_index];
-                    assert!(dbg_info.place.projection.is_empty());
-                    dbg_info.place.local = opt_info.local_0;
-                    dbg_info.place.projection = opt_info.dbg_projection;
+                    assert!(
+                        matches!(dbg_info.value, VarDebugInfoContents::Place(_)),
+                        "value was not a Place"
+                    );
+                    if let VarDebugInfoContents::Place(p) = &mut dbg_info.value {
+                        assert!(p.projection.is_empty());
+                        p.local = opt_info.local_0;
+                        p.projection = opt_info.dbg_projection;
+                    }
                 }
 
                 trace!("block is now {:?}", bb.statements);
diff --git a/compiler/rustc_mir/src/util/graphviz.rs b/compiler/rustc_mir/src/util/graphviz.rs
index 625f1a3e684..370010d65f0 100644
--- a/compiler/rustc_mir/src/util/graphviz.rs
+++ b/compiler/rustc_mir/src/util/graphviz.rs
@@ -220,7 +220,7 @@ fn write_graph_label<'tcx, W: Write>(
             w,
             r#"debug {} =&gt; {};<br align="left"/>"#,
             var_debug_info.name,
-            escape(&var_debug_info.place)
+            escape(&var_debug_info.value),
         )?;
     }
 
diff --git a/compiler/rustc_mir/src/util/pretty.rs b/compiler/rustc_mir/src/util/pretty.rs
index cd60602b088..b6a1b652cf6 100644
--- a/compiler/rustc_mir/src/util/pretty.rs
+++ b/compiler/rustc_mir/src/util/pretty.rs
@@ -495,7 +495,7 @@ fn write_scope_tree(
 
         let indented_debug_info = format!(
             "{0:1$}debug {2} => {3:?};",
-            INDENT, indent, var_debug_info.name, var_debug_info.place,
+            INDENT, indent, var_debug_info.name, var_debug_info.value,
         );
 
         writeln!(
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 3ee15248ae2..5e7f9ce8760 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -1992,7 +1992,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         self.var_debug_info.push(VarDebugInfo {
             name,
             source_info: debug_source_info,
-            place: for_arm_body.into(),
+            value: VarDebugInfoContents::Place(for_arm_body.into()),
         });
         let locals = if has_guard.0 {
             let ref_for_guard = self.local_decls.push(LocalDecl::<'tcx> {
@@ -2011,7 +2011,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             self.var_debug_info.push(VarDebugInfo {
                 name,
                 source_info: debug_source_info,
-                place: ref_for_guard.into(),
+                value: VarDebugInfoContents::Place(ref_for_guard.into()),
             });
             LocalsForNode::ForGuard { ref_for_guard, for_arm_body }
         } else {
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index c50389a850e..fc872da56bc 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -796,7 +796,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     self.var_debug_info.push(VarDebugInfo {
                         name: ident.name,
                         source_info,
-                        place: arg_local.into(),
+                        value: VarDebugInfoContents::Place(arg_local.into()),
                     });
                 }
             }
@@ -860,10 +860,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     self.var_debug_info.push(VarDebugInfo {
                         name,
                         source_info: SourceInfo::outermost(tcx_hir.span(var_id)),
-                        place: Place {
+                        value: VarDebugInfoContents::Place(Place {
                             local: closure_env_arg,
                             projection: tcx.intern_place_elems(&projs),
-                        },
+                        }),
                     });
 
                     mutability