about summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa/src/mir
diff options
context:
space:
mode:
authorNam Nguyen <nanguye@microsoft.com>2021-02-08 11:52:59 -0800
committerNam Nguyen <nanguye@microsoft.com>2021-02-09 15:59:28 -0800
commit615fd141bde1e4319f95c3ea2981a1f5a8aa5dbd (patch)
tree27acf6281373a4326f538772c90976d153fd921e /compiler/rustc_codegen_ssa/src/mir
parent921ec4b3fca17cc777766c240038d7d50ba98e0d (diff)
downloadrust-615fd141bde1e4319f95c3ea2981a1f5a8aa5dbd.tar.gz
rust-615fd141bde1e4319f95c3ea2981a1f5a8aa5dbd.zip
Set the kind for local variables created by &str and slice arguments to LocalVariable
Diffstat (limited to 'compiler/rustc_codegen_ssa/src/mir')
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs30
1 files changed, 25 insertions, 5 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index f1eae605da0..ea59e183118 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -320,6 +320,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     ) -> Option<IndexVec<mir::Local, Vec<PerLocalVarDebugInfo<'tcx, Bx::DIVariable>>>> {
         let full_debug_info = self.cx.sess().opts.debuginfo == DebugInfo::Full;
 
+        let target_is_msvc = self.cx.sess().target.is_like_msvc;
+
         if !full_debug_info && self.cx.sess().fewer_names() {
             return None;
         }
@@ -341,11 +343,29 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             && 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)
+                            if target_is_msvc {
+                                // Rust compiler decomposes every &str or slice argument into two components:
+                                // a pointer to the memory address where the data is stored and a usize representing
+                                // the length of the str (or slice). These components will later be used to reconstruct
+                                // the original argument inside the body of the function that owns it (see the
+                                // definition of debug_introduce_local for more details).
+                                //
+                                // Since the original argument is declared inside a function rather than being passed
+                                // in as an argument, it must be marked as a LocalVariable for MSVC debuggers to visualize
+                                // its data correctly. (See issue #81894 for an in-depth description of the problem).
+                                match *var_ty.kind() {
+                                    ty::Ref(_, inner_type, _) => match *inner_type.kind() {
+                                        ty::Slice(_) | ty::Str => VariableKind::LocalVariable,
+                                        _ => VariableKind::ArgumentVariable(arg_index + 1),
+                                    },
+                                    _ => VariableKind::ArgumentVariable(arg_index + 1),
+                                }
+                            } else {
+                                // 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
                         };