about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2024-12-01 13:12:43 +0100
committerRalf Jung <post@ralfj.de>2024-12-18 11:00:21 +0100
commit21de42bf8ddd0f39c766c7705990152302ae1f3b (patch)
treefd27ee9da12fb8c8682f7aaddb4dc749cfa1bfe6
parent37e74596c0b59e81b9ac58657f92297ef4ccb7ef (diff)
downloadrust-21de42bf8ddd0f39c766c7705990152302ae1f3b.tar.gz
rust-21de42bf8ddd0f39c766c7705990152302ae1f3b.zip
Variants::Single: do not use invalid VariantIdx for uninhabited enums
-rw-r--r--compiler/rustc_abi/src/layout.rs14
-rw-r--r--compiler/rustc_abi/src/lib.rs8
-rw-r--r--compiler/rustc_codegen_cranelift/src/discriminant.rs5
-rw-r--r--compiler/rustc_codegen_gcc/src/type_of.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/type_of.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/discriminant.rs23
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs4
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs2
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs13
-rw-r--r--compiler/rustc_mir_transform/src/jump_threading.rs31
-rw-r--r--compiler/rustc_mir_transform/src/unreachable_enum_branching.rs6
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/abi.rs6
-rw-r--r--compiler/rustc_transmute/src/layout/tree.rs10
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs14
-rw-r--r--compiler/rustc_ty_utils/src/layout/invariant.rs122
-rw-r--r--compiler/stable_mir/src/abi.rs1
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/layout.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/utils.rs2
-rw-r--r--tests/mir-opt/set_no_discriminant.f.JumpThreading.diff3
-rw-r--r--tests/mir-opt/set_no_discriminant.generic.JumpThreading.diff3
-rw-r--r--tests/mir-opt/set_no_discriminant.rs21
-rw-r--r--tests/ui/abi/c-zst.aarch64-darwin.stderr8
-rw-r--r--tests/ui/abi/c-zst.powerpc-linux.stderr8
-rw-r--r--tests/ui/abi/c-zst.s390x-linux.stderr8
-rw-r--r--tests/ui/abi/c-zst.sparc64-linux.stderr8
-rw-r--r--tests/ui/abi/c-zst.x86_64-linux.stderr8
-rw-r--r--tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr8
-rw-r--r--tests/ui/abi/debug.stderr96
-rw-r--r--tests/ui/abi/sysv64-zst.stderr8
-rw-r--r--tests/ui/abi/win64-zst.x86_64-linux.stderr8
-rw-r--r--tests/ui/abi/win64-zst.x86_64-windows-gnu.stderr8
-rw-r--r--tests/ui/abi/win64-zst.x86_64-windows-msvc.stderr8
-rw-r--r--tests/ui/layout/debug.stderr64
-rw-r--r--tests/ui/layout/hexagon-enum.stderr20
-rw-r--r--tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr48
-rw-r--r--tests/ui/layout/issue-96185-overaligned-enum.stderr16
-rw-r--r--tests/ui/layout/thumb-enum.stderr20
-rw-r--r--tests/ui/layout/zero-sized-array-enum-niche.stderr36
-rw-r--r--tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr20
-rw-r--r--tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr20
-rw-r--r--tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr20
-rw-r--r--tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr20
-rw-r--r--tests/ui/repr/repr-c-int-dead-variants.stderr20
-rw-r--r--tests/ui/type/pattern_types/range_patterns.stderr28
47 files changed, 548 insertions, 280 deletions
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index e6d66f608da..f2b50ae408e 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -120,7 +120,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
             .max_by_key(|niche| niche.available(dl));
 
         LayoutData {
-            variants: Variants::Single { index: VariantIdx::new(0) },
+            variants: Variants::Single { index: Some(VariantIdx::new(0)) },
             fields: FieldsShape::Arbitrary {
                 offsets: [Size::ZERO, b_offset].into(),
                 memory_index: [0, 1].into(),
@@ -214,7 +214,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
     ) -> LayoutData<FieldIdx, VariantIdx> {
         let dl = self.cx.data_layout();
         LayoutData {
-            variants: Variants::Single { index: VariantIdx::new(0) },
+            variants: Variants::Single { index: None },
             fields: FieldsShape::Primitive,
             backend_repr: BackendRepr::Uninhabited,
             largest_niche: None,
@@ -385,7 +385,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
         };
 
         Ok(LayoutData {
-            variants: Variants::Single { index: only_variant_idx },
+            variants: Variants::Single { index: Some(only_variant_idx) },
             fields: FieldsShape::Union(union_field_count),
             backend_repr: abi,
             largest_niche: None,
@@ -424,7 +424,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
         };
 
         let mut st = self.univariant(&variants[v], repr, kind)?;
-        st.variants = Variants::Single { index: v };
+        st.variants = Variants::Single { index: Some(v) };
 
         if is_unsafe_cell {
             let hide_niches = |scalar: &mut _| match scalar {
@@ -543,7 +543,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                 .iter_enumerated()
                 .map(|(j, v)| {
                     let mut st = self.univariant(v, repr, StructKind::AlwaysSized).ok()?;
-                    st.variants = Variants::Single { index: j };
+                    st.variants = Variants::Single { index: Some(j) };
 
                     align = align.max(st.align);
                     max_repr_align = max_repr_align.max(st.max_repr_align);
@@ -736,7 +736,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                     repr,
                     StructKind::Prefixed(min_ity.size(), prefix_align),
                 )?;
-                st.variants = Variants::Single { index: i };
+                st.variants = Variants::Single { index: Some(i) };
                 // Find the first field we can't move later
                 // to make room for a larger discriminant.
                 for field_idx in st.fields.index_by_increasing_offset() {
@@ -1344,7 +1344,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
         };
 
         Ok(LayoutData {
-            variants: Variants::Single { index: VariantIdx::new(0) },
+            variants: Variants::Single { index: Some(VariantIdx::new(0)) },
             fields: FieldsShape::Arbitrary { offsets, memory_index },
             backend_repr: abi,
             largest_niche,
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 15a27c0b6ee..242e2cadd18 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -1506,9 +1506,9 @@ impl BackendRepr {
 pub enum Variants<FieldIdx: Idx, VariantIdx: Idx> {
     /// Single enum variants, structs/tuples, unions, and all non-ADTs.
     Single {
-        /// Always 0 for non-enums/generators.
-        /// For enums without a variant, this is an invalid index!
-        index: VariantIdx,
+        /// Always `Some(0)` for types without variants (i.e., everything except for `!`, enums, and
+        /// generators). `None` indicates an uninhabited type; this is used for zero-variant enums.
+        index: Option<VariantIdx>,
     },
 
     /// Enum-likes with more than one variant: each variant comes with
@@ -1706,7 +1706,7 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
         let size = scalar.size(cx);
         let align = scalar.align(cx);
         LayoutData {
-            variants: Variants::Single { index: VariantIdx::new(0) },
+            variants: Variants::Single { index: Some(VariantIdx::new(0)) },
             fields: FieldsShape::Primitive,
             backend_repr: BackendRepr::Scalar(scalar),
             largest_niche,
diff --git a/compiler/rustc_codegen_cranelift/src/discriminant.rs b/compiler/rustc_codegen_cranelift/src/discriminant.rs
index 45794a42665..055063c876f 100644
--- a/compiler/rustc_codegen_cranelift/src/discriminant.rs
+++ b/compiler/rustc_codegen_cranelift/src/discriminant.rs
@@ -19,7 +19,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
     }
     match layout.variants {
         Variants::Single { index } => {
-            assert_eq!(index, variant_index);
+            assert_eq!(index.unwrap(), variant_index);
         }
         Variants::Multiple {
             tag: _,
@@ -86,9 +86,10 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
 
     let (tag_scalar, tag_field, tag_encoding) = match &layout.variants {
         Variants::Single { index } => {
+            let index = index.unwrap();
             let discr_val = layout
                 .ty
-                .discriminant_for_variant(fx.tcx, *index)
+                .discriminant_for_variant(fx.tcx, index)
                 .map_or(u128::from(index.as_u32()), |discr| discr.val);
 
             let val = match dest_layout.ty.kind() {
diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs
index 0efdf36da48..426d28f4ed7 100644
--- a/compiler/rustc_codegen_gcc/src/type_of.rs
+++ b/compiler/rustc_codegen_gcc/src/type_of.rs
@@ -99,14 +99,14 @@ fn uncached_gcc_type<'gcc, 'tcx>(
             if !cx.sess().fewer_names() =>
         {
             let mut name = with_no_trimmed_paths!(layout.ty.to_string());
-            if let (&ty::Adt(def, _), &Variants::Single { index }) =
+            if let (&ty::Adt(def, _), &Variants::Single { index: Some(index) }) =
                 (layout.ty.kind(), &layout.variants)
             {
                 if def.is_enum() && !def.variants().is_empty() {
                     write!(&mut name, "::{}", def.variant(index).name).unwrap();
                 }
             }
-            if let (&ty::Coroutine(_, _), &Variants::Single { index }) =
+            if let (&ty::Coroutine(_, _), &Variants::Single { index: Some(index) }) =
                 (layout.ty.kind(), &layout.variants)
             {
                 write!(&mut name, "::{}", ty::CoroutineArgs::variant_name(index)).unwrap();
@@ -230,7 +230,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
 
         // Check the cache.
         let variant_index = match self.variants {
-            Variants::Single { index } => Some(index),
+            Variants::Single { index } => index,
             _ => None,
         };
         let cached_type = cx.types.borrow().get(&(self.ty, variant_index)).cloned();
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
index d374767f187..8ec83fa7c92 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
@@ -213,11 +213,11 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
         |cx, enum_type_di_node| {
             match enum_type_and_layout.variants {
                 Variants::Single { index: variant_index } => {
-                    if enum_adt_def.variants().is_empty() {
+                    let Some(variant_index) = variant_index else {
                         // Uninhabited enums have Variants::Single. We don't generate
                         // any members for them.
                         return smallvec![];
-                    }
+                    };
 
                     build_single_variant_union_fields(
                         cx,
diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs
index 2b05e24a7ba..833a687fe74 100644
--- a/compiler/rustc_codegen_llvm/src/type_of.rs
+++ b/compiler/rustc_codegen_llvm/src/type_of.rs
@@ -35,14 +35,14 @@ fn uncached_llvm_type<'a, 'tcx>(
             if !cx.sess().fewer_names() =>
         {
             let mut name = with_no_visible_paths!(with_no_trimmed_paths!(layout.ty.to_string()));
-            if let (&ty::Adt(def, _), &Variants::Single { index }) =
+            if let (&ty::Adt(def, _), &Variants::Single { index: Some(index) }) =
                 (layout.ty.kind(), &layout.variants)
             {
-                if def.is_enum() && !def.variants().is_empty() {
+                if def.is_enum() {
                     write!(&mut name, "::{}", def.variant(index).name).unwrap();
                 }
             }
-            if let (&ty::Coroutine(_, _), &Variants::Single { index }) =
+            if let (&ty::Coroutine(_, _), &Variants::Single { index: Some(index) }) =
                 (layout.ty.kind(), &layout.variants)
             {
                 write!(&mut name, "::{}", ty::CoroutineArgs::variant_name(index)).unwrap();
@@ -216,7 +216,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
 
         // Check the cache.
         let variant_index = match self.variants {
-            Variants::Single { index } => Some(index),
+            Variants::Single { index } => index,
             _ => None,
         };
         if let Some(llty) = cx.type_lowering.borrow().get(&(self.ty, variant_index)) {
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index a9e80e27ed4..cef3d8255a0 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -244,6 +244,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
         }
         let (tag_scalar, tag_encoding, tag_field) = match self.layout.variants {
             Variants::Single { index } => {
+                let index = index.unwrap(); // we already checked `is_uninhabited`
                 let discr_val = self
                     .layout
                     .ty
@@ -366,7 +367,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
         }
         match self.layout.variants {
             Variants::Single { index } => {
-                assert_eq!(index, variant_index);
+                assert_eq!(index.unwrap(), variant_index);
             }
             Variants::Multiple { tag_encoding: TagEncoding::Direct, tag_field, .. } => {
                 let ptr = self.project_field(bx, tag_field);
diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs
index 6faac1582ab..6cfd1613229 100644
--- a/compiler/rustc_const_eval/src/interpret/discriminant.rs
+++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs
@@ -44,7 +44,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         }
     }
 
-    /// Read discriminant, return the runtime value as well as the variant index.
+    /// Read discriminant, return the variant index.
     /// Can also legally be called on non-enums (e.g. through the discriminant_value intrinsic)!
     ///
     /// Will never return an uninhabited variant.
@@ -66,21 +66,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         // straight-forward (`TagEncoding::Direct`) or with a niche (`TagEncoding::Niche`).
         let (tag_scalar_layout, tag_encoding, tag_field) = match op.layout().variants {
             Variants::Single { index } => {
-                // Do some extra checks on enums.
-                if ty.is_enum() {
-                    // Hilariously, `Single` is used even for 0-variant enums.
-                    // (See https://github.com/rust-lang/rust/issues/89765).
-                    if ty.ty_adt_def().unwrap().variants().is_empty() {
-                        throw_ub!(UninhabitedEnumVariantRead(index))
-                    }
+                if op.layout().is_uninhabited() {
                     // For consistency with `write_discriminant`, and to make sure that
                     // `project_downcast` cannot fail due to strange layouts, we declare immediate UB
-                    // for uninhabited variants.
-                    if op.layout().for_variant(self, index).is_uninhabited() {
-                        throw_ub!(UninhabitedEnumVariantRead(index))
-                    }
+                    // for uninhabited enums.
+                    throw_ub!(UninhabitedEnumVariantRead(None));
                 }
-                return interp_ok(index);
+                // Since the type is inhabited, there must be an index.
+                return interp_ok(index.unwrap());
             }
             Variants::Multiple { tag, ref tag_encoding, tag_field, .. } => {
                 (tag, tag_encoding, tag_field)
@@ -199,11 +192,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         // `uninhabited_enum_branching` MIR pass. It also ensures consistency with
         // `write_discriminant`.
         if op.layout().for_variant(self, index).is_uninhabited() {
-            throw_ub!(UninhabitedEnumVariantRead(index))
+            throw_ub!(UninhabitedEnumVariantRead(Some(index)))
         }
         interp_ok(index)
     }
 
+    /// Read discriminant, return the user-visible discriminant.
+    /// Can also legally be called on non-enums (e.g. through the discriminant_value intrinsic)!
     pub fn discriminant_for_variant(
         &self,
         ty: Ty<'tcx>,
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 8e18b243906..832183b42dc 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -342,7 +342,9 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
                 match layout.variants {
                     Variants::Single { index } => {
                         // Inside a variant
-                        PathElem::Field(def.variant(index).fields[FieldIdx::from_usize(field)].name)
+                        PathElem::Field(
+                            def.variant(index.unwrap()).fields[FieldIdx::from_usize(field)].name,
+                        )
                     }
                     Variants::Multiple { .. } => bug!("we handled variants above"),
                 }
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index fbada6ec405..37328470aa7 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -392,7 +392,7 @@ pub enum UndefinedBehaviorInfo<'tcx> {
     /// A discriminant of an uninhabited enum variant is written.
     UninhabitedEnumVariantWritten(VariantIdx),
     /// An uninhabited enum variant is projected.
-    UninhabitedEnumVariantRead(VariantIdx),
+    UninhabitedEnumVariantRead(Option<VariantIdx>),
     /// Trying to set discriminant to the niched variant, but the value does not match.
     InvalidNichedEnumVariantWritten { enum_ty: Ty<'tcx> },
     /// ABI-incompatible argument types.
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index ad1680ed3a2..5f7b30b5d04 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -734,7 +734,7 @@ where
         let layout = match this.variants {
             Variants::Single { index }
                 // If all variants but one are uninhabited, the variant layout is the enum layout.
-                if index == variant_index &&
+                if index == Some(variant_index) &&
                 // Don't confuse variants of uninhabited enums with the enum itself.
                 // For more details see https://github.com/rust-lang/rust/issues/69763.
                 this.fields != FieldsShape::Primitive =>
@@ -743,6 +743,8 @@ where
             }
 
             Variants::Single { index } => {
+                // `Single` variant enums *can* have other variants, but those are uninhabited.
+
                 let tcx = cx.tcx();
                 let typing_env = cx.typing_env();
 
@@ -758,7 +760,7 @@ where
                     _ => bug!("`ty_and_layout_for_variant` on unexpected type {}", this.ty),
                 };
                 tcx.mk_layout(LayoutData {
-                    variants: Variants::Single { index: variant_index },
+                    variants: Variants::Single { index: Some(variant_index) },
                     fields: match NonZero::new(fields) {
                         Some(fields) => FieldsShape::Union(fields),
                         None => FieldsShape::Arbitrary { offsets: IndexVec::new(), memory_index: IndexVec::new() },
@@ -775,7 +777,7 @@ where
             Variants::Multiple { ref variants, .. } => cx.tcx().mk_layout(variants[variant_index].clone()),
         };
 
-        assert_eq!(*layout.variants(), Variants::Single { index: variant_index });
+        assert_eq!(*layout.variants(), Variants::Single { index: Some(variant_index) });
 
         TyAndLayout { ty: this.ty, layout }
     }
@@ -905,7 +907,7 @@ where
                     Variants::Single { index } => TyMaybeWithLayout::Ty(
                         args.as_coroutine()
                             .state_tys(def_id, tcx)
-                            .nth(index.as_usize())
+                            .nth(index.unwrap().as_usize())
                             .unwrap()
                             .nth(i)
                             .unwrap(),
@@ -924,7 +926,8 @@ where
                 ty::Adt(def, args) => {
                     match this.variants {
                         Variants::Single { index } => {
-                            let field = &def.variant(index).fields[FieldIdx::from_usize(i)];
+                            let field =
+                                &def.variant(index.unwrap()).fields[FieldIdx::from_usize(i)];
                             TyMaybeWithLayout::Ty(field.ty(tcx, args))
                         }
 
diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs
index beed007589b..8feb90ff7a0 100644
--- a/compiler/rustc_mir_transform/src/jump_threading.rs
+++ b/compiler/rustc_mir_transform/src/jump_threading.rs
@@ -35,7 +35,6 @@
 //! Likewise, applying the optimisation can create a lot of new MIR, so we bound the instruction
 //! cost by `MAX_COST`.
 
-use rustc_abi::{TagEncoding, Variants};
 use rustc_arena::DroplessArena;
 use rustc_const_eval::const_eval::DummyMachine;
 use rustc_const_eval::interpret::{ImmTy, Immediate, InterpCx, OpTy, Projectable};
@@ -565,31 +564,15 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> {
             StatementKind::SetDiscriminant { box place, variant_index } => {
                 let Some(discr_target) = self.map.find_discr(place.as_ref()) else { return };
                 let enum_ty = place.ty(self.body, self.tcx).ty;
-                // `SetDiscriminant` may be a no-op if the assigned variant is the untagged variant
-                // of a niche encoding. If we cannot ensure that we write to the discriminant, do
-                // nothing.
-                let Ok(enum_layout) = self.ecx.layout_of(enum_ty) else {
+                // `SetDiscriminant` guarantees that the discriminant is now `variant_index`.
+                // Even if the discriminant write does nothing due to niches, it is UB to set the
+                // discriminant when the data does not encode the desired discriminant.
+                let Some(discr) =
+                    self.ecx.discriminant_for_variant(enum_ty, *variant_index).discard_err()
+                else {
                     return;
                 };
-                let writes_discriminant = match enum_layout.variants {
-                    Variants::Single { index } => {
-                        assert_eq!(index, *variant_index);
-                        true
-                    }
-                    Variants::Multiple { tag_encoding: TagEncoding::Direct, .. } => true,
-                    Variants::Multiple {
-                        tag_encoding: TagEncoding::Niche { untagged_variant, .. },
-                        ..
-                    } => *variant_index != untagged_variant,
-                };
-                if writes_discriminant {
-                    let Some(discr) =
-                        self.ecx.discriminant_for_variant(enum_ty, *variant_index).discard_err()
-                    else {
-                        return;
-                    };
-                    self.process_immediate(bb, discr_target, discr, state);
-                }
+                self.process_immediate(bb, discr_target, discr, state);
             }
             // If we expect `lhs ?= true`, we have an opportunity if we assume `lhs == true`.
             StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(
diff --git a/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs b/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs
index 57e255b7c32..0ce3955163b 100644
--- a/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs
+++ b/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs
@@ -54,7 +54,11 @@ fn variant_discriminants<'tcx>(
     tcx: TyCtxt<'tcx>,
 ) -> FxHashSet<u128> {
     match &layout.variants {
-        Variants::Single { index } => {
+        Variants::Single { index: None } => {
+            // Uninhabited, no valid discriminant.
+            FxHashSet::default()
+        }
+        Variants::Single { index: Some(index) } => {
             let mut res = FxHashSet::default();
             res.insert(
                 ty.discriminant_for_variant(tcx, *index)
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs
index af24fd23f50..2717f4ab62f 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs
@@ -164,9 +164,9 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Variants<rustc_abi::FieldIdx, rustc_abi::
 
     fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
         match self {
-            rustc_abi::Variants::Single { index } => {
-                VariantsShape::Single { index: index.stable(tables) }
-            }
+            rustc_abi::Variants::Single { index } => VariantsShape::Single {
+                index: index.unwrap_or(rustc_abi::VariantIdx::from_u32(0)).stable(tables),
+            },
             rustc_abi::Variants::Multiple { tag, tag_encoding, tag_field, variants } => {
                 VariantsShape::Multiple {
                     tag: tag.stable(tables),
diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs
index 83463babc4f..049f4734e7b 100644
--- a/compiler/rustc_transmute/src/layout/tree.rs
+++ b/compiler/rustc_transmute/src/layout/tree.rs
@@ -339,14 +339,12 @@ pub(crate) mod rustc {
 
             match layout.variants() {
                 Variants::Single { index } => {
-                    // Hilariously, `Single` is used even for 0-variant enums;
-                    // `index` is just junk in that case.
-                    if ty.ty_adt_def().unwrap().variants().is_empty() {
-                        Ok(Self::uninhabited())
-                    } else {
+                    if let Some(index) = index {
                         // `Variants::Single` on enums with variants denotes that
                         // the enum delegates its layout to the variant at `index`.
                         layout_of_variant(*index, None)
+                    } else {
+                        Ok(Self::uninhabited())
                     }
                 }
                 Variants::Multiple { tag, tag_encoding, tag_field, .. } => {
@@ -504,7 +502,7 @@ pub(crate) mod rustc {
             ty::Adt(def, args) => {
                 match layout.variants {
                     Variants::Single { index } => {
-                        let field = &def.variant(index).fields[i];
+                        let field = &def.variant(index.unwrap()).fields[i];
                         field.ty(cx.tcx(), args)
                     }
                     // Discriminant field for enums (where applicable).
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 7c7c3803ad9..b393190a493 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -339,7 +339,7 @@ fn layout_of_uncached<'tcx>(
             let largest_niche = if count != 0 { element.largest_niche } else { None };
 
             tcx.mk_layout(LayoutData {
-                variants: Variants::Single { index: FIRST_VARIANT },
+                variants: Variants::Single { index: Some(FIRST_VARIANT) },
                 fields: FieldsShape::Array { stride: element.size, count },
                 backend_repr: abi,
                 largest_niche,
@@ -352,7 +352,7 @@ fn layout_of_uncached<'tcx>(
         ty::Slice(element) => {
             let element = cx.layout_of(element)?;
             tcx.mk_layout(LayoutData {
-                variants: Variants::Single { index: FIRST_VARIANT },
+                variants: Variants::Single { index: Some(FIRST_VARIANT) },
                 fields: FieldsShape::Array { stride: element.size, count: 0 },
                 backend_repr: BackendRepr::Memory { sized: false },
                 largest_niche: None,
@@ -363,7 +363,7 @@ fn layout_of_uncached<'tcx>(
             })
         }
         ty::Str => tcx.mk_layout(LayoutData {
-            variants: Variants::Single { index: FIRST_VARIANT },
+            variants: Variants::Single { index: Some(FIRST_VARIANT) },
             fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
             backend_repr: BackendRepr::Memory { sized: false },
             largest_niche: None,
@@ -534,7 +534,7 @@ fn layout_of_uncached<'tcx>(
             };
 
             tcx.mk_layout(LayoutData {
-                variants: Variants::Single { index: FIRST_VARIANT },
+                variants: Variants::Single { index: Some(FIRST_VARIANT) },
                 fields,
                 backend_repr: abi,
                 largest_niche: e_ly.largest_niche,
@@ -926,7 +926,7 @@ fn coroutine_layout<'tcx>(
                 &ReprOptions::default(),
                 StructKind::Prefixed(prefix_size, prefix_align.abi),
             )?;
-            variant.variants = Variants::Single { index };
+            variant.variants = Variants::Single { index: Some(index) };
 
             let FieldsShape::Arbitrary { offsets, memory_index } = variant.fields else {
                 bug!();
@@ -1105,7 +1105,9 @@ fn variant_info_for_adt<'tcx>(
 
     match layout.variants {
         Variants::Single { index } => {
-            if !adt_def.variants().is_empty() && layout.fields != FieldsShape::Primitive {
+            if let Some(index) = index
+                && layout.fields != FieldsShape::Primitive
+            {
                 debug!("print-type-size `{:#?}` variant {}", layout, adt_def.variant(index).name);
                 let variant_def = &adt_def.variant(index);
                 let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect();
diff --git a/compiler/rustc_ty_utils/src/layout/invariant.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs
index f39b87622f4..7e2375154c0 100644
--- a/compiler/rustc_ty_utils/src/layout/invariant.rs
+++ b/compiler/rustc_ty_utils/src/layout/invariant.rs
@@ -241,63 +241,81 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou
 
     check_layout_abi(cx, layout);
 
-    if let Variants::Multiple { variants, tag, tag_encoding, .. } = &layout.variants {
-        if let TagEncoding::Niche { niche_start, untagged_variant, niche_variants } = tag_encoding {
-            let niche_size = tag.size(cx);
-            assert!(*niche_start <= niche_size.unsigned_int_max());
-            for (idx, variant) in variants.iter_enumerated() {
-                // Ensure all inhabited variants are accounted for.
-                if !variant.is_uninhabited() {
-                    assert!(idx == *untagged_variant || niche_variants.contains(&idx));
-                }
-            }
+    match &layout.variants {
+        Variants::Single { index: None } => {
+            assert!(layout.is_uninhabited());
         }
-        for variant in variants.iter() {
-            // No nested "multiple".
-            assert_matches!(variant.variants, Variants::Single { .. });
-            // Variants should have the same or a smaller size as the full thing,
-            // and same for alignment.
-            if variant.size > layout.size {
-                bug!(
-                    "Type with size {} bytes has variant with size {} bytes: {layout:#?}",
-                    layout.size.bytes(),
-                    variant.size.bytes(),
-                )
+        Variants::Single { index: Some(idx) } => {
+            if let Some(variants) = layout.ty.variant_range(tcx) {
+                assert!(variants.contains(idx));
+            } else {
+                // Types without variants use `0` as dummy variant index.
+                assert!(idx.as_u32() == 0);
             }
-            if variant.align.abi > layout.align.abi {
-                bug!(
-                    "Type with alignment {} bytes has variant with alignment {} bytes: {layout:#?}",
-                    layout.align.abi.bytes(),
-                    variant.align.abi.bytes(),
-                )
-            }
-            // Skip empty variants.
-            if variant.size == Size::ZERO || variant.fields.count() == 0 || variant.is_uninhabited()
+        }
+        Variants::Multiple { variants, tag, tag_encoding, .. } => {
+            if let TagEncoding::Niche { niche_start, untagged_variant, niche_variants } =
+                tag_encoding
             {
-                // These are never actually accessed anyway, so we can skip the coherence check
-                // for them. They also fail that check, since they have
-                // `Aggregate`/`Uninhabited` ABI even when the main type is
-                // `Scalar`/`ScalarPair`. (Note that sometimes, variants with fields have size
-                // 0, and sometimes, variants without fields have non-0 size.)
-                continue;
+                let niche_size = tag.size(cx);
+                assert!(*niche_start <= niche_size.unsigned_int_max());
+                for (idx, variant) in variants.iter_enumerated() {
+                    // Ensure all inhabited variants are accounted for.
+                    if !variant.is_uninhabited() {
+                        assert!(idx == *untagged_variant || niche_variants.contains(&idx));
+                    }
+                }
             }
-            // The top-level ABI and the ABI of the variants should be coherent.
-            let scalar_coherent =
-                |s1: Scalar, s2: Scalar| s1.size(cx) == s2.size(cx) && s1.align(cx) == s2.align(cx);
-            let abi_coherent = match (layout.backend_repr, variant.backend_repr) {
-                (BackendRepr::Scalar(s1), BackendRepr::Scalar(s2)) => scalar_coherent(s1, s2),
-                (BackendRepr::ScalarPair(a1, b1), BackendRepr::ScalarPair(a2, b2)) => {
-                    scalar_coherent(a1, a2) && scalar_coherent(b1, b2)
+            for variant in variants.iter() {
+                // No nested "multiple".
+                assert_matches!(variant.variants, Variants::Single { .. });
+                // Variants should have the same or a smaller size as the full thing,
+                // and same for alignment.
+                if variant.size > layout.size {
+                    bug!(
+                        "Type with size {} bytes has variant with size {} bytes: {layout:#?}",
+                        layout.size.bytes(),
+                        variant.size.bytes(),
+                    )
+                }
+                if variant.align.abi > layout.align.abi {
+                    bug!(
+                        "Type with alignment {} bytes has variant with alignment {} bytes: {layout:#?}",
+                        layout.align.abi.bytes(),
+                        variant.align.abi.bytes(),
+                    )
+                }
+                // Skip empty variants.
+                if variant.size == Size::ZERO
+                    || variant.fields.count() == 0
+                    || variant.is_uninhabited()
+                {
+                    // These are never actually accessed anyway, so we can skip the coherence check
+                    // for them. They also fail that check, since they have
+                    // `Aggregate`/`Uninhabited` ABI even when the main type is
+                    // `Scalar`/`ScalarPair`. (Note that sometimes, variants with fields have size
+                    // 0, and sometimes, variants without fields have non-0 size.)
+                    continue;
+                }
+                // The top-level ABI and the ABI of the variants should be coherent.
+                let scalar_coherent = |s1: Scalar, s2: Scalar| {
+                    s1.size(cx) == s2.size(cx) && s1.align(cx) == s2.align(cx)
+                };
+                let abi_coherent = match (layout.backend_repr, variant.backend_repr) {
+                    (BackendRepr::Scalar(s1), BackendRepr::Scalar(s2)) => scalar_coherent(s1, s2),
+                    (BackendRepr::ScalarPair(a1, b1), BackendRepr::ScalarPair(a2, b2)) => {
+                        scalar_coherent(a1, a2) && scalar_coherent(b1, b2)
+                    }
+                    (BackendRepr::Uninhabited, _) => true,
+                    (BackendRepr::Memory { .. }, _) => true,
+                    _ => false,
+                };
+                if !abi_coherent {
+                    bug!(
+                        "Variant ABI is incompatible with top-level ABI:\nvariant={:#?}\nTop-level: {layout:#?}",
+                        variant
+                    );
                 }
-                (BackendRepr::Uninhabited, _) => true,
-                (BackendRepr::Memory { .. }, _) => true,
-                _ => false,
-            };
-            if !abi_coherent {
-                bug!(
-                    "Variant ABI is incompatible with top-level ABI:\nvariant={:#?}\nTop-level: {layout:#?}",
-                    variant
-                );
             }
         }
     }
diff --git a/compiler/stable_mir/src/abi.rs b/compiler/stable_mir/src/abi.rs
index 2ac30b5aff1..cf28a0c5885 100644
--- a/compiler/stable_mir/src/abi.rs
+++ b/compiler/stable_mir/src/abi.rs
@@ -181,6 +181,7 @@ impl FieldsShape {
 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
 pub enum VariantsShape {
     /// Single enum variants, structs/tuples, unions, and all non-ADTs.
+    // FIXME: needs to become `Option` like in the internal type.
     Single { index: VariantIdx },
 
     /// Enum-likes with more than one inhabited variant: each variant comes with
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
index 0c1f63880cd..08026f11c83 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
@@ -189,7 +189,7 @@ fn layout_of_simd_ty(
     };
 
     Ok(Arc::new(Layout {
-        variants: Variants::Single { index: struct_variant_idx() },
+        variants: Variants::Single { index: Some(struct_variant_idx()) },
         fields,
         backend_repr: BackendRepr::Vector { element: e_abi, count: e_len },
         largest_niche: e_ly.largest_niche,
@@ -305,7 +305,7 @@ pub fn layout_of_ty_query(
             let largest_niche = if count != 0 { element.largest_niche } else { None };
 
             Layout {
-                variants: Variants::Single { index: struct_variant_idx() },
+                variants: Variants::Single { index: Some(struct_variant_idx()) },
                 fields: FieldsShape::Array { stride: element.size, count },
                 backend_repr,
                 largest_niche,
@@ -318,7 +318,7 @@ pub fn layout_of_ty_query(
         TyKind::Slice(element) => {
             let element = db.layout_of_ty(element.clone(), trait_env)?;
             Layout {
-                variants: Variants::Single { index: struct_variant_idx() },
+                variants: Variants::Single { index: Some(struct_variant_idx()) },
                 fields: FieldsShape::Array { stride: element.size, count: 0 },
                 backend_repr: BackendRepr::Memory { sized: false },
                 largest_niche: None,
@@ -329,7 +329,7 @@ pub fn layout_of_ty_query(
             }
         }
         TyKind::Str => Layout {
-            variants: Variants::Single { index: struct_variant_idx() },
+            variants: Variants::Single { index: Some(struct_variant_idx()) },
             fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
             backend_repr: BackendRepr::Memory { sized: false },
             largest_niche: None,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
index d7029651fc1..9375853e915 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
@@ -1639,7 +1639,8 @@ impl Evaluator<'_> {
         };
         match &layout.variants {
             Variants::Single { index } => {
-                let r = self.const_eval_discriminant(self.db.enum_data(e).variants[index.0].0)?;
+                let r = self
+                    .const_eval_discriminant(self.db.enum_data(e).variants[index.unwrap().0].0)?;
                 Ok(r)
             }
             Variants::Multiple { tag, tag_encoding, variants, .. } => {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
index 06719b09f73..43ed6a06f42 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
@@ -335,7 +335,7 @@ pub(crate) fn detect_variant_from_bytes<'a>(
 ) -> Option<(EnumVariantId, &'a Layout)> {
     let (var_id, var_layout) = match &layout.variants {
         hir_def::layout::Variants::Single { index } => {
-            (db.enum_data(e).variants[index.0].0, layout)
+            (db.enum_data(e).variants[index.unwrap().0].0, layout)
         }
         hir_def::layout::Variants::Multiple { tag, tag_encoding, variants, .. } => {
             let size = tag.size(target_data_layout).bytes_usize();
diff --git a/tests/mir-opt/set_no_discriminant.f.JumpThreading.diff b/tests/mir-opt/set_no_discriminant.f.JumpThreading.diff
index 3d9852aef65..992b16fabf6 100644
--- a/tests/mir-opt/set_no_discriminant.f.JumpThreading.diff
+++ b/tests/mir-opt/set_no_discriminant.f.JumpThreading.diff
@@ -10,7 +10,8 @@
           _2 = E::<char>::A;
           discriminant(_2) = 1;
           _1 = discriminant(_2);
-          switchInt(copy _1) -> [0: bb1, otherwise: bb2];
+-         switchInt(copy _1) -> [0: bb1, otherwise: bb2];
++         goto -> bb2;
       }
   
       bb1: {
diff --git a/tests/mir-opt/set_no_discriminant.generic.JumpThreading.diff b/tests/mir-opt/set_no_discriminant.generic.JumpThreading.diff
index c7af1638316..0600b751699 100644
--- a/tests/mir-opt/set_no_discriminant.generic.JumpThreading.diff
+++ b/tests/mir-opt/set_no_discriminant.generic.JumpThreading.diff
@@ -10,7 +10,8 @@
           _2 = E::<T>::A;
           discriminant(_2) = 1;
           _1 = discriminant(_2);
-          switchInt(copy _1) -> [0: bb1, otherwise: bb2];
+-         switchInt(copy _1) -> [0: bb1, otherwise: bb2];
++         goto -> bb2;
       }
   
       bb1: {
diff --git a/tests/mir-opt/set_no_discriminant.rs b/tests/mir-opt/set_no_discriminant.rs
index 586e28ae426..c44575a4d61 100644
--- a/tests/mir-opt/set_no_discriminant.rs
+++ b/tests/mir-opt/set_no_discriminant.rs
@@ -1,5 +1,6 @@
 // `SetDiscriminant` does not actually write anything if the chosen variant is the untagged variant
-// of a niche encoding. Verify that we do not thread over this case.
+// of a niche encoding. However, it is UB to call `SetDiscriminant` with the untagged variant if the
+// value currently encodes a different variant. Verify that we do correctly thread in this case.
 //@ test-mir-pass: JumpThreading
 
 #![feature(custom_mir)]
@@ -16,20 +17,21 @@ enum E<T> {
 #[custom_mir(dialect = "runtime")]
 pub fn f() -> usize {
     // CHECK-LABEL: fn f(
-    // CHECK-NOT: goto
-    // CHECK: switchInt(
-    // CHECK-NOT: goto
+    // CHECK-NOT: switchInt
+    // CHECK: goto
+    // CHECK-NOT: switchInt
     mir! {
         let a: isize;
         let e: E<char>;
         {
             e = E::A;
-            SetDiscriminant(e, 1);
+            SetDiscriminant(e, 1); // UB!
             a = Discriminant(e);
             match a {
                 0 => bb0,
                 _ => bb1,
             }
+
         }
         bb0 = {
             RET = 0;
@@ -46,15 +48,15 @@ pub fn f() -> usize {
 #[custom_mir(dialect = "runtime")]
 pub fn generic<T>() -> usize {
     // CHECK-LABEL: fn generic(
-    // CHECK-NOT: goto
-    // CHECK: switchInt(
-    // CHECK-NOT: goto
+    // CHECK-NOT: switchInt
+    // CHECK: goto
+    // CHECK-NOT: switchInt
     mir! {
         let a: isize;
         let e: E<T>;
         {
             e = E::A;
-            SetDiscriminant(e, 1);
+            SetDiscriminant(e, 1); // UB!
             a = Discriminant(e);
             match a {
                 0 => bb0,
@@ -72,6 +74,7 @@ pub fn generic<T>() -> usize {
     }
 }
 
+// CHECK-LABEL: fn main(
 fn main() {
     assert_eq!(f(), 0);
     assert_eq!(generic::<char>(), 0);
diff --git a/tests/ui/abi/c-zst.aarch64-darwin.stderr b/tests/ui/abi/c-zst.aarch64-darwin.stderr
index 7d384bc875f..aae92bd7dc9 100644
--- a/tests/ui/abi/c-zst.aarch64-darwin.stderr
+++ b/tests/ui/abi/c-zst.aarch64-darwin.stderr
@@ -18,7 +18,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            },
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -45,7 +47,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
diff --git a/tests/ui/abi/c-zst.powerpc-linux.stderr b/tests/ui/abi/c-zst.powerpc-linux.stderr
index 7980710bab6..4ff4a8b90cf 100644
--- a/tests/ui/abi/c-zst.powerpc-linux.stderr
+++ b/tests/ui/abi/c-zst.powerpc-linux.stderr
@@ -18,7 +18,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            },
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -56,7 +58,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
diff --git a/tests/ui/abi/c-zst.s390x-linux.stderr b/tests/ui/abi/c-zst.s390x-linux.stderr
index 7980710bab6..4ff4a8b90cf 100644
--- a/tests/ui/abi/c-zst.s390x-linux.stderr
+++ b/tests/ui/abi/c-zst.s390x-linux.stderr
@@ -18,7 +18,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            },
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -56,7 +58,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
diff --git a/tests/ui/abi/c-zst.sparc64-linux.stderr b/tests/ui/abi/c-zst.sparc64-linux.stderr
index 7980710bab6..4ff4a8b90cf 100644
--- a/tests/ui/abi/c-zst.sparc64-linux.stderr
+++ b/tests/ui/abi/c-zst.sparc64-linux.stderr
@@ -18,7 +18,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            },
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -56,7 +58,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
diff --git a/tests/ui/abi/c-zst.x86_64-linux.stderr b/tests/ui/abi/c-zst.x86_64-linux.stderr
index 7d384bc875f..aae92bd7dc9 100644
--- a/tests/ui/abi/c-zst.x86_64-linux.stderr
+++ b/tests/ui/abi/c-zst.x86_64-linux.stderr
@@ -18,7 +18,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            },
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -45,7 +47,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
diff --git a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr
index 7980710bab6..4ff4a8b90cf 100644
--- a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr
+++ b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr
@@ -18,7 +18,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            },
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -56,7 +58,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
diff --git a/tests/ui/abi/debug.stderr b/tests/ui/abi/debug.stderr
index aa51c42c58d..0cbdf366616 100644
--- a/tests/ui/abi/debug.stderr
+++ b/tests/ui/abi/debug.stderr
@@ -21,7 +21,9 @@ error: fn_abi_of(test) = FnAbi {
                            fields: Primitive,
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -67,7 +69,9 @@ error: fn_abi_of(test) = FnAbi {
                            },
                        ),
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
@@ -124,7 +128,9 @@ error: fn_abi_of(TestFnPtr) = FnAbi {
                                },
                            ),
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -161,7 +167,9 @@ error: fn_abi_of(TestFnPtr) = FnAbi {
                        fields: Primitive,
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
@@ -210,7 +218,9 @@ error: fn_abi_of(test_generic) = FnAbi {
                            fields: Primitive,
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -244,7 +254,9 @@ error: fn_abi_of(test_generic) = FnAbi {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
@@ -292,7 +304,9 @@ error: ABIs are not compatible
                            fields: Primitive,
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -326,7 +340,9 @@ error: ABIs are not compatible
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
@@ -362,7 +378,9 @@ error: ABIs are not compatible
                            fields: Primitive,
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -396,7 +414,9 @@ error: ABIs are not compatible
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
@@ -435,7 +455,9 @@ error: ABIs are not compatible
                            },
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -473,7 +495,9 @@ error: ABIs are not compatible
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
@@ -506,7 +530,9 @@ error: ABIs are not compatible
                            },
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -544,7 +570,9 @@ error: ABIs are not compatible
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
@@ -585,7 +613,9 @@ error: ABIs are not compatible
                            fields: Primitive,
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -619,7 +649,9 @@ error: ABIs are not compatible
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
@@ -655,7 +687,9 @@ error: ABIs are not compatible
                            fields: Primitive,
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -689,7 +723,9 @@ error: ABIs are not compatible
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
@@ -731,7 +767,9 @@ error: ABIs are not compatible
                            fields: Primitive,
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -765,7 +803,9 @@ error: ABIs are not compatible
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
@@ -801,7 +841,9 @@ error: ABIs are not compatible
                            fields: Primitive,
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -835,7 +877,9 @@ error: ABIs are not compatible
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
@@ -902,7 +946,9 @@ error: fn_abi_of(assoc_test) = FnAbi {
                                },
                            ),
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -938,7 +984,9 @@ error: fn_abi_of(assoc_test) = FnAbi {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
diff --git a/tests/ui/abi/sysv64-zst.stderr b/tests/ui/abi/sysv64-zst.stderr
index 8e1791e27d2..920963c6987 100644
--- a/tests/ui/abi/sysv64-zst.stderr
+++ b/tests/ui/abi/sysv64-zst.stderr
@@ -18,7 +18,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            },
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -45,7 +47,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
diff --git a/tests/ui/abi/win64-zst.x86_64-linux.stderr b/tests/ui/abi/win64-zst.x86_64-linux.stderr
index 76d90670eb1..2752555b4f3 100644
--- a/tests/ui/abi/win64-zst.x86_64-linux.stderr
+++ b/tests/ui/abi/win64-zst.x86_64-linux.stderr
@@ -18,7 +18,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            },
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -45,7 +47,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
diff --git a/tests/ui/abi/win64-zst.x86_64-windows-gnu.stderr b/tests/ui/abi/win64-zst.x86_64-windows-gnu.stderr
index 7ee90e24744..19abb5930b1 100644
--- a/tests/ui/abi/win64-zst.x86_64-windows-gnu.stderr
+++ b/tests/ui/abi/win64-zst.x86_64-windows-gnu.stderr
@@ -18,7 +18,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            },
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -56,7 +58,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
diff --git a/tests/ui/abi/win64-zst.x86_64-windows-msvc.stderr b/tests/ui/abi/win64-zst.x86_64-windows-msvc.stderr
index 76d90670eb1..2752555b4f3 100644
--- a/tests/ui/abi/win64-zst.x86_64-windows-msvc.stderr
+++ b/tests/ui/abi/win64-zst.x86_64-windows-msvc.stderr
@@ -18,7 +18,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            },
                            largest_niche: None,
                            variants: Single {
-                               index: 0,
+                               index: Some(
+                                   0,
+                               ),
                            },
                            max_repr_align: None,
                            unadjusted_abi_align: $SOME_ALIGN,
@@ -45,7 +47,9 @@ error: fn_abi_of(pass_zst) = FnAbi {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: $SOME_ALIGN,
diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr
index bd31665dac1..8ae2933c427 100644
--- a/tests/ui/layout/debug.stderr
+++ b/tests/ui/layout/debug.stderr
@@ -57,7 +57,9 @@ error: layout_of(E) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -83,7 +85,9 @@ error: layout_of(E) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -134,7 +138,9 @@ error: layout_of(S) = Layout {
            },
            largest_niche: None,
            variants: Single {
-               index: 0,
+               index: Some(
+                   0,
+               ),
            },
            max_repr_align: None,
            unadjusted_abi_align: Align(4 bytes),
@@ -158,7 +164,9 @@ error: layout_of(U) = Layout {
            ),
            largest_niche: None,
            variants: Single {
-               index: 0,
+               index: Some(
+                   0,
+               ),
            },
            max_repr_align: None,
            unadjusted_abi_align: Align(4 bytes),
@@ -251,7 +259,9 @@ error: layout_of(Result<i32, i32>) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -288,7 +298,9 @@ error: layout_of(Result<i32, i32>) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -321,7 +333,9 @@ error: layout_of(i32) = Layout {
            fields: Primitive,
            largest_niche: None,
            variants: Single {
-               index: 0,
+               index: Some(
+                   0,
+               ),
            },
            max_repr_align: None,
            unadjusted_abi_align: Align(4 bytes),
@@ -345,7 +359,9 @@ error: layout_of(V) = Layout {
            ),
            largest_niche: None,
            variants: Single {
-               index: 0,
+               index: Some(
+                   0,
+               ),
            },
            max_repr_align: None,
            unadjusted_abi_align: Align(2 bytes),
@@ -369,7 +385,9 @@ error: layout_of(W) = Layout {
            ),
            largest_niche: None,
            variants: Single {
-               index: 0,
+               index: Some(
+                   0,
+               ),
            },
            max_repr_align: None,
            unadjusted_abi_align: Align(2 bytes),
@@ -393,7 +411,9 @@ error: layout_of(Y) = Layout {
            ),
            largest_niche: None,
            variants: Single {
-               index: 0,
+               index: Some(
+                   0,
+               ),
            },
            max_repr_align: None,
            unadjusted_abi_align: Align(2 bytes),
@@ -417,7 +437,9 @@ error: layout_of(P1) = Layout {
            ),
            largest_niche: None,
            variants: Single {
-               index: 0,
+               index: Some(
+                   0,
+               ),
            },
            max_repr_align: None,
            unadjusted_abi_align: Align(1 bytes),
@@ -441,7 +463,9 @@ error: layout_of(P2) = Layout {
            ),
            largest_niche: None,
            variants: Single {
-               index: 0,
+               index: Some(
+                   0,
+               ),
            },
            max_repr_align: None,
            unadjusted_abi_align: Align(1 bytes),
@@ -465,7 +489,9 @@ error: layout_of(P3) = Layout {
            ),
            largest_niche: None,
            variants: Single {
-               index: 0,
+               index: Some(
+                   0,
+               ),
            },
            max_repr_align: None,
            unadjusted_abi_align: Align(1 bytes),
@@ -489,7 +515,9 @@ error: layout_of(P4) = Layout {
            ),
            largest_niche: None,
            variants: Single {
-               index: 0,
+               index: Some(
+                   0,
+               ),
            },
            max_repr_align: None,
            unadjusted_abi_align: Align(1 bytes),
@@ -518,7 +546,9 @@ error: layout_of(P5) = Layout {
            ),
            largest_niche: None,
            variants: Single {
-               index: 0,
+               index: Some(
+                   0,
+               ),
            },
            max_repr_align: None,
            unadjusted_abi_align: Align(1 bytes),
@@ -547,7 +577,9 @@ error: layout_of(MaybeUninit<u8>) = Layout {
            ),
            largest_niche: None,
            variants: Single {
-               index: 0,
+               index: Some(
+                   0,
+               ),
            },
            max_repr_align: None,
            unadjusted_abi_align: Align(1 bytes),
diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr
index 59fe667923f..a934f270911 100644
--- a/tests/ui/layout/hexagon-enum.stderr
+++ b/tests/ui/layout/hexagon-enum.stderr
@@ -57,7 +57,9 @@ error: layout_of(A) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -131,7 +133,9 @@ error: layout_of(B) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -205,7 +209,9 @@ error: layout_of(C) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(2 bytes),
@@ -279,7 +285,9 @@ error: layout_of(P) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -353,7 +361,9 @@ error: layout_of(T) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr
index ca041fb539b..8b4e46de845 100644
--- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr
+++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr
@@ -79,7 +79,9 @@ error: layout_of(MissingPayloadField) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -99,7 +101,9 @@ error: layout_of(MissingPayloadField) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -197,7 +201,9 @@ error: layout_of(CommonPayloadField) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -234,7 +240,9 @@ error: layout_of(CommonPayloadField) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -330,7 +338,9 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -366,7 +376,9 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -478,7 +490,9 @@ error: layout_of(NicheFirst) = Layout {
                            },
                        ),
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -498,7 +512,9 @@ error: layout_of(NicheFirst) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -518,7 +534,9 @@ error: layout_of(NicheFirst) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 2,
+                           index: Some(
+                               2,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -630,7 +648,9 @@ error: layout_of(NicheSecond) = Layout {
                            },
                        ),
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -650,7 +670,9 @@ error: layout_of(NicheSecond) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -670,7 +692,9 @@ error: layout_of(NicheSecond) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 2,
+                           index: Some(
+                               2,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr
index bc40a2aa482..92643445595 100644
--- a/tests/ui/layout/issue-96185-overaligned-enum.stderr
+++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr
@@ -51,7 +51,9 @@ error: layout_of(Aligned1) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: Some(
                            Align(8 bytes),
@@ -73,7 +75,9 @@ error: layout_of(Aligned1) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: Some(
                            Align(8 bytes),
@@ -151,7 +155,9 @@ error: layout_of(Aligned2) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: Some(
                            Align(1 bytes),
@@ -173,7 +179,9 @@ error: layout_of(Aligned2) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: Some(
                            Align(1 bytes),
diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr
index bf043af586b..f35cf0dab3d 100644
--- a/tests/ui/layout/thumb-enum.stderr
+++ b/tests/ui/layout/thumb-enum.stderr
@@ -57,7 +57,9 @@ error: layout_of(A) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -131,7 +133,9 @@ error: layout_of(B) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -205,7 +209,9 @@ error: layout_of(C) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(2 bytes),
@@ -279,7 +285,9 @@ error: layout_of(P) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -353,7 +361,9 @@ error: layout_of(T) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr
index d61408098df..4c6f636b267 100644
--- a/tests/ui/layout/zero-sized-array-enum-niche.stderr
+++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr
@@ -55,7 +55,9 @@ error: layout_of(Result<[u32; 0], bool>) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -88,7 +90,9 @@ error: layout_of(Result<[u32; 0], bool>) = Layout {
                            },
                        ),
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -160,7 +164,9 @@ error: layout_of(MultipleAlignments) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(2 bytes),
@@ -184,7 +190,9 @@ error: layout_of(MultipleAlignments) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -217,7 +225,9 @@ error: layout_of(MultipleAlignments) = Layout {
                            },
                        ),
                        variants: Single {
-                           index: 2,
+                           index: Some(
+                               2,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -289,7 +299,9 @@ error: layout_of(Result<[u32; 0], Packed<NonZero<u16>>>) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -322,7 +334,9 @@ error: layout_of(Result<[u32; 0], Packed<NonZero<u16>>>) = Layout {
                            },
                        ),
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -398,7 +412,9 @@ error: layout_of(Result<[u32; 0], Packed<U16IsZero>>) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -431,7 +447,9 @@ error: layout_of(Result<[u32; 0], Packed<U16IsZero>>) = Layout {
                            },
                        ),
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr
index 64a0cb7f31a..08fd4237eeb 100644
--- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr
+++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr
@@ -51,7 +51,9 @@ error: layout_of(Univariant) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -133,7 +135,9 @@ error: layout_of(TwoVariants) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -169,7 +173,9 @@ error: layout_of(TwoVariants) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -241,7 +247,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: Some(
                            Align(8 bytes),
@@ -267,7 +275,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(8 bytes),
diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr
index 5c4daa6d519..473268cac1a 100644
--- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr
+++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr
@@ -51,7 +51,9 @@ error: layout_of(Univariant) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -133,7 +135,9 @@ error: layout_of(TwoVariants) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -169,7 +173,9 @@ error: layout_of(TwoVariants) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -241,7 +247,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: Some(
                            Align(8 bytes),
@@ -267,7 +275,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(8 bytes),
diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr
index 64a0cb7f31a..08fd4237eeb 100644
--- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr
+++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr
@@ -51,7 +51,9 @@ error: layout_of(Univariant) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -133,7 +135,9 @@ error: layout_of(TwoVariants) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -169,7 +173,9 @@ error: layout_of(TwoVariants) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -241,7 +247,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: Some(
                            Align(8 bytes),
@@ -267,7 +275,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(8 bytes),
diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr
index 64a0cb7f31a..08fd4237eeb 100644
--- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr
+++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr
@@ -51,7 +51,9 @@ error: layout_of(Univariant) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -133,7 +135,9 @@ error: layout_of(TwoVariants) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -169,7 +173,9 @@ error: layout_of(TwoVariants) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -241,7 +247,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: Some(
                            Align(8 bytes),
@@ -267,7 +275,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(8 bytes),
diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr
index 75005a64523..1200f120d37 100644
--- a/tests/ui/repr/repr-c-int-dead-variants.stderr
+++ b/tests/ui/repr/repr-c-int-dead-variants.stderr
@@ -51,7 +51,9 @@ error: layout_of(UnivariantU8) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -133,7 +135,9 @@ error: layout_of(TwoVariantsU8) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -169,7 +173,9 @@ error: layout_of(TwoVariantsU8) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -241,7 +247,9 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: Some(
                            Align(8 bytes),
@@ -267,7 +275,9 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(8 bytes),
diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr
index 0eed7c2ce1c..9954471968d 100644
--- a/tests/ui/type/pattern_types/range_patterns.stderr
+++ b/tests/ui/type/pattern_types/range_patterns.stderr
@@ -32,7 +32,9 @@ error: layout_of(NonZero<u32>) = Layout {
                },
            ),
            variants: Single {
-               index: 0,
+               index: Some(
+                   0,
+               ),
            },
            max_repr_align: None,
            unadjusted_abi_align: Align(4 bytes),
@@ -69,7 +71,9 @@ error: layout_of((u32) is 1..=) = Layout {
                },
            ),
            variants: Single {
-               index: 0,
+               index: Some(
+                   0,
+               ),
            },
            max_repr_align: None,
            unadjusted_abi_align: Align(4 bytes),
@@ -133,7 +137,9 @@ error: layout_of(Option<(u32) is 1..=>) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -172,7 +178,9 @@ error: layout_of(Option<(u32) is 1..=>) = Layout {
                            },
                        ),
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -241,7 +249,9 @@ error: layout_of(Option<NonZero<u32>>) = Layout {
                        },
                        largest_niche: None,
                        variants: Single {
-                           index: 0,
+                           index: Some(
+                               0,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(1 bytes),
@@ -280,7 +290,9 @@ error: layout_of(Option<NonZero<u32>>) = Layout {
                            },
                        ),
                        variants: Single {
-                           index: 1,
+                           index: Some(
+                               1,
+                           ),
                        },
                        max_repr_align: None,
                        unadjusted_abi_align: Align(4 bytes),
@@ -329,7 +341,9 @@ error: layout_of(NonZeroU32New) = Layout {
                },
            ),
            variants: Single {
-               index: 0,
+               index: Some(
+                   0,
+               ),
            },
            max_repr_align: None,
            unadjusted_abi_align: Align(4 bytes),