From 3d69b5bc17e29348c36f76b400e70bccd007f491 Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wesleywiser@microsoft.com>
Date: Fri, 3 Sep 2021 18:43:09 -0400
Subject: [PATCH 1/4] Add tracing level for codegen_mir

---
 compiler/rustc_codegen_ssa/src/mir/mod.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index e2edd448267..a8ce39067f8 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -129,6 +129,7 @@ impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> {
 
 ///////////////////////////////////////////////////////////////////////////
 
+#[tracing::instrument(level = "debug", skip(cx))]
 pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     cx: &'a Bx::CodegenCx,
     instance: Instance<'tcx>,

From 7790af4d889f6238935b1da590cd113b658c53a8 Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wesleywiser@microsoft.com>
Date: Wed, 1 Sep 2021 16:31:35 -0400
Subject: [PATCH 2/4] Add test to show issue with ScalarPair parameters

---
 src/test/debuginfo/msvc-scalarpair-params.rs | 100 +++++++++++++++++++
 1 file changed, 100 insertions(+)
 create mode 100644 src/test/debuginfo/msvc-scalarpair-params.rs

diff --git a/src/test/debuginfo/msvc-scalarpair-params.rs b/src/test/debuginfo/msvc-scalarpair-params.rs
new file mode 100644
index 00000000000..7ebbf79d082
--- /dev/null
+++ b/src/test/debuginfo/msvc-scalarpair-params.rs
@@ -0,0 +1,100 @@
+// only-cdb
+// compile-flags: -g
+
+// cdb-command: g
+
+// cdb-command: dx r1
+// cdb-check:r1               : (0xa..0xc) [Type: core::ops::range::Range<u32>]
+// cdb-command: dx r2
+// cdb-check:r2               : 0x14 [Type: core::ops::range::Range<u64> *]
+
+// cdb-command: g
+
+// cdb-command: dx r1
+// cdb-check:r1               : (0x9..0x64) [Type: core::ops::range::Range<u32>]
+// cdb-command: dx r2
+// cdb-check:r2               : 0xc [Type: core::ops::range::Range<u64> *]
+
+// cdb-command: g
+
+// cdb-command: dx o1
+// cdb-check:o1               : Some [Type: enum$<core::option::Option<u32> >]
+// cdb-check:    [variant]        : Some
+// cdb-check:    [+0x004] __0              : 0x4d2 [Type: [...]]
+// cdb-command: dx o2
+// cdb-check:o2               : 0x1 [Type: enum$<core::option::Option<u64> > *]
+// cdb-check:    [variant]
+
+// cdb-command: g
+
+// cdb-command: dx t1
+// cdb-check:t1               : (0xa, 0x14) [Type: tuple$<u32,u32>]
+// cdb-check:    [0]              : 0xa [Type: unsigned int]
+// cdb-check:    [1]              : 0x14 [Type: unsigned int]
+// cdb-command: dx t2
+// cdb-check:t2               : 0x1e [Type: tuple$<u64,u64> *]
+// cdb-check:    [0]              : Unable to read memory at Address 0x1e
+// cdb-check:    [1]              : Unable to read memory at Address 0x26
+
+// cdb-command: g
+
+// cdb-command: dx s
+// cdb-check:s                : "this is a static str" [Type: str]
+// cdb-check:    [len]            : 0x14 [Type: unsigned __int64]
+// cdb-check:    [chars]
+
+// cdb-command: g
+
+// cdb-command: dx s
+// cdb-check:s                : { len=0x5 } [Type: slice$<u8>]
+// cdb-check:    [len]            : 0x5 [Type: unsigned __int64]
+// cdb-check:    [0]              : 0x1 [Type: unsigned char]
+// cdb-check:    [1]              : 0x2 [Type: unsigned char]
+// cdb-check:    [2]              : 0x3 [Type: unsigned char]
+// cdb-check:    [3]              : 0x4 [Type: unsigned char]
+// cdb-check:    [4]              : 0x5 [Type: unsigned char]
+
+use std::ops::Range;
+
+fn range(r1: Range<u32>, r2: Range<u64>) {
+    zzz(); // #break
+}
+
+fn range_mut(mut r1: Range<u32>, mut r2: Range<u64>) {
+    if r1.start == 9 {
+        r1.end = 100;
+    }
+
+    if r2.start == 12 {
+        r2.end = 90;
+    }
+
+    zzz(); // #break
+}
+
+fn option(o1: Option<u32>, o2: Option<u64>) {
+    zzz(); // #break
+}
+
+fn tuple(t1: (u32, u32), t2: (u64, u64)) {
+    zzz(); // #break
+}
+
+fn str(s: &str) {
+    zzz(); // #break
+}
+
+fn slice(s: &[u8]) {
+    zzz(); // #break
+}
+
+fn zzz() { }
+
+fn main() {
+    range(10..12, 20..30);
+    range_mut(9..20, 12..80);
+    option(Some(1234), Some(5678));
+    tuple((10, 20), (30, 40));
+    str("this is a static str");
+    slice(&[1, 2, 3, 4, 5]);
+}

From 4e8701e6200d114d9576f8cdf9721b0a81de0118 Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wesleywiser@microsoft.com>
Date: Wed, 1 Sep 2021 15:56:32 -0400
Subject: [PATCH 3/4] Fix debuginfo for ScalarPair abi parameters

Mark all of these as locals so the debugger does not try to interpret
them as being a pointer to the value. This extends the approach used in
PR #81898.
---
 .../rustc_codegen_ssa/src/mir/debuginfo.rs    | 25 ++++++++-----------
 src/test/debuginfo/msvc-scalarpair-params.rs  | 19 +++++++-------
 2 files changed, 20 insertions(+), 24 deletions(-)

diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index c139f915e6c..c710fcc2c1d 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -3,9 +3,11 @@ use rustc_index::vec::IndexVec;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir;
 use rustc_middle::ty;
+use rustc_middle::ty::layout::LayoutOf;
 use rustc_session::config::DebugInfo;
 use rustc_span::symbol::{kw, Symbol};
 use rustc_span::{BytePos, Span};
+use rustc_target::abi::Abi;
 use rustc_target::abi::Size;
 
 use super::operand::{OperandRef, OperandValue};
@@ -368,21 +370,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         {
                             let arg_index = place.local.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),
+                                // ScalarPair parameters are spilled to the stack so they need to
+                                // be marked as a `LocalVariable` for MSVC debuggers to visualize
+                                // their data correctly. (See #81894 & #88625)
+                                let var_ty_layout = self.cx.layout_of(var_ty);
+                                if let Abi::ScalarPair(_, _) = var_ty_layout.abi {
+                                    VariableKind::LocalVariable
+                                } else {
+                                    VariableKind::ArgumentVariable(arg_index + 1)
                                 }
                             } else {
                                 // FIXME(eddyb) shouldn't `ArgumentVariable` indices be
diff --git a/src/test/debuginfo/msvc-scalarpair-params.rs b/src/test/debuginfo/msvc-scalarpair-params.rs
index 7ebbf79d082..3846fb42f81 100644
--- a/src/test/debuginfo/msvc-scalarpair-params.rs
+++ b/src/test/debuginfo/msvc-scalarpair-params.rs
@@ -6,14 +6,14 @@
 // cdb-command: dx r1
 // cdb-check:r1               : (0xa..0xc) [Type: core::ops::range::Range<u32>]
 // cdb-command: dx r2
-// cdb-check:r2               : 0x14 [Type: core::ops::range::Range<u64> *]
+// cdb-check:r2               : (0x14..0x1e) [Type: core::ops::range::Range<u64>]
 
 // cdb-command: g
 
 // cdb-command: dx r1
 // cdb-check:r1               : (0x9..0x64) [Type: core::ops::range::Range<u32>]
 // cdb-command: dx r2
-// cdb-check:r2               : 0xc [Type: core::ops::range::Range<u64> *]
+// cdb-check:r2               : (0xc..0x5a) [Type: core::ops::range::Range<u64>]
 
 // cdb-command: g
 
@@ -22,8 +22,9 @@
 // cdb-check:    [variant]        : Some
 // cdb-check:    [+0x004] __0              : 0x4d2 [Type: [...]]
 // cdb-command: dx o2
-// cdb-check:o2               : 0x1 [Type: enum$<core::option::Option<u64> > *]
-// cdb-check:    [variant]
+// cdb-check:o2               : Some [Type: enum$<core::option::Option<u64> >]
+// cdb-check:    [variant]        : Some
+// cdb-check:    [+0x008] __0              : 0x162e [Type: unsigned __int64]
 
 // cdb-command: g
 
@@ -32,22 +33,22 @@
 // cdb-check:    [0]              : 0xa [Type: unsigned int]
 // cdb-check:    [1]              : 0x14 [Type: unsigned int]
 // cdb-command: dx t2
-// cdb-check:t2               : 0x1e [Type: tuple$<u64,u64> *]
-// cdb-check:    [0]              : Unable to read memory at Address 0x1e
-// cdb-check:    [1]              : Unable to read memory at Address 0x26
+// cdb-check:t2               : (0x1e, 0x28) [Type: tuple$<u64,u64>]
+// cdb-check:    [0]              : 0x1e [Type: unsigned __int64]
+// cdb-check:    [1]              : 0x28 [Type: unsigned __int64]
 
 // cdb-command: g
 
 // cdb-command: dx s
 // cdb-check:s                : "this is a static str" [Type: str]
-// cdb-check:    [len]            : 0x14 [Type: unsigned __int64]
+// cdb-check:    [len]            : 0x14 [Type: unsigned [...]]
 // cdb-check:    [chars]
 
 // cdb-command: g
 
 // cdb-command: dx s
 // cdb-check:s                : { len=0x5 } [Type: slice$<u8>]
-// cdb-check:    [len]            : 0x5 [Type: unsigned __int64]
+// cdb-check:    [len]            : 0x5 [Type: unsigned [...]]
 // cdb-check:    [0]              : 0x1 [Type: unsigned char]
 // cdb-check:    [1]              : 0x2 [Type: unsigned char]
 // cdb-check:    [2]              : 0x3 [Type: unsigned char]

From a6c642a9f861c504a63ae0a624b3cb559eee0051 Mon Sep 17 00:00:00 2001
From: Oli Scherer <github35764891676564198441@oli-obk.de>
Date: Sat, 4 Sep 2021 10:14:12 +0200
Subject: [PATCH 4/4] Update compiler/rustc_codegen_ssa/src/mir/mod.rs

---
 compiler/rustc_codegen_ssa/src/mir/mod.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index a8ce39067f8..0877345938a 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -129,7 +129,7 @@ impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> {
 
 ///////////////////////////////////////////////////////////////////////////
 
-#[tracing::instrument(level = "debug", skip(cx))]
+#[instrument(level = "debug", skip(cx))]
 pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     cx: &'a Bx::CodegenCx,
     instance: Instance<'tcx>,