about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-15 12:59:53 +0000
committerbors <bors@rust-lang.org>2022-08-15 12:59:53 +0000
commit4916e2b9e6ef8cee6f9c6abb75bd01ba9dc07e5c (patch)
tree7115ce81f5279dae264956cac3d4be4dcedc1c18 /src
parent6ce76091c7cef21692a15dce1f0a4c415d245be4 (diff)
parent03b93d008d16132dc644d811bef9e452c515ed75 (diff)
downloadrust-4916e2b9e6ef8cee6f9c6abb75bd01ba9dc07e5c.tar.gz
rust-4916e2b9e6ef8cee6f9c6abb75bd01ba9dc07e5c.zip
Auto merge of #98393 - michaelwoerister:new-cpp-like-enum-debuginfo, r=wesleywiser
debuginfo: Generalize C++-like encoding for enums.

The updated encoding should be able to handle niche layouts where more than one variant has fields (as introduced in https://github.com/rust-lang/rust/pull/94075).

The new encoding is more uniform as there is no structural difference between direct-tag, niche-tag, and no-tag layouts anymore. The only difference between those cases is that the "dataful" variant in a niche-tag enum will have a `(start, end)` pair denoting the tag range instead of a single value.

The new encoding now also supports 128-bit tags, which occur in at least some standard library types. These tags are represented as `u64` pairs so that debuggers (which don't always have support for 128-bit integers) can reliably deal with them. The downside is that this adds quite a bit of complexity to the encoding and especially to the corresponding NatVis.

The new encoding seems to increase the size of (x86_64-pc-windows-msvc) debuginfo by 10-15%. The size of binaries is not affected (release builds were built with `-Cdebuginfo=2`, numbers are in kilobytes):

EXE | before | after | relative
-- | -- | -- | --
cargo (debug) | 40453 | 40450 | +0%
ripgrep (debug) | 10275 | 10273 | +0%
cargo (release) | 16186 | 16185 | +0%
ripgrep (release) | 4727 | 4726 | +0%

PDB | before | after | relative
-- | -- | -- | --
cargo (debug) | 236524 | 261412 | +11%
ripgrep (debug) | 53140 | 59060 | +11%
cargo (release) | 148516 | 169620 | +14%
ripgrep (release) | 10676 | 11804 | +11%

Given that the new encoding is more general, this is to be expected. Only platforms using C++-like debuginfo are affected -- which currently is only `*-pc-windows-msvc`.

*TODO*
- [x] Properly update documentation
- [x] Add regression tests for new optimized enum layouts as introduced by #94075.

r? `@wesleywiser`
Diffstat (limited to 'src')
-rw-r--r--src/etc/natvis/intrinsic.natvis249
-rw-r--r--src/etc/natvis/liballoc.natvis8
-rw-r--r--src/test/codegen/async-fn-debug-awaitee-field.rs4
-rw-r--r--src/test/codegen/async-fn-debug-msvc.rs7
-rw-r--r--src/test/codegen/debug-vtable.rs2
-rw-r--r--src/test/codegen/generator-debug-msvc.rs8
-rw-r--r--src/test/debuginfo/generator-objects.rs13
-rw-r--r--src/test/debuginfo/msvc-pretty-enums.rs212
-rw-r--r--src/test/debuginfo/msvc-scalarpair-params.rs8
-rw-r--r--src/test/debuginfo/mutex.rs15
-rw-r--r--src/test/debuginfo/pretty-std.rs22
-rw-r--r--src/test/debuginfo/result-types.rs11
-rw-r--r--src/test/debuginfo/type-names.rs34
-rw-r--r--src/tools/compiletest/src/main.rs2
14 files changed, 421 insertions, 174 deletions
diff --git a/src/etc/natvis/intrinsic.natvis b/src/etc/natvis/intrinsic.natvis
index 558536fa613..277e57aaf6f 100644
--- a/src/etc/natvis/intrinsic.natvis
+++ b/src/etc/natvis/intrinsic.natvis
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
   <Type Name="str">
     <DisplayString>{(char*)data_ptr,[length]s8}</DisplayString>
@@ -150,76 +150,189 @@
     </Expand>
   </Type>
 
-  <!-- Directly tagged enums. $T1 is the type name -->
-  <Type Name="enum$&lt;*&gt;">
-    <Intrinsic Name="tag" Expression="discriminant" />
-    <DisplayString Condition="tag() == 0">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 1" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 2" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 3" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 4" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 5" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 6" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 7" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 8" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 9" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 10" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 11" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 12" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 13" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 14" Optional="true">{tag(),en}</DisplayString>
-    <DisplayString Condition="tag() == 15" Optional="true">{tag(),en}</DisplayString>
+  <!--
+    This is the visualizer for all enums. It takes care of selecting the active variant.
+    See `compiler\rustc_codegen_llvm\src\debuginfo\metadata\enums\cpp_like.rs` for more information.
+  -->
+  <Type Name="enum2$&lt;*&gt;">
+    <!-- NOTE: That tag ranges can wrap around, in which case `end` is less than `begin` and we
+               have to do a different check -->
+    <Intrinsic Name="in_range" Expression="(begin &lt;= end) ? ((x &gt;= begin) &amp;&amp; (x &lt;= end)) : ((x &gt;= begin) || (x &lt;= end))">
+      <Parameter Name="x" Type="unsigned __int64" />
+      <Parameter Name="begin" Type="unsigned __int64" />
+      <Parameter Name="end" Type="unsigned __int64" />
+    </Intrinsic>
 
-    <Expand>
-      <Synthetic Name="[variant]">
-        <DisplayString>{tag(),en}</DisplayString>
-      </Synthetic>
-      <ExpandedItem Condition="tag() == 0">variant0</ExpandedItem>
-      <ExpandedItem Condition="tag() == 1" Optional="true">variant1</ExpandedItem>
-      <ExpandedItem Condition="tag() == 2" Optional="true">variant2</ExpandedItem>
-      <ExpandedItem Condition="tag() == 3" Optional="true">variant3</ExpandedItem>
-      <ExpandedItem Condition="tag() == 4" Optional="true">variant4</ExpandedItem>
-      <ExpandedItem Condition="tag() == 5" Optional="true">variant5</ExpandedItem>
-      <ExpandedItem Condition="tag() == 6" Optional="true">variant6</ExpandedItem>
-      <ExpandedItem Condition="tag() == 7" Optional="true">variant7</ExpandedItem>
-      <ExpandedItem Condition="tag() == 8" Optional="true">variant8</ExpandedItem>
-      <ExpandedItem Condition="tag() == 9" Optional="true">variant9</ExpandedItem>
-      <ExpandedItem Condition="tag() == 10" Optional="true">variant10</ExpandedItem>
-      <ExpandedItem Condition="tag() == 11" Optional="true">variant11</ExpandedItem>
-      <ExpandedItem Condition="tag() == 12" Optional="true">variant12</ExpandedItem>
-      <ExpandedItem Condition="tag() == 13" Optional="true">variant13</ExpandedItem>
-      <ExpandedItem Condition="tag() == 14" Optional="true">variant14</ExpandedItem>
-      <ExpandedItem Condition="tag() == 15" Optional="true">variant15</ExpandedItem>
-    </Expand>
-  </Type>
+    <Intrinsic Name="eq128" Expression="(x_hi == y_hi) &amp;&amp; (x_lo == y_lo)">
+      <Parameter Name="x_hi" Type="unsigned __int64" />
+      <Parameter Name="x_lo" Type="unsigned __int64" />
+      <Parameter Name="y_hi" Type="unsigned __int64" />
+      <Parameter Name="y_lo" Type="unsigned __int64" />
+    </Intrinsic>
 
-  <!-- Single variant enums. $T1 is the name of the enum, $T2 is the name of the variant -->
-  <Type Name="enum$&lt;*, *&gt;">
-    <DisplayString>{"$T2",sb}</DisplayString>
-    <Expand>
-      <Synthetic Name="[variant]">
-        <DisplayString>{"$T2",sb}</DisplayString>
-      </Synthetic>
-      <ExpandedItem>$T2</ExpandedItem>
-    </Expand>
-  </Type>
+    <Intrinsic Name="lt128" Expression="(x_hi &lt; y_hi) || ((x_hi == y_hi) &amp;&amp; (x_lo &lt; y_lo))">
+      <Parameter Name="x_hi" Type="unsigned __int64" />
+      <Parameter Name="x_lo" Type="unsigned __int64" />
+      <Parameter Name="y_hi" Type="unsigned __int64" />
+      <Parameter Name="y_lo" Type="unsigned __int64" />
+    </Intrinsic>
 
-  <!-- Niche-layout enums. $T1 is the name of the enum, $T2 is the low value of the dataful
-       variant tag, $T3 is the high value of the dataful variant tag, $T4 is the name of
-       the dataful variant -->
-  <Type Name="enum$&lt;*, *, *, *&gt;">
-    <Intrinsic Name="tag" Expression="discriminant" />
-    <Intrinsic Name="is_dataful" Expression="tag() &gt;= $T2 &amp;&amp; tag() &lt;= $T3" />
-    <DisplayString Condition="is_dataful()">{"$T4",sb}({dataful_variant})</DisplayString>
-    <DisplayString Condition="!is_dataful()">{discriminant,en}</DisplayString>
-    <Expand>
-      <ExpandedItem Condition="is_dataful()">dataful_variant</ExpandedItem>
-      <Synthetic Condition="is_dataful()" Name="[variant]">
-        <DisplayString>{"$T4",sb}</DisplayString>
-      </Synthetic>
-      <Synthetic Condition="!is_dataful()" Name="[variant]">
-        <DisplayString>{discriminant,en}</DisplayString>
-      </Synthetic>
+    <Intrinsic Name="lt_or_eq128" Expression="((x_hi == y_hi) &amp;&amp; (x_lo == y_lo)) || lt128(x_hi, x_lo, y_hi, y_lo)">
+      <Parameter Name="x_hi" Type="unsigned __int64" />
+      <Parameter Name="x_lo" Type="unsigned __int64" />
+      <Parameter Name="y_hi" Type="unsigned __int64" />
+      <Parameter Name="y_lo" Type="unsigned __int64" />
+    </Intrinsic>
+
+    <!-- NOTE: That tag ranges can wrap around, in which case `end` is less than `begin` and we
+               have to do a different check -->
+    <Intrinsic Name="in_range128" Expression="(lt_or_eq128(begin_hi, begin_lo, end_hi, end_lo)) ?
+                                              (lt_or_eq128(begin_hi, begin_lo, x_hi, x_lo) &amp;&amp; lt_or_eq128(x_hi, x_lo, end_hi, end_lo)) :
+                                              (lt_or_eq128(begin_hi, begin_lo, x_hi, x_lo) || lt_or_eq128(x_hi, x_lo, end_hi, end_lo))">
+      <Parameter Name="x_hi" Type="unsigned __int64" />
+      <Parameter Name="x_lo" Type="unsigned __int64" />
+      <Parameter Name="begin_hi" Type="unsigned __int64" />
+      <Parameter Name="begin_lo" Type="unsigned __int64" />
+      <Parameter Name="end_hi" Type="unsigned __int64" />
+      <Parameter Name="end_lo" Type="unsigned __int64" />
+    </Intrinsic>
+
+    <DisplayString Condition="tag == variant0.DISCR_EXACT" Optional="true">{variant0.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant1.DISCR_EXACT" Optional="true">{variant1.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant2.DISCR_EXACT" Optional="true">{variant2.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant3.DISCR_EXACT" Optional="true">{variant3.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant4.DISCR_EXACT" Optional="true">{variant4.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant5.DISCR_EXACT" Optional="true">{variant5.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant6.DISCR_EXACT" Optional="true">{variant6.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant7.DISCR_EXACT" Optional="true">{variant7.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant8.DISCR_EXACT" Optional="true">{variant8.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant9.DISCR_EXACT" Optional="true">{variant9.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant10.DISCR_EXACT" Optional="true">{variant10.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant11.DISCR_EXACT" Optional="true">{variant11.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant12.DISCR_EXACT" Optional="true">{variant12.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant13.DISCR_EXACT" Optional="true">{variant13.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant14.DISCR_EXACT" Optional="true">{variant14.NAME,en}</DisplayString>
+    <DisplayString Condition="tag == variant15.DISCR_EXACT" Optional="true">{variant15.NAME,en}</DisplayString>
+
+    <DisplayString Condition="in_range(tag, variant0.DISCR_BEGIN, variant0.DISCR_END)" Optional="true">{variant0.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant1.DISCR_BEGIN, variant1.DISCR_END)" Optional="true">{variant1.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant2.DISCR_BEGIN, variant2.DISCR_END)" Optional="true">{variant2.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant3.DISCR_BEGIN, variant3.DISCR_END)" Optional="true">{variant3.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant4.DISCR_BEGIN, variant4.DISCR_END)" Optional="true">{variant4.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant5.DISCR_BEGIN, variant5.DISCR_END)" Optional="true">{variant5.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant6.DISCR_BEGIN, variant6.DISCR_END)" Optional="true">{variant6.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant7.DISCR_BEGIN, variant7.DISCR_END)" Optional="true">{variant7.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant8.DISCR_BEGIN, variant8.DISCR_END)" Optional="true">{variant8.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant9.DISCR_BEGIN, variant9.DISCR_END)" Optional="true">{variant9.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant10.DISCR_BEGIN, variant10.DISCR_END)" Optional="true">{variant10.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant11.DISCR_BEGIN, variant11.DISCR_END)" Optional="true">{variant11.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant12.DISCR_BEGIN, variant12.DISCR_END)" Optional="true">{variant12.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant13.DISCR_BEGIN, variant13.DISCR_END)" Optional="true">{variant13.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant14.DISCR_BEGIN, variant14.DISCR_END)" Optional="true">{variant14.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range(tag, variant15.DISCR_BEGIN, variant15.DISCR_END)" Optional="true">{variant15.NAME,en}</DisplayString>
+
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant0.DISCR128_EXACT_HI, variant0.DISCR128_EXACT_LO)" Optional="true">{variant0.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant1.DISCR128_EXACT_HI, variant1.DISCR128_EXACT_LO)" Optional="true">{variant1.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant2.DISCR128_EXACT_HI, variant2.DISCR128_EXACT_LO)" Optional="true">{variant2.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant3.DISCR128_EXACT_HI, variant3.DISCR128_EXACT_LO)" Optional="true">{variant3.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant4.DISCR128_EXACT_HI, variant4.DISCR128_EXACT_LO)" Optional="true">{variant4.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant5.DISCR128_EXACT_HI, variant5.DISCR128_EXACT_LO)" Optional="true">{variant5.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant6.DISCR128_EXACT_HI, variant6.DISCR128_EXACT_LO)" Optional="true">{variant6.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant7.DISCR128_EXACT_HI, variant7.DISCR128_EXACT_LO)" Optional="true">{variant7.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant8.DISCR128_EXACT_HI, variant8.DISCR128_EXACT_LO)" Optional="true">{variant8.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant9.DISCR128_EXACT_HI, variant9.DISCR128_EXACT_LO)" Optional="true">{variant9.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant10.DISCR128_EXACT_HI, variant10.DISCR128_EXACT_LO)" Optional="true">{variant10.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant11.DISCR128_EXACT_HI, variant11.DISCR128_EXACT_LO)" Optional="true">{variant11.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant12.DISCR128_EXACT_HI, variant12.DISCR128_EXACT_LO)" Optional="true">{variant12.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant13.DISCR128_EXACT_HI, variant13.DISCR128_EXACT_LO)" Optional="true">{variant13.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant14.DISCR128_EXACT_HI, variant14.DISCR128_EXACT_LO)" Optional="true">{variant14.NAME,en}</DisplayString>
+    <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant15.DISCR128_EXACT_HI, variant15.DISCR128_EXACT_LO)" Optional="true">{variant15.NAME,en}</DisplayString>
+
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant0.DISCR128_BEGIN_HI, variant0.DISCR128_BEGIN_LO, variant0.DISCR128_END_HI, variant0.DISCR128_END_LO)" Optional="true">{variant0.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant1.DISCR128_BEGIN_HI, variant1.DISCR128_BEGIN_LO, variant1.DISCR128_END_HI, variant1.DISCR128_END_LO)" Optional="true">{variant1.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant2.DISCR128_BEGIN_HI, variant2.DISCR128_BEGIN_LO, variant2.DISCR128_END_HI, variant2.DISCR128_END_LO)" Optional="true">{variant2.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant3.DISCR128_BEGIN_HI, variant3.DISCR128_BEGIN_LO, variant3.DISCR128_END_HI, variant3.DISCR128_END_LO)" Optional="true">{variant3.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant4.DISCR128_BEGIN_HI, variant4.DISCR128_BEGIN_LO, variant4.DISCR128_END_HI, variant4.DISCR128_END_LO)" Optional="true">{variant4.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant5.DISCR128_BEGIN_HI, variant5.DISCR128_BEGIN_LO, variant5.DISCR128_END_HI, variant5.DISCR128_END_LO)" Optional="true">{variant5.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant6.DISCR128_BEGIN_HI, variant6.DISCR128_BEGIN_LO, variant6.DISCR128_END_HI, variant6.DISCR128_END_LO)" Optional="true">{variant6.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant7.DISCR128_BEGIN_HI, variant7.DISCR128_BEGIN_LO, variant7.DISCR128_END_HI, variant7.DISCR128_END_LO)" Optional="true">{variant7.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant8.DISCR128_BEGIN_HI, variant8.DISCR128_BEGIN_LO, variant8.DISCR128_END_HI, variant8.DISCR128_END_LO)" Optional="true">{variant8.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant9.DISCR128_BEGIN_HI, variant9.DISCR128_BEGIN_LO, variant9.DISCR128_END_HI, variant9.DISCR128_END_LO)" Optional="true">{variant9.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant10.DISCR128_BEGIN_HI, variant10.DISCR128_BEGIN_LO, variant10.DISCR128_END_HI, variant10.DISCR128_END_LO)" Optional="true">{variant10.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant11.DISCR128_BEGIN_HI, variant11.DISCR128_BEGIN_LO, variant11.DISCR128_END_HI, variant11.DISCR128_END_LO)" Optional="true">{variant11.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant12.DISCR128_BEGIN_HI, variant12.DISCR128_BEGIN_LO, variant12.DISCR128_END_HI, variant12.DISCR128_END_LO)" Optional="true">{variant12.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant13.DISCR128_BEGIN_HI, variant13.DISCR128_BEGIN_LO, variant13.DISCR128_END_HI, variant13.DISCR128_END_LO)" Optional="true">{variant13.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant14.DISCR128_BEGIN_HI, variant14.DISCR128_BEGIN_LO, variant14.DISCR128_END_HI, variant14.DISCR128_END_LO)" Optional="true">{variant14.NAME,en}</DisplayString>
+    <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant15.DISCR128_BEGIN_HI, variant15.DISCR128_BEGIN_LO, variant15.DISCR128_END_HI, variant15.DISCR128_END_LO)" Optional="true">{variant15.NAME,en}</DisplayString>
+
+    <Expand HideRawView="true">
+      <ExpandedItem Condition="tag == variant0.DISCR_EXACT" Optional="true">variant0.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant1.DISCR_EXACT" Optional="true">variant1.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant2.DISCR_EXACT" Optional="true">variant2.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant3.DISCR_EXACT" Optional="true">variant3.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant4.DISCR_EXACT" Optional="true">variant4.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant5.DISCR_EXACT" Optional="true">variant5.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant6.DISCR_EXACT" Optional="true">variant6.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant7.DISCR_EXACT" Optional="true">variant7.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant8.DISCR_EXACT" Optional="true">variant8.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant9.DISCR_EXACT" Optional="true">variant9.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant10.DISCR_EXACT" Optional="true">variant10.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant11.DISCR_EXACT" Optional="true">variant11.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant12.DISCR_EXACT" Optional="true">variant12.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant13.DISCR_EXACT" Optional="true">variant13.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant14.DISCR_EXACT" Optional="true">variant14.value</ExpandedItem>
+      <ExpandedItem Condition="tag == variant15.DISCR_EXACT" Optional="true">variant15.value</ExpandedItem>
+
+      <ExpandedItem Condition="in_range(tag, variant0.DISCR_BEGIN, variant0.DISCR_END)" Optional="true">variant0.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant1.DISCR_BEGIN, variant1.DISCR_END)" Optional="true">variant1.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant2.DISCR_BEGIN, variant2.DISCR_END)" Optional="true">variant2.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant3.DISCR_BEGIN, variant3.DISCR_END)" Optional="true">variant3.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant4.DISCR_BEGIN, variant4.DISCR_END)" Optional="true">variant4.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant5.DISCR_BEGIN, variant5.DISCR_END)" Optional="true">variant5.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant6.DISCR_BEGIN, variant6.DISCR_END)" Optional="true">variant6.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant7.DISCR_BEGIN, variant7.DISCR_END)" Optional="true">variant7.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant8.DISCR_BEGIN, variant8.DISCR_END)" Optional="true">variant8.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant9.DISCR_BEGIN, variant9.DISCR_END)" Optional="true">variant9.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant10.DISCR_BEGIN, variant10.DISCR_END)" Optional="true">variant10.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant11.DISCR_BEGIN, variant11.DISCR_END)" Optional="true">variant11.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant12.DISCR_BEGIN, variant12.DISCR_END)" Optional="true">variant12.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant13.DISCR_BEGIN, variant13.DISCR_END)" Optional="true">variant13.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant14.DISCR_BEGIN, variant14.DISCR_END)" Optional="true">variant14.value</ExpandedItem>
+      <ExpandedItem Condition="in_range(tag, variant15.DISCR_BEGIN, variant15.DISCR_END)" Optional="true">variant15.value</ExpandedItem>
+
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant0.DISCR128_EXACT_HI, variant0.DISCR128_EXACT_LO)" Optional="true">variant0.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant1.DISCR128_EXACT_HI, variant1.DISCR128_EXACT_LO)" Optional="true">variant1.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant2.DISCR128_EXACT_HI, variant2.DISCR128_EXACT_LO)" Optional="true">variant2.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant3.DISCR128_EXACT_HI, variant3.DISCR128_EXACT_LO)" Optional="true">variant3.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant4.DISCR128_EXACT_HI, variant4.DISCR128_EXACT_LO)" Optional="true">variant4.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant5.DISCR128_EXACT_HI, variant5.DISCR128_EXACT_LO)" Optional="true">variant5.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant6.DISCR128_EXACT_HI, variant6.DISCR128_EXACT_LO)" Optional="true">variant6.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant7.DISCR128_EXACT_HI, variant7.DISCR128_EXACT_LO)" Optional="true">variant7.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant8.DISCR128_EXACT_HI, variant8.DISCR128_EXACT_LO)" Optional="true">variant8.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant9.DISCR128_EXACT_HI, variant9.DISCR128_EXACT_LO)" Optional="true">variant9.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant10.DISCR128_EXACT_HI, variant10.DISCR128_EXACT_LO)" Optional="true">variant10.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant11.DISCR128_EXACT_HI, variant11.DISCR128_EXACT_LO)" Optional="true">variant11.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant12.DISCR128_EXACT_HI, variant12.DISCR128_EXACT_LO)" Optional="true">variant12.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant13.DISCR128_EXACT_HI, variant13.DISCR128_EXACT_LO)" Optional="true">variant13.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant14.DISCR128_EXACT_HI, variant14.DISCR128_EXACT_LO)" Optional="true">variant14.value</ExpandedItem>
+      <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant15.DISCR128_EXACT_HI, variant15.DISCR128_EXACT_LO)" Optional="true">variant15.value</ExpandedItem>
+
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant0.DISCR128_BEGIN_HI, variant0.DISCR128_BEGIN_LO, variant0.DISCR128_END_HI, variant0.DISCR128_END_LO)" Optional="true">variant0.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant1.DISCR128_BEGIN_HI, variant1.DISCR128_BEGIN_LO, variant1.DISCR128_END_HI, variant1.DISCR128_END_LO)" Optional="true">variant1.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant2.DISCR128_BEGIN_HI, variant2.DISCR128_BEGIN_LO, variant2.DISCR128_END_HI, variant2.DISCR128_END_LO)" Optional="true">variant2.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant3.DISCR128_BEGIN_HI, variant3.DISCR128_BEGIN_LO, variant3.DISCR128_END_HI, variant3.DISCR128_END_LO)" Optional="true">variant3.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant4.DISCR128_BEGIN_HI, variant4.DISCR128_BEGIN_LO, variant4.DISCR128_END_HI, variant4.DISCR128_END_LO)" Optional="true">variant4.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant5.DISCR128_BEGIN_HI, variant5.DISCR128_BEGIN_LO, variant5.DISCR128_END_HI, variant5.DISCR128_END_LO)" Optional="true">variant5.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant6.DISCR128_BEGIN_HI, variant6.DISCR128_BEGIN_LO, variant6.DISCR128_END_HI, variant6.DISCR128_END_LO)" Optional="true">variant6.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant7.DISCR128_BEGIN_HI, variant7.DISCR128_BEGIN_LO, variant7.DISCR128_END_HI, variant7.DISCR128_END_LO)" Optional="true">variant7.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant8.DISCR128_BEGIN_HI, variant8.DISCR128_BEGIN_LO, variant8.DISCR128_END_HI, variant8.DISCR128_END_LO)" Optional="true">variant8.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant9.DISCR128_BEGIN_HI, variant9.DISCR128_BEGIN_LO, variant9.DISCR128_END_HI, variant9.DISCR128_END_LO)" Optional="true">variant9.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant10.DISCR128_BEGIN_HI, variant10.DISCR128_BEGIN_LO, variant10.DISCR128_END_HI, variant10.DISCR128_END_LO)" Optional="true">variant10.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant11.DISCR128_BEGIN_HI, variant11.DISCR128_BEGIN_LO, variant11.DISCR128_END_HI, variant11.DISCR128_END_LO)" Optional="true">variant11.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant12.DISCR128_BEGIN_HI, variant12.DISCR128_BEGIN_LO, variant12.DISCR128_END_HI, variant12.DISCR128_END_LO)" Optional="true">variant12.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant13.DISCR128_BEGIN_HI, variant13.DISCR128_BEGIN_LO, variant13.DISCR128_END_HI, variant13.DISCR128_END_LO)" Optional="true">variant13.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant14.DISCR128_BEGIN_HI, variant14.DISCR128_BEGIN_LO, variant14.DISCR128_END_HI, variant14.DISCR128_END_LO)" Optional="true">variant14.value</ExpandedItem>
+      <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant15.DISCR128_BEGIN_HI, variant15.DISCR128_BEGIN_LO, variant15.DISCR128_END_HI, variant15.DISCR128_END_LO)" Optional="true">variant15.value</ExpandedItem>
     </Expand>
   </Type>
 </AutoVisualizer>
