diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index e05646e1e86..8647fbace2a 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -59,7 +59,13 @@ fn push_debuginfo_type_name<'tcx>(
     match *t.kind() {
         ty::Bool => output.push_str("bool"),
         ty::Char => output.push_str("char"),
-        ty::Str => output.push_str("str"),
+        ty::Str => {
+            if cpp_like_debuginfo {
+                output.push_str("str$")
+            } else {
+                output.push_str("str")
+            }
+        }
         ty::Never => {
             if cpp_like_debuginfo {
                 output.push_str("never$");
@@ -152,25 +158,19 @@ fn push_debuginfo_type_name<'tcx>(
             }
         }
         ty::Ref(_, inner_type, mutbl) => {
-            // Slices and `&str` are treated like C++ pointers when computing debug
-            // info for MSVC debugger. However, wrapping these types' names in a synthetic type
-            // causes the .natvis engine for WinDbg to fail to display their data, so we opt these
-            // types out to aid debugging in MSVC.
-            let is_slice_or_str = matches!(*inner_type.kind(), ty::Slice(_) | ty::Str);
-
-            if !cpp_like_debuginfo {
-                output.push('&');
-                output.push_str(mutbl.prefix_str());
-            } else if !is_slice_or_str {
+            if cpp_like_debuginfo {
                 match mutbl {
                     Mutability::Not => output.push_str("ref$<"),
                     Mutability::Mut => output.push_str("ref_mut$<"),
                 }
+            } else {
+                output.push('&');
+                output.push_str(mutbl.prefix_str());
             }
 
             push_debuginfo_type_name(tcx, inner_type, qualified, output, visited);
 
-            if cpp_like_debuginfo && !is_slice_or_str {
+            if cpp_like_debuginfo {
                 push_close_angle_bracket(cpp_like_debuginfo, output);
             }
         }
@@ -195,7 +195,7 @@ fn push_debuginfo_type_name<'tcx>(
         }
         ty::Slice(inner_type) => {
             if cpp_like_debuginfo {
-                output.push_str("slice$<");
+                output.push_str("slice2$<");
             } else {
                 output.push('[');
             }
diff --git a/src/etc/natvis/intrinsic.natvis b/src/etc/natvis/intrinsic.natvis
index 277e57aaf6f..8c16a562e34 100644
--- a/src/etc/natvis/intrinsic.natvis
+++ b/src/etc/natvis/intrinsic.natvis
@@ -1,6 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
-  <Type Name="str">
+  <Type Name="ref$&lt;str$&gt;">
+    <AlternativeType Name="ref_mut$&lt;str$&gt;" />
+    <AlternativeType Name="ptr_const$&lt;str$&gt;" />
+    <AlternativeType Name="ptr_mut$&lt;str$&gt;" />
+
     <DisplayString>{(char*)data_ptr,[length]s8}</DisplayString>
     <StringView>(char*)data_ptr,[length]s8</StringView>
     <Expand>
@@ -15,7 +19,11 @@
       </Synthetic>
     </Expand>
   </Type>
-  <Type Name="slice$&lt;*&gt;">
+  <Type Name="ref$&lt;slice2$&lt;*&gt; &gt;">
+    <AlternativeType Name="ref_mut$&lt;slice2$&lt;*&gt; &gt;" />
+    <AlternativeType Name="ptr_const$&lt;slice2$&lt;*&gt; &gt;" />
+    <AlternativeType Name="ptr_mut$&lt;slice2$&lt;*&gt; &gt;" />
+
     <DisplayString>{{ len={length} }}</DisplayString>
     <Expand>
       <Item Name="[len]" ExcludeView="simple">length</Item>
diff --git a/src/etc/natvis/liballoc.natvis b/src/etc/natvis/liballoc.natvis
index bf6c02b9146..41f4a3767f5 100644
--- a/src/etc/natvis/liballoc.natvis
+++ b/src/etc/natvis/liballoc.natvis
@@ -85,7 +85,7 @@
   </Type>
 
   <!-- alloc::rc::Rc<[T]> -->
-  <Type Name="alloc::rc::Rc&lt;slice$&lt;*&gt; &gt;">
+  <Type Name="alloc::rc::Rc&lt;slice2$&lt;*&gt; &gt;">
     <DisplayString>{{ len={ptr.pointer.length} }}</DisplayString>
     <Expand>
       <Item Name="[Length]" ExcludeView="simple">ptr.pointer.length</Item>
@@ -115,7 +115,7 @@
   </Type>
 
   <!-- alloc::rc::Weak<[T]> -->
-  <Type Name="alloc::rc::Weak&lt;slice$&lt;*&gt; &gt;">
+  <Type Name="alloc::rc::Weak&lt;slice2$&lt;*&gt; &gt;">
     <DisplayString>{{ len={ptr.pointer.length} }}</DisplayString>
     <Expand>
       <Item Name="[Length]" ExcludeView="simple">ptr.pointer.length</Item>
@@ -144,7 +144,7 @@
   </Type>
 
   <!-- alloc::sync::Arc<[T]> -->
-  <Type Name="alloc::sync::Arc&lt;slice$&lt;*&gt; &gt;">
+  <Type Name="alloc::sync::Arc&lt;slice2$&lt;*&gt; &gt;">
     <DisplayString>{{ len={ptr.pointer.length} }}</DisplayString>
     <Expand>
       <Item Name="[Length]" ExcludeView="simple">ptr.pointer.length</Item>
@@ -173,7 +173,7 @@
   </Type>
 
   <!-- alloc::sync::Weak<[T]> -->
-  <Type Name="alloc::sync::Weak&lt;slice$&lt;*&gt; &gt;">
+  <Type Name="alloc::sync::Weak&lt;slice2$&lt;*&gt; &gt;">
     <DisplayString>{{ len={ptr.pointer.length} }}</DisplayString>
     <Expand>
       <Item Name="[Length]" ExcludeView="simple">ptr.pointer.length</Item>
diff --git a/src/test/debuginfo/basic-types.rs b/src/test/debuginfo/basic-types.rs
index 07d33be2a07..9e82f071469 100644
--- a/src/test/debuginfo/basic-types.rs
+++ b/src/test/debuginfo/basic-types.rs
@@ -47,7 +47,6 @@
 // gdbg-check:$15 = {data_ptr = [...] "Hello, World!", length = 13}
 // gdbr-check:$15 = "Hello, World!"
 
-
 // === LLDB TESTS ==================================================================================
 
 // lldb-command:run
@@ -96,7 +95,6 @@
 // lldbg-check:[...]$12 = 3.5
 // lldbr-check:(f64) f64 = 3.5
 
-
 // === CDB TESTS ===================================================================================
 
 // cdb-command:g
@@ -131,7 +129,7 @@
 // cdb-command:.enable_unicode 1
 // FIXME(#88840): The latest version of the Windows SDK broke the visualizer for str.
 // cdb-command:dx  s
-// cdb-check:s                : [...] [Type: str]
+// cdb-check:s                : [...] [Type: ref$<str$>]
 
 #![allow(unused_variables)]
 #![feature(omit_gdb_pretty_printer_section)]
@@ -156,4 +154,6 @@ fn main() {
     _zzz(); // #break
 }
 
-fn _zzz() {()}
+fn _zzz() {
+    ()
+}
diff --git a/src/test/debuginfo/msvc-pretty-enums.rs b/src/test/debuginfo/msvc-pretty-enums.rs
index 7f1be6f2784..d66e4c660f7 100644
--- a/src/test/debuginfo/msvc-pretty-enums.rs
+++ b/src/test/debuginfo/msvc-pretty-enums.rs
@@ -116,13 +116,13 @@
 // cdb-check: niche_w_fields_3_niche5,d : F [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
 
 // cdb-command: dx -r3 niche_w_fields_std_result_ok,d
-// cdb-check: niche_w_fields_std_result_ok,d : Ok [Type: enum2$<core::result::Result<alloc::boxed::Box<slice$<u8>,alloc::alloc::Global>,u64> >]
-// cdb-check:    [+0x[...]] __0              [Type: alloc::boxed::Box<slice$<u8>,alloc::alloc::Global>]
+// cdb-check: niche_w_fields_std_result_ok,d : Ok [Type: enum2$<core::result::Result<alloc::boxed::Box<slice2$<u8>,alloc::alloc::Global>,u64> >]
+// cdb-check:    [+0x[...]] __0              [Type: alloc::boxed::Box<slice2$<u8>,alloc::alloc::Global>]
 // cdb-check:        [+0x[...]] data_ptr         : [...]
 // cdb-check:        [+0x[...]] length           : 3 [...]
 
 // cdb-command: dx -r3 niche_w_fields_std_result_err,d
-// cdb-check: niche_w_fields_std_result_err,d : Err [Type: enum2$<core::result::Result<alloc::boxed::Box<slice$<u8>,alloc::alloc::Global>,u64> >]
+// cdb-check: niche_w_fields_std_result_err,d : Err [Type: enum2$<core::result::Result<alloc::boxed::Box<slice2$<u8>,alloc::alloc::Global>,u64> >]
 // cdb-check:    [+0x[...]] __0              : 789 [Type: unsigned __int64]
 
 // cdb-command: dx -r2 arbitrary_discr1,d
diff --git a/src/test/debuginfo/msvc-scalarpair-params.rs b/src/test/debuginfo/msvc-scalarpair-params.rs
index 9630952cbaa..ae67f698151 100644
--- a/src/test/debuginfo/msvc-scalarpair-params.rs
+++ b/src/test/debuginfo/msvc-scalarpair-params.rs
@@ -38,14 +38,14 @@
 // cdb-command: g
 
 // cdb-command: dx s
-// cdb-check:s                : "this is a static str" [Type: str]
+// cdb-check:s                : "this is a static str" [Type: ref$<str$>]
 // 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:s                : { len=0x5 } [Type: ref$<slice2$<u8> >]
 // cdb-check:    [len]            : 0x5 [Type: unsigned [...]]
 // cdb-check:    [0]              : 0x1 [Type: unsigned char]
 // cdb-check:    [1]              : 0x2 [Type: unsigned char]
diff --git a/src/test/debuginfo/pretty-std.rs b/src/test/debuginfo/pretty-std.rs
index a51b37205e8..d8c6344e0b6 100644
--- a/src/test/debuginfo/pretty-std.rs
+++ b/src/test/debuginfo/pretty-std.rs
@@ -69,7 +69,7 @@
 // cdb-command: g
 
 // cdb-command: dx slice,d
-// cdb-check:slice,d          : { len=4 } [Type: slice$<i32>]
+// cdb-check:slice,d          : { len=4 } [Type: ref$<slice2$<i32> >]
 // cdb-check:    [len]            : 4 [Type: [...]]
 // cdb-check:    [0]              : 0 [Type: int]
 // cdb-check:    [1]              : 1 [Type: int]
@@ -86,7 +86,7 @@
 // cdb-check:    [3]              : 7 [Type: unsigned __int64]
 
 // cdb-command: dx str_slice
-// cdb-check:str_slice        : "IAMA string slice!" [Type: str]
+// cdb-check:str_slice        : "IAMA string slice!" [Type: ref$<str$>]
 
 // cdb-command: dx string
 // cdb-check:string           : "IAMA string!" [Type: [...]::String]
diff --git a/src/test/debuginfo/rc_arc.rs b/src/test/debuginfo/rc_arc.rs
index c05c565d956..5d5492d7217 100644
--- a/src/test/debuginfo/rc_arc.rs
+++ b/src/test/debuginfo/rc_arc.rs
@@ -57,7 +57,7 @@
 // cdb-check:    [Weak reference count] : 2 [Type: core::cell::Cell<usize>]
 
 // cdb-command:dx slice_rc,d
-// cdb-check:slice_rc,d       : { len=3 } [Type: alloc::rc::Rc<slice$<u32> >]
+// cdb-check:slice_rc,d       : { len=3 } [Type: alloc::rc::Rc<slice2$<u32> >]
 // cdb-check:    [Length]         : 3 [Type: [...]]
 // cdb-check:    [Reference count] : 41 [Type: core::cell::Cell<usize>]
 // cdb-check:    [Weak reference count] : 2 [Type: core::cell::Cell<usize>]
@@ -66,7 +66,7 @@
 // cdb-check:    [2]              : 3 [Type: u32]
 
 // cdb-command:dx slice_rc_weak,d
-// cdb-check:slice_rc_weak,d  : { len=3 } [Type: alloc::rc::Weak<slice$<u32> >]
+// cdb-check:slice_rc_weak,d  : { len=3 } [Type: alloc::rc::Weak<slice2$<u32> >]
 // cdb-check:    [Length]         : 3 [Type: [...]]
 // cdb-check:    [Reference count] : 41 [Type: core::cell::Cell<usize>]
 // cdb-check:    [Weak reference count] : 2 [Type: core::cell::Cell<usize>]
@@ -85,7 +85,7 @@
 // cdb-check:    [Weak reference count] : 2 [Type: core::sync::atomic::AtomicUsize]
 
 // cdb-command:dx slice_arc,d
-// cdb-check:slice_arc,d      : { len=3 } [Type: alloc::sync::Arc<slice$<u32> >]
+// cdb-check:slice_arc,d      : { len=3 } [Type: alloc::sync::Arc<slice2$<u32> >]
 // cdb-check:    [Length]         : 3 [Type: [...]]
 // cdb-check:    [Reference count] : 61 [Type: core::sync::atomic::AtomicUsize]
 // cdb-check:    [Weak reference count] : 2 [Type: core::sync::atomic::AtomicUsize]
@@ -94,7 +94,7 @@
 // cdb-check:    [2]              : 6 [Type: u32]
 
 // cdb-command:dx slice_arc_weak,d
-// cdb-check:slice_arc_weak,d : { len=3 } [Type: alloc::sync::Weak<slice$<u32> >]
+// cdb-check:slice_arc_weak,d : { len=3 } [Type: alloc::sync::Weak<slice2$<u32> >]
 // cdb-check:    [Length]         : 3 [Type: [...]]
 // cdb-check:    [Reference count] : 61 [Type: core::sync::atomic::AtomicUsize]
 // cdb-check:    [Weak reference count] : 2 [Type: core::sync::atomic::AtomicUsize]
diff --git a/src/test/debuginfo/result-types.rs b/src/test/debuginfo/result-types.rs
index cdac47a784d..f1944fa38d2 100644
--- a/src/test/debuginfo/result-types.rs
+++ b/src/test/debuginfo/result-types.rs
@@ -7,12 +7,12 @@
 // cdb-command: g
 
 // cdb-command: dx x,d
-// cdb-check:x,d              : Ok [Type: enum2$<core::result::Result<i32,str> >]
+// cdb-check:x,d              : Ok [Type: enum2$<core::result::Result<i32,ref$<str$> > >]
 // cdb-check:    [...] __0              : -3 [Type: int]
 
 // cdb-command: dx y
-// cdb-check:y                : Err [Type: enum2$<core::result::Result<i32,str> >]
-// cdb-check:    [...] __0              : "Some error message" [Type: str]
+// cdb-check:y                : Err [Type: enum2$<core::result::Result<i32,ref$<str$> > >]
+// cdb-check:    [...] __0              : "Some error message" [Type: ref$<str$>]
 
 fn main() {
     let x: Result<i32, &str> = Ok(-3);
diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs
index 9cc99d7767c..d7b79a845d2 100644
--- a/src/test/debuginfo/type-names.rs
+++ b/src/test/debuginfo/type-names.rs
@@ -95,7 +95,7 @@
 // gdb-check:type = &[usize]
 
 // gdb-command:whatis slice2
-// gdb-check:type = &[type_names::mod1::Enum2]
+// gdb-check:type = &mut [type_names::mod1::Enum2]
 
 // TRAITS
 // gdb-command:whatis box_trait
@@ -218,8 +218,8 @@
 // cdb-check:struct alloc::vec::Vec<usize,alloc::alloc::Global> vec1 = [...]
 // cdb-check:struct alloc::vec::Vec<enum2$<type_names::mod1::Enum2>,alloc::alloc::Global> vec2 = [...]
 // cdb-command:dv /t slice*
-// cdb-check:struct slice$<usize> slice1 = [...]
-// cdb-check:struct slice$<enum2$<type_names::mod1::Enum2> > slice2 = [...]
+// cdb-check:struct ref$<slice2$<usize> > slice1 = [...]
+// cdb-check:struct ref_mut$<slice2$<enum2$<type_names::mod1::Enum2> > > slice2 = [...]
 
 // TRAITS
 // cdb-command:dv /t *_trait
@@ -417,8 +417,8 @@ fn main() {
 
     let vec1 = vec![0_usize, 2, 3];
     let slice1 = &*vec1;
-    let vec2 = vec![mod1::Enum2::Variant2(Struct1)];
-    let slice2 = &*vec2;
+    let mut vec2 = vec![mod1::Enum2::Variant2(Struct1)];
+    let slice2 = &mut *vec2;
 
     // Trait Objects
     let box_trait = Box::new(0_isize) as Box<dyn Trait1>;
diff --git a/src/test/debuginfo/unsized.rs b/src/test/debuginfo/unsized.rs
index 7cb0002ca51..b1ec9b06830 100644
--- a/src/test/debuginfo/unsized.rs
+++ b/src/test/debuginfo/unsized.rs
@@ -32,13 +32,13 @@
 
 // cdb-command: g
 // cdb-command:dx a
-// cdb-check:a                [Type: ref$<unsized::Foo<slice$<u8> > >]
-// cdb-check:    [+0x000] data_ptr         : 0x[...] [Type: unsized::Foo<slice$<u8> > *]
+// cdb-check:a                [Type: ref$<unsized::Foo<slice2$<u8> > >]
+// cdb-check:    [+0x000] data_ptr         : 0x[...] [Type: unsized::Foo<slice2$<u8> > *]
 // cdb-check:    [...] length           : 0x4 [Type: unsigned [...]int[...]
 
 // cdb-command:dx b
-// cdb-check:b                [Type: ref$<unsized::Foo<unsized::Foo<slice$<u8> > > >]
-// cdb-check:    [+0x000] data_ptr         : 0x[...] [Type: unsized::Foo<unsized::Foo<slice$<u8> > > *]
+// cdb-check:b                [Type: ref$<unsized::Foo<unsized::Foo<slice2$<u8> > > >]
+// cdb-check:    [+0x000] data_ptr         : 0x[...] [Type: unsized::Foo<unsized::Foo<slice2$<u8> > > *]
 // cdb-check:    [...] length           : 0x4 [Type: unsigned [...]int[...]
 
 // cdb-command:dx c
@@ -53,8 +53,8 @@
 // cdb-check:[...] vtable           : 0x[...] [Type: unsigned [...]int[...] (*)[3]]
 
 // cdb-command:dx tuple_slice
-// cdb-check:tuple_slice      [Type: ref$<tuple$<i32,i32,slice$<i32> > >]
-// cdb-check:    [+0x000] data_ptr         : 0x[...] [Type: tuple$<i32,i32,slice$<i32> > *]
+// cdb-check:tuple_slice      [Type: ref$<tuple$<i32,i32,slice2$<i32> > >]
+// cdb-check:    [+0x000] data_ptr         : 0x[...] [Type: tuple$<i32,i32,slice2$<i32> > *]
 // cdb-check:    [...] length           : 0x2 [Type: unsigned [...]int[...]
 
 // cdb-command:dx tuple_dyn