diff --git a/src/etc/natvis/liballoc.natvis b/src/etc/natvis/liballoc.natvis
index 912418fa7d1..bf6c02b9146 100644
--- a/src/etc/natvis/liballoc.natvis
+++ b/src/etc/natvis/liballoc.natvis
@@ -185,12 +185,4 @@
       </ArrayItems>
     </Expand>
   </Type>
-
-  <Type Name="alloc::borrow::Cow&lt;*&gt;">
-    <DisplayString Condition="RUST$ENUM$DISR == 0x0">Borrowed({__0})</DisplayString>
-    <DisplayString Condition="RUST$ENUM$DISR == 0x1">Owned({__0})</DisplayString>
-    <Expand>
-      <Item Name="[value]" ExcludeView="simple">__0</Item>
-    </Expand>
-  </Type>
 </AutoVisualizer>
diff --git a/src/test/codegen/async-fn-debug-awaitee-field.rs b/src/test/codegen/async-fn-debug-awaitee-field.rs
index efb345fa9f3..909cd0062a6 100644
--- a/src/test/codegen/async-fn-debug-awaitee-field.rs
+++ b/src/test/codegen/async-fn-debug-awaitee-field.rs
@@ -12,11 +12,11 @@ async fn async_fn_test() {
 }
 
 // NONMSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}",
-// MSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<async_fn_debug_awaitee_field::async_fn_test::async_fn_env$0>",
+// MSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_awaitee_field::async_fn_test::async_fn_env$0>",
 // CHECK: [[SUSPEND_STRUCT:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend0", scope: [[GEN]],
 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__awaitee", scope: [[SUSPEND_STRUCT]], {{.*}}, baseType: [[AWAITEE_TYPE:![0-9]*]],
 // NONMSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<async_fn_debug_awaitee_field::foo::{async_fn_env#0}>",
-// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<enum$<async_fn_debug_awaitee_field::foo::async_fn_env$0> >",
+// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<enum2$<async_fn_debug_awaitee_field::foo::async_fn_env$0> >",
 
 fn main() {
     let _fn = async_fn_test();
diff --git a/src/test/codegen/async-fn-debug-msvc.rs b/src/test/codegen/async-fn-debug-msvc.rs
index 8995605e3dd..73c652c9dd1 100644
--- a/src/test/codegen/async-fn-debug-msvc.rs
+++ b/src/test/codegen/async-fn-debug-msvc.rs
@@ -16,7 +16,7 @@ async fn async_fn_test() {
 
 // FIXME: No way to reliably check the filename.
 
-// CHECK-DAG:  [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<async_fn_debug_msvc::async_fn_test::async_fn_env$0>",
+// CHECK-DAG:  [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_msvc::async_fn_test::async_fn_env$0>",
 // CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant0", scope: [[GEN]],
 // For brevity, we only check the struct name and members of the last variant.
 // CHECK-SAME: file: [[FILE:![0-9]*]], line: 11,
@@ -36,16 +36,17 @@ async fn async_fn_test() {
 // CHECK-SAME: )
 // CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant4", scope: [[GEN]],
 // CHECK-SAME: file: [[FILE]], line: 14,
-// CHECK-SAME: baseType: [[VARIANT:![0-9]*]]
+// CHECK-SAME: baseType: [[VARIANT_WRAPPER:![0-9]*]]
 // CHECK-NOT:  flags: DIFlagArtificial
 // CHECK-SAME: )
+// CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "value", scope: [[VARIANT_WRAPPER]], file: !2, baseType: [[VARIANT:![0-9]*]],
 // CHECK:      [[VARIANT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]],
 // CHECK-NOT:  flags: DIFlagArtificial
 // CHECK-SAME: )
 // CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[VARIANT]]
 // CHECK-NOT:  flags: DIFlagArtificial
 // CHECK-SAME: )
-// CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "discriminant", scope: [[GEN]],
+// CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "tag", scope: [[GEN]],
 // CHECK-NOT: flags: DIFlagArtificial
 
 fn main() {
diff --git a/src/test/codegen/debug-vtable.rs b/src/test/codegen/debug-vtable.rs
index b9cb4f93d07..bdd312878ec 100644
--- a/src/test/codegen/debug-vtable.rs
+++ b/src/test/codegen/debug-vtable.rs
@@ -46,7 +46,7 @@
 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "align", scope: ![[VTABLE_TY2]], {{.*}}, baseType: ![[USIZE]], size: {{64|32}}, align: {{64|32}}, offset: {{128|64}})
 
 // NONMSVC: !DIGlobalVariable(name: "<debug_vtable::bar::{closure_env#0} as core::ops::function::FnOnce<(core::option::Option<&dyn core::ops::function::Fn<(), Output=()>>)>>::{vtable}"
-// MSVC: !DIGlobalVariable(name: "impl$<debug_vtable::bar::closure_env$0, core::ops::function::FnOnce<tuple$<enum$<core::option::Option<ref$<dyn$<core::ops::function::Fn<tuple$<>,assoc$<Output,tuple$<> > > > > >, {{.*}}, {{.*}}, Some> > > >::vtable$"
+// MSVC: !DIGlobalVariable(name: "impl$<debug_vtable::bar::closure_env$0, core::ops::function::FnOnce<tuple$<enum2$<core::option::Option<ref$<dyn$<core::ops::function::Fn<tuple$<>,assoc$<Output,tuple$<> > > > > > > > > >::vtable$"
 
 // NONMSVC: !DIGlobalVariable(name: "<debug_vtable::generic_closure::{closure_env#0}<bool> as core::ops::function::FnOnce<()>>::{vtable}"
 // MSVC: !DIGlobalVariable(name: "impl$<debug_vtable::generic_closure::closure_env$0<bool>, core::ops::function::FnOnce<tuple$<> > >::vtable$
diff --git a/src/test/codegen/generator-debug-msvc.rs b/src/test/codegen/generator-debug-msvc.rs
index 033da80be16..b712068bf27 100644
--- a/src/test/codegen/generator-debug-msvc.rs
+++ b/src/test/codegen/generator-debug-msvc.rs
@@ -20,7 +20,7 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> {
 
 // FIXME: No way to reliably check the filename.
 
-// CHECK-DAG:  [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<generator_debug_msvc::generator_test::generator_env$0>"
+// CHECK-DAG:  [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<generator_debug_msvc::generator_test::generator_env$0>"
 // CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant0", scope: [[GEN]],
 // For brevity, we only check the struct name and members of the last variant.
 // CHECK-SAME: file: [[FILE:![0-9]*]], line: 14,
@@ -40,16 +40,18 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> {
 // CHECK-SAME: )
 // CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant4", scope: [[GEN]],
 // CHECK-SAME: file: [[FILE]], line: 17,
-// CHECK-SAME: baseType: [[VARIANT:![0-9]*]]
+// CHECK-SAME: baseType: [[VARIANT_WRAPPER:![0-9]*]]
 // CHECK-NOT:  flags: DIFlagArtificial
 // CHECK-SAME: )
+// CHECK:      [[VARIANT_WRAPPER]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Variant4", scope: [[GEN]],
+// CHECK:      !DIDerivedType(tag: DW_TAG_member, name: "value", scope: [[VARIANT_WRAPPER]], {{.*}}, baseType: [[VARIANT:![0-9]*]],
 // CHECK:      [[VARIANT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]],
 // CHECK-NOT:  flags: DIFlagArtificial
 // CHECK-SAME: )
 // CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[VARIANT]]
 // CHECK-NOT:  flags: DIFlagArtificial
 // CHECK-SAME: )
-// CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "discriminant", scope: [[GEN]],
+// CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "tag", scope: [[GEN]],
 // CHECK-NOT: flags: DIFlagArtificial
 
 fn main() {
diff --git a/src/test/debuginfo/generator-objects.rs b/src/test/debuginfo/generator-objects.rs
index d6d7e5b44aa..11c4ae2f659 100644
--- a/src/test/debuginfo/generator-objects.rs
+++ b/src/test/debuginfo/generator-objects.rs
@@ -41,31 +41,26 @@
 
 // cdb-command: g
 // cdb-command: dx b
-// cdb-check: b                : Unresumed [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check:    [variant]        : Unresumed
+// cdb-check: b                : Unresumed [Type: enum2$<generator_objects::main::generator_env$0>]
 // cdb-check:    [+0x[...]] _ref__a          : 0x[...] : 5 [Type: int *]
 
 // cdb-command: g
 // cdb-command: dx b
-// cdb-check: b                : Suspend0 [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check:    [variant]        : Suspend0
+// cdb-check: b                : Suspend0 [Type: enum2$<generator_objects::main::generator_env$0>]
 // cdb-check:    [+0x[...]] c                : 6 [Type: int]
 // cdb-check:    [+0x[...]] d                : 7 [Type: int]
 // cdb-check:    [+0x[...]] _ref__a          : 0x[...] : 5 [Type: int *]
 
 // cdb-command: g
 // cdb-command: dx b
-// cdb-check: b                : Suspend1 [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check:    [variant]        : Suspend1
+// cdb-check: b                : Suspend1 [Type: enum2$<generator_objects::main::generator_env$0>]
 // cdb-check:    [+0x[...]] c                : 7 [Type: int]
 // cdb-check:    [+0x[...]] d                : 8 [Type: int]
 // cdb-check:    [+0x[...]] _ref__a          : 0x[...] : 6 [Type: int *]
 
 // cdb-command: g
 // cdb-command: dx b
-// cdb-check: b                : Returned [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check:    [<Raw View>]     [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check:    [variant]        : Returned
+// cdb-check: b                : Returned [Type: enum2$<generator_objects::main::generator_env$0>]
 // cdb-check:    [+0x[...]] _ref__a          : 0x[...] : 6 [Type: int *]
 
 #![feature(omit_gdb_pretty_printer_section, generators, generator_trait)]
diff --git a/src/test/debuginfo/msvc-pretty-enums.rs b/src/test/debuginfo/msvc-pretty-enums.rs
index a153a9a4228..45d5ddf5c0e 100644
--- a/src/test/debuginfo/msvc-pretty-enums.rs
+++ b/src/test/debuginfo/msvc-pretty-enums.rs
@@ -4,69 +4,141 @@
 // cdb-command: g
 
 // cdb-command: dx a
-// cdb-check:a                :  Some({...}) [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>]
-// cdb-check:    [variant]        :  Some
+// cdb-check:a                : Some [Type: enum2$<core::option::Option<msvc_pretty_enums::CStyleEnum> >]
 // cdb-check:    [+0x000] __0              : Low (0x2) [Type: msvc_pretty_enums::CStyleEnum]
 
 // cdb-command: dx b
-// cdb-check:b                : None [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>]
-// cdb-check:    [variant]        : None
+// cdb-check:b                : None [Type: enum2$<core::option::Option<msvc_pretty_enums::CStyleEnum> >]
 
 // cdb-command: dx c
-// cdb-check:c                : Tag1 [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check:    [<Raw View>]     [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check:    [variant]        : Tag1
+// cdb-check:c                : Tag1 [Type: enum2$<msvc_pretty_enums::NicheLayoutEnum>]
 
 // cdb-command: dx d
-// cdb-check:d                :  Data({...}) [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check:    [<Raw View>]     [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check:    [variant]        :  Data
+// cdb-check:d                : Data [Type: enum2$<msvc_pretty_enums::NicheLayoutEnum>]
 // cdb-check:    [+0x000] my_data          : High (0x10) [Type: msvc_pretty_enums::CStyleEnum]
 
 // cdb-command: dx e
-// cdb-check:e                : Tag2 [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check:    [<Raw View>]     [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check:    [variant]        : Tag2
+// cdb-check:e                : Tag2 [Type: enum2$<msvc_pretty_enums::NicheLayoutEnum>]
 
 // cdb-command: dx f
-// cdb-check:f                :  Some({...}) [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
-// cdb-check:    [variant]        :  Some
+// cdb-check:f                : Some [Type: enum2$<core::option::Option<ref$<u32> > >]
 // cdb-check:    [+0x000] __0              : 0x[...] : 0x1 [Type: unsigned int *]
 
 // cdb-command: dx g
-// cdb-check:g                : None [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
-// cdb-check:    [variant]        : None
+// cdb-check:g                : None [Type: enum2$<core::option::Option<ref$<u32> > >]
 
 // cdb-command: dx h
-// cdb-check:h                : Some [Type: enum$<core::option::Option<u32> >]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<u32> >]
-// cdb-check:    [variant]        : Some
+// cdb-check:h                : Some [Type: enum2$<core::option::Option<u32> >]
 // cdb-check:    [+0x004] __0              : 0xc [Type: unsigned int]
 
 // cdb-command: dx i
-// cdb-check:i                : None [Type: enum$<core::option::Option<u32> >]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<u32> >]
-// cdb-check:    [variant]        : None
+// cdb-check:i                : None [Type: enum2$<core::option::Option<u32> >]
 
 // cdb-command: dx j
 // cdb-check:j                : High (0x10) [Type: msvc_pretty_enums::CStyleEnum]
 
 // cdb-command: dx k
-// cdb-check:k                :  Some({...}) [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
-// cdb-check:    [variant]        :  Some
+// cdb-check:k                : Some [Type: enum2$<core::option::Option<alloc::string::String> >]
 // cdb-check:    [+0x000] __0              : "IAMA optional string!" [Type: alloc::string::String]
 
 // cdb-command: dx l
-// cdb-check:l                :  Ok [Type: enum$<core::result::Result<u32,enum$<msvc_pretty_enums::Empty> >, Ok>]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::result::Result<u32,enum$<msvc_pretty_enums::Empty> >, Ok>]
-// cdb-check:    [variant]        :  Ok
+// cdb-check:l                : Ok [Type: enum2$<core::result::Result<u32,enum2$<msvc_pretty_enums::Empty> > >]
 // cdb-check:    [+0x000] __0              : 0x2a [Type: unsigned int]
 
+// cdb-command: dx niche128_some
+// cdb-check: niche128_some    : Some [Type: enum2$<core::option::Option<core::num::nonzero::NonZeroI128> >]
+// Note: we can't actually read the value of the field because CDB cannot handle 128 bit integers.
+// cdb-check:    [+0x000] __0 [...] [Type: core::num::nonzero::NonZeroI128]
+
+// cdb-command: dx niche128_none
+// cdb-check: niche128_none    : None [Type: enum2$<core::option::Option<core::num::nonzero::NonZeroI128> >]
+
+// cdb-command: dx wrapping_niche128_dataful
+// cdb-check: wrapping_niche128_dataful : X [Type: enum2$<msvc_pretty_enums::Wrapping128Niche>]
+// cdb-check:    [+0x[...]] __0              [Type: msvc_pretty_enums::Wrapping128]
+
+// cdb-command: dx wrapping_niche128_none1
+// cdb-check: wrapping_niche128_none1 : Y [Type: enum2$<msvc_pretty_enums::Wrapping128Niche>]
+// cdb-check:    [+0x[...]] __0              [Type: msvc_pretty_enums::Wrapping128]
+
+// cdb-command: dx wrapping_niche128_none2
+// cdb-check: wrapping_niche128_none2 : Z [Type: enum2$<msvc_pretty_enums::Wrapping128Niche>]
+// cdb-check:    [+0x[...]] __0              [Type: msvc_pretty_enums::Wrapping128]
+
+// cdb-command: dx direct_tag_128_a,d
+// cdb-check: direct_tag_128_a,d : A [Type: enum2$<msvc_pretty_enums::DirectTag128>]
+// cdb-check:     [+0x[...]] __0              : 42 [Type: unsigned int]
+
+// cdb-command: dx direct_tag_128_b,d
+// cdb-check: direct_tag_128_b,d : B [Type: enum2$<msvc_pretty_enums::DirectTag128>]
+// cdb-check:     [+0x[...]] __0              : 137 [Type: unsigned int]
+
+// cdb-command: dx niche_w_fields_1_some,d
+// cdb-check: niche_w_fields_1_some,d : A [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields1>]
+// cdb-check:     [+0x[...]] __0              : 0x[...] : 77 [Type: unsigned char *]
+// cdb-check:     [+0x[...]] __1              : 7 [Type: unsigned int]
+
+// cdb-command: dx niche_w_fields_1_none,d
+// cdb-check: niche_w_fields_1_none,d : B [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields1>]
+// cdb-check:     [+0x[...]] __0              : 99 [Type: unsigned int]
+
+// cdb-command: dx niche_w_fields_2_some,d
+// cdb-check: niche_w_fields_2_some,d : A [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields2>]
+// cdb-check:     [+0x[...]] __0              : 800 [Type: core::num::nonzero::NonZeroU32]
+// cdb-check:     [+0x[...]] __1              : 900 [Type: unsigned __int64]
+
+// cdb-command: dx niche_w_fields_2_none,d
+// cdb-check: niche_w_fields_2_none,d : B [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields2>]
+// cdb-check:     [+0x[...]] __0              : 1000 [Type: unsigned __int64]
+
+// cdb-command: dx niche_w_fields_3_some,d
+// cdb-check: niche_w_fields_3_some,d : A [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check:     [+0x[...]] __0              : 137 [Type: unsigned char]
+// cdb-check:     [+0x[...]] __1              : true [Type: bool]
+
+// cdb-command: dx niche_w_fields_3_niche1,d
+// cdb-check: niche_w_fields_3_niche1,d : B [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check:     [+0x[...]] __0              : 12 [Type: unsigned char]
+
+// cdb-command: dx niche_w_fields_3_niche2,d
+// cdb-check: niche_w_fields_3_niche2,d : C [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check:     [+0x[...]] __0              : false [Type: bool]
+
+// cdb-command: dx niche_w_fields_3_niche3,d
+// cdb-check: niche_w_fields_3_niche3,d : D [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check:     [+0x[...]] __0              : 34 [Type: unsigned char]
+
+// cdb-command: dx niche_w_fields_3_niche4,d
+// cdb-check: niche_w_fields_3_niche4,d : E [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check:     [+0x[...]] __0              : 56 [Type: unsigned char]
+
+// cdb-command: dx niche_w_fields_3_niche5,d
+// 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:        [+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:    [+0x[...]] __0              : 789 [Type: unsigned __int64]
+
+// cdb-command: dx -r2 arbitrary_discr1,d
+// cdb-check: arbitrary_discr1,d : Abc [Type: enum2$<msvc_pretty_enums::ArbitraryDiscr>]
+// cdb-check:     [+0x[...]] __0              : 1234 [Type: unsigned int]
+
+// cdb-command: dx -r2 arbitrary_discr2,d
+// cdb-check: arbitrary_discr2,d : Def [Type: enum2$<msvc_pretty_enums::ArbitraryDiscr>]
+// cdb-check:     [+0x[...]] __0              : 5678 [Type: unsigned int]
+
+#![feature(rustc_attrs)]
+#![feature(repr128)]
+#![feature(arbitrary_enum_discriminant)]
+
+use std::num::{NonZeroI128, NonZeroU32};
+
 pub enum CStyleEnum {
     Low = 2,
     High = 16,
@@ -80,6 +152,51 @@ pub enum NicheLayoutEnum {
 
 pub enum Empty {}
 
+// The following three types will use a niche layout once
+// https://github.com/rust-lang/rust/pull/94075 is merged:
+enum NicheLayoutWithFields1<'a> {
+    A(&'a u8, u32),
+    B(u32),
+}
+
+enum NicheLayoutWithFields2 {
+    A(NonZeroU32, u64),
+    B(u64),
+}
+
+enum NicheLayoutWithFields3 {
+    A(u8, bool),
+    B(u8),
+    C(bool),
+    D(u8),
+    E(u8),
+    F,
+}
+
+#[rustc_layout_scalar_valid_range_start(340282366920938463463374607431768211454)]
+#[rustc_layout_scalar_valid_range_end(1)]
+#[repr(transparent)]
+struct Wrapping128(u128);
+
+// #[rustc_layout(debug)]
+enum Wrapping128Niche {
+    X(Wrapping128),
+    Y,
+    Z,
+}
+
+#[repr(i128)]
+enum DirectTag128 {
+    A(u32),
+    B(u32),
+}
+
+#[repr(u32)]
+enum ArbitraryDiscr {
+    Abc(u32) = 1000,
+    Def(u32) = 5000_000,
+}
+
 fn main() {
     let a = Some(CStyleEnum::Low);
     let b = Option::<CStyleEnum>::None;
@@ -93,6 +210,35 @@ fn main() {
     let j = CStyleEnum::High;
     let k = Some("IAMA optional string!".to_string());
     let l = Result::<u32, Empty>::Ok(42);
+    let niche128_some = Some(NonZeroI128::new(123456).unwrap());
+    let niche128_none: Option<NonZeroI128> = None;
+
+    let wrapping_niche128_dataful =
+        unsafe { Wrapping128Niche::X(Wrapping128(340282366920938463463374607431768211454)) };
+    let wrapping_niche128_none1 = Wrapping128Niche::Y;
+    let wrapping_niche128_none2 = Wrapping128Niche::Z;
+
+    let direct_tag_128_a = DirectTag128::A(42);
+    let direct_tag_128_b = DirectTag128::B(137);
+
+    let niche_w_fields_1_some = NicheLayoutWithFields1::A(&77, 7);
+    let niche_w_fields_1_none = NicheLayoutWithFields1::B(99);
+
+    let niche_w_fields_2_some = NicheLayoutWithFields2::A(NonZeroU32::new(800).unwrap(), 900);
+    let niche_w_fields_2_none = NicheLayoutWithFields2::B(1000);
+
+    let niche_w_fields_3_some = NicheLayoutWithFields3::A(137, true);
+    let niche_w_fields_3_niche1 = NicheLayoutWithFields3::B(12);
+    let niche_w_fields_3_niche2 = NicheLayoutWithFields3::C(false);
+    let niche_w_fields_3_niche3 = NicheLayoutWithFields3::D(34);
+    let niche_w_fields_3_niche4 = NicheLayoutWithFields3::E(56);
+    let niche_w_fields_3_niche5 = NicheLayoutWithFields3::F;
+
+    let niche_w_fields_std_result_ok: Result<Box<[u8]>, u64> = Ok(vec![1, 2, 3].into());
+    let niche_w_fields_std_result_err: Result<Box<[u8]>, u64> = Err(789);
+
+    let arbitrary_discr1 = ArbitraryDiscr::Abc(1234);
+    let arbitrary_discr2 = ArbitraryDiscr::Def(5678);
 
     zzz(); // #break
 }
diff --git a/src/test/debuginfo/msvc-scalarpair-params.rs b/src/test/debuginfo/msvc-scalarpair-params.rs
index 3846fb42f81..9630952cbaa 100644
--- a/src/test/debuginfo/msvc-scalarpair-params.rs
+++ b/src/test/debuginfo/msvc-scalarpair-params.rs
@@ -18,12 +18,10 @@
 // cdb-command: g
 
 // cdb-command: dx o1
-// cdb-check:o1               : Some [Type: enum$<core::option::Option<u32> >]
-// cdb-check:    [variant]        : Some
+// cdb-check:o1               : Some [Type: enum2$<core::option::Option<u32> >]
 // cdb-check:    [+0x004] __0              : 0x4d2 [Type: [...]]
 // cdb-command: dx o2
-// cdb-check:o2               : Some [Type: enum$<core::option::Option<u64> >]
-// cdb-check:    [variant]        : Some
+// cdb-check:o2               : Some [Type: enum2$<core::option::Option<u64> >]
 // cdb-check:    [+0x008] __0              : 0x162e [Type: unsigned __int64]
 
 // cdb-command: g
@@ -89,7 +87,7 @@ fn slice(s: &[u8]) {
     zzz(); // #break
 }
 
-fn zzz() { }
+fn zzz() {}
 
 fn main() {
     range(10..12, 20..30);
diff --git a/src/test/debuginfo/mutex.rs b/src/test/debuginfo/mutex.rs
index 00dccf5f906..314ba40b0e3 100644
--- a/src/test/debuginfo/mutex.rs
+++ b/src/test/debuginfo/mutex.rs
@@ -20,19 +20,20 @@
 // cdb-check:    [<Raw View>]     [Type: core::cell::UnsafeCell<i32>]
 
 //
-// cdb-command:dx lock,d
-// cdb-check:lock,d           : Ok [Type: enum$<core::result::Result<std::sync::mutex::MutexGuard<i32>,enum$<std::sync::poison::TryLockError<std::sync::mutex::MutexGuard<i32> >, 0, 1, Poisoned> > >]
-// cdb-check:    [variant]        : Ok
+// cdb-command:dx _lock,d
+// cdb-check:_lock,d          : Ok [Type: enum2$<core::result::Result<std::sync::mutex::MutexGuard<i32>,enum2$<std::sync::poison::TryLockError<std::sync::mutex::MutexGuard<i32> > > > >]
 // cdb-check:    [...] __0              [Type: std::sync::mutex::MutexGuard<i32>]
 
 use std::sync::Mutex;
 
-#[allow(unused_variables)]
-fn main()
-{
+fn main() {
     let m = Mutex::new(0);
-    let lock = m.try_lock();
+    let _lock = m.try_lock();
+
+    println!("this line avoids an `Ambiguous symbol error` while setting the breakpoint");
+
     zzz(); // #break
 }
 
+#[inline(never)]
 fn zzz() {}
diff --git a/src/test/debuginfo/pretty-std.rs b/src/test/debuginfo/pretty-std.rs
index 55a4ecc1c1a..a51b37205e8 100644
--- a/src/test/debuginfo/pretty-std.rs
+++ b/src/test/debuginfo/pretty-std.rs
@@ -39,7 +39,6 @@
 // gdb-command: print some_string
 // gdb-check:$8 = Some = {"IAMA "...}
 
-
 // === LLDB TESTS ==================================================================================
 
 // lldb-command: run
@@ -65,7 +64,6 @@
 // lldb-command: print os_string
 // lldb-check:[...]$6 = "IAMA OS string 😃"[...]
 
-
 // === CDB TESTS ==================================================================================
 
 // cdb-command: g
@@ -118,20 +116,17 @@
 // cdb-check:    [chars]          : "IAMA OS string [...]"
 
 // cdb-command: dx some
-// cdb-check:some             : Some [Type: enum$<core::option::Option<i16> >]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<i16> >]
-// cdb-check:    [variant]        : Some
+// cdb-check:some             : Some [Type: enum2$<core::option::Option<i16> >]
+// cdb-check:    [<Raw View>]     [Type: enum2$<core::option::Option<i16> >]
 // cdb-check:    [+0x002] __0              : 8 [Type: short]
 
 // cdb-command: dx none
-// cdb-check:none             : None [Type: enum$<core::option::Option<i64> >]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<i64> >]
-// cdb-check:    [variant]        : None
+// cdb-check:none             : None [Type: enum2$<core::option::Option<i64> >]
+// cdb-check:    [<Raw View>]     [Type: enum2$<core::option::Option<i64> >]
 
 // cdb-command: dx some_string
-// cdb-check:some_string      :  Some({...}) [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
-// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
-// cdb-check:    [variant]        :  Some
+// cdb-check:some_string      : Some [Type: enum2$<core::option::Option<alloc::string::String> >]
+// cdb-check:    [<Raw View>]     [Type: enum2$<core::option::Option<alloc::string::String> >]
 // cdb-check:    [+0x000] __0              : "IAMA optional string!" [Type: alloc::string::String]
 
 // cdb-command: dx linkedlist
@@ -153,7 +148,6 @@ use std::collections::{LinkedList, VecDeque};
 use std::ffi::OsString;
 
 fn main() {
-
     // &[]
     let slice: &[i32] = &[0, 1, 2, 3];
 
@@ -188,4 +182,6 @@ fn main() {
     zzz(); // #break
 }
 
-fn zzz() { () }
+fn zzz() {
+    ()
+}
diff --git a/src/test/debuginfo/result-types.rs b/src/test/debuginfo/result-types.rs
index c0d905a6acc..cdac47a784d 100644
--- a/src/test/debuginfo/result-types.rs
+++ b/src/test/debuginfo/result-types.rs
@@ -7,15 +7,14 @@
 // cdb-command: g
 
 // cdb-command: dx x,d
-// cdb-check:x,d              : Ok [Type: enum$<core::result::Result<i32,str> >]
+// cdb-check:x,d              : Ok [Type: enum2$<core::result::Result<i32,str> >]
 // cdb-check:    [...] __0              : -3 [Type: int]
 
 // cdb-command: dx y
-// cdb-check:y                : Err [Type: enum$<core::result::Result<i32,str> >]
+// cdb-check:y                : Err [Type: enum2$<core::result::Result<i32,str> >]
 // cdb-check:    [...] __0              : "Some error message" [Type: str]
 
-fn main()
-{
+fn main() {
     let x: Result<i32, &str> = Ok(-3);
     assert_eq!(x.is_ok(), true);
 
@@ -25,4 +24,6 @@ fn main()
     zzz(); // #break.
 }
 
-fn zzz() { () }
+fn zzz() {
+    ()
+}
diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs
index b040a6e7494..9cc99d7767c 100644
--- a/src/test/debuginfo/type-names.rs
+++ b/src/test/debuginfo/type-names.rs
@@ -175,51 +175,51 @@
 // 0-sized structs appear to be optimized away in some cases, so only check the structs that do
 // actually appear.
 // cdb-command:dv /t *_struct
-// cdb-check:struct type_names::GenericStruct<enum$<type_names::mod1::Enum2>,f64> mut_generic_struct = [...]
+// cdb-check:struct type_names::GenericStruct<enum2$<type_names::mod1::Enum2>,f64> mut_generic_struct = [...]
 
 // ENUMS
 // cdb-command:dv /t *_enum_*
-// cdb-check:union enum$<type_names::Enum1> simple_enum_1 = [...]
-// cdb-check:union enum$<type_names::Enum1> simple_enum_2 = [...]
-// cdb-check:union enum$<type_names::mod1::Enum2> simple_enum_3 = [...]
-// cdb-check:union enum$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > generic_enum_1 = [...]
-// cdb-check:union enum$<type_names::mod1::mod2::Enum3<type_names::Struct1> > generic_enum_2 = [...]
+// cdb-check:union enum2$<type_names::Enum1> simple_enum_1 = [...]
+// cdb-check:union enum2$<type_names::Enum1> simple_enum_2 = [...]
+// cdb-check:union enum2$<type_names::mod1::Enum2> simple_enum_3 = [...]
+// cdb-check:union enum2$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > generic_enum_1 = [...]
+// cdb-check:union enum2$<type_names::mod1::mod2::Enum3<type_names::Struct1> > generic_enum_2 = [...]
 
 // TUPLES
 // cdb-command:dv /t tuple*
-// cdb-check:struct tuple$<u32,type_names::Struct1,enum$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > > tuple1 = [...]
-// cdb-check:struct tuple$<tuple$<type_names::Struct1,type_names::mod1::mod2::Struct3>,enum$<type_names::mod1::Enum2>,char> tuple2 = [...]
+// cdb-check:struct tuple$<u32,type_names::Struct1,enum2$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > > tuple1 = [...]
+// cdb-check:struct tuple$<tuple$<type_names::Struct1,type_names::mod1::mod2::Struct3>,enum2$<type_names::mod1::Enum2>,char> tuple2 = [...]
 
 // BOX
 // cdb-command:dv /t box*
 // cdb-check:struct tuple$<alloc::boxed::Box<f32,alloc::alloc::Global>,i32> box1 = [...]
-// cdb-check:struct tuple$<alloc::boxed::Box<enum$<type_names::mod1::mod2::Enum3<f32> >,alloc::alloc::Global>,i32> box2 = [...]
+// cdb-check:struct tuple$<alloc::boxed::Box<enum2$<type_names::mod1::mod2::Enum3<f32> >,alloc::alloc::Global>,i32> box2 = [...]
 
 // REFERENCES
 // cdb-command:dv /t *ref*
 // cdb-check:struct tuple$<ref$<type_names::Struct1>,i32> ref1 = [...]
 // cdb-check:struct tuple$<ref$<type_names::GenericStruct<char,type_names::Struct1> >,i32> ref2 = [...]
 // cdb-check:struct tuple$<ref_mut$<type_names::Struct1>,i32> mut_ref1 = [...]
-// cdb-check:struct tuple$<ref_mut$<type_names::GenericStruct<enum$<type_names::mod1::Enum2>,f64> >,i32> mut_ref2 = [...]
+// cdb-check:struct tuple$<ref_mut$<type_names::GenericStruct<enum2$<type_names::mod1::Enum2>,f64> >,i32> mut_ref2 = [...]
 
 // RAW POINTERS
 // cdb-command:dv /t *_ptr*
 // cdb-check:struct tuple$<ptr_mut$<type_names::Struct1>,isize> mut_ptr1 = [...]
 // cdb-check:struct tuple$<ptr_mut$<isize>,isize> mut_ptr2 = [...]
-// cdb-check:struct tuple$<ptr_mut$<enum$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> mut_ptr3 = [...]
+// cdb-check:struct tuple$<ptr_mut$<enum2$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> mut_ptr3 = [...]
 // cdb-check:struct tuple$<ptr_const$<type_names::Struct1>,isize> const_ptr1 = [...]
 // cdb-check:struct tuple$<ptr_const$<isize>,isize> const_ptr2 = [...]
-// cdb-check:struct tuple$<ptr_const$<enum$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> const_ptr3 = [...]
+// cdb-check:struct tuple$<ptr_const$<enum2$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> const_ptr3 = [...]
 
 // VECTORS
 // cdb-command:dv /t *vec*
 // cdb-check:struct tuple$<array$<type_names::Struct1,3>,i16> fixed_size_vec1 = [...]
 // cdb-check:struct tuple$<array$<usize,3>,i16> fixed_size_vec2 = [...]
 // cdb-check:struct alloc::vec::Vec<usize,alloc::alloc::Global> vec1 = [...]
-// cdb-check:struct alloc::vec::Vec<enum$<type_names::mod1::Enum2>,alloc::alloc::Global> vec2 = [...]
+// 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$<enum$<type_names::mod1::Enum2> > slice2 = [...]
+// cdb-check:struct slice$<enum2$<type_names::mod1::Enum2> > slice2 = [...]
 
 // TRAITS
 // cdb-command:dv /t *_trait
@@ -238,16 +238,16 @@
 // cdb-check:struct tuple$<type_names::mod1::Struct2 (*)(type_names::GenericStruct<u16,u8>),usize> unsafe_fn_with_return_value = [...]
 // cdb-check:struct tuple$<type_names::Struct1 (*)(),usize> extern_c_fn_with_return_value = [...]
 // cdb-check:struct tuple$<usize (*)(f64),usize> rust_fn_with_return_value = [...]
-// cdb-check:struct tuple$<void (*)(enum$<core::result::Result<char,f64> >),usize> unsafe_fn = [...]
+// cdb-check:struct tuple$<void (*)(enum2$<core::result::Result<char,f64> >),usize> unsafe_fn = [...]
 // cdb-check:struct tuple$<void (*)(isize),usize> extern_c_fn = [...]
-// cdb-check:struct tuple$<void (*)(enum$<core::option::Option<isize> >,enum$<core::option::Option<ref$<type_names::mod1::Struct2> >, 1, [...], Some>),usize> rust_fn = [...]
+// cdb-check:struct tuple$<void (*)(enum2$<core::option::Option<isize> >,enum2$<core::option::Option<ref$<type_names::mod1::Struct2> > >),usize> rust_fn = [...]
 // cdb-command:dv /t *_function*
 // cdb-check:struct tuple$<isize (*)(ptr_const$<u8>, ...),usize> variadic_function = [...]
 // cdb-check:struct tuple$<type_names::mod1::mod2::Struct3 (*)(type_names::mod1::mod2::Struct3),usize> generic_function_struct3 = [...]
 // cdb-check:struct tuple$<isize (*)(isize),usize> generic_function_int = [...]
 // cdb-command:dx Debugger.State.Scripts.@"type-names.cdb".Contents.getFunctionDetails("rust_fn")
 // cdb-check:Return Type: void
-// cdb-check:Parameter Types: enum$<core::option::Option<isize> >,enum$<core::option::Option<ref$<type_names::mod1::Struct2> >, 1, [...], Some>
+// cdb-check:Parameter Types: enum2$<core::option::Option<isize> >,enum2$<core::option::Option<ref$<type_names::mod1::Struct2> > >
 // cdb-command:dx Debugger.State.Scripts.@"type-names.cdb".Contents.getFunctionDetails("rust_fn_with_return_value")
 // cdb-check:Return Type: usize
 // cdb-check:Parameter Types: f64
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index ac6d80bb439..0e2cc52a645 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -545,6 +545,8 @@ fn common_inputs_stamp(config: &Config) -> Stamp {
         stamp.add_path(&path);
     }
 
+    stamp.add_dir(&rust_src_dir.join("src/etc/natvis"));
+
     stamp.add_dir(&config.run_lib_path);
 
     if let Some(ref rustdoc_path) = config.rustdoc_path {