From 09a7b75339d620f6bb2cb1455577860d35a5e365 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Tue, 12 Aug 2025 21:27:43 -0500 Subject: [PATCH 1/6] Prepare offset_of for non-absent uninhabited variants in using tagless enum representations --- compiler/rustc_abi/src/callconv.rs | 2 +- compiler/rustc_abi/src/layout.rs | 14 ++++----- compiler/rustc_abi/src/layout/coroutine.rs | 2 +- compiler/rustc_abi/src/layout/simple.rs | 16 +++++----- compiler/rustc_abi/src/lib.rs | 19 ++++++++++-- .../src/discriminant.rs | 8 ++--- compiler/rustc_codegen_gcc/src/type_of.rs | 6 ++-- .../src/debuginfo/metadata/enums/cpp_like.rs | 6 ++-- .../src/debuginfo/metadata/enums/mod.rs | 2 +- .../src/debuginfo/metadata/enums/native.rs | 2 +- compiler/rustc_codegen_llvm/src/type_of.rs | 6 ++-- .../rustc_codegen_ssa/src/debuginfo/mod.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/analyze.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/operand.rs | 16 ++++++---- compiler/rustc_codegen_ssa/src/mir/place.rs | 4 +-- .../src/interpret/discriminant.rs | 6 ++-- .../src/interpret/validity.rs | 8 ++--- .../rustc_const_eval/src/interpret/visitor.rs | 2 +- .../src/util/check_validity_requirement.rs | 2 +- compiler/rustc_middle/src/ty/layout.rs | 29 ++++++++++++------- .../rustc_mir_transform/src/check_enums.rs | 4 +-- compiler/rustc_mir_transform/src/gvn.rs | 2 +- .../rustc_mir_transform/src/large_enums.rs | 2 +- .../src/unreachable_enum_branching.rs | 4 +-- compiler/rustc_public/src/abi.rs | 21 ++++++++++++-- .../src/unstable/convert/stable/abi.rs | 11 ++++--- .../rustc_target/src/callconv/loongarch.rs | 2 +- compiler/rustc_target/src/callconv/riscv.rs | 2 +- compiler/rustc_target/src/callconv/x86_64.rs | 2 +- compiler/rustc_transmute/src/layout/tree.rs | 8 ++--- compiler/rustc_ty_utils/src/layout.rs | 5 ++-- .../rustc_ty_utils/src/layout/invariant.rs | 4 +-- src/tools/miri/src/helpers.rs | 2 +- .../crates/hir-ty/src/mir/eval.rs | 8 ++--- .../rust-analyzer/crates/hir-ty/src/utils.rs | 4 +-- tests/ui/abi/c-zst.aarch64-darwin.stderr | 2 ++ tests/ui/abi/c-zst.powerpc-linux.stderr | 2 ++ tests/ui/abi/c-zst.s390x-linux.stderr | 2 ++ tests/ui/abi/c-zst.sparc64-linux.stderr | 2 ++ tests/ui/abi/c-zst.x86_64-linux.stderr | 2 ++ .../ui/abi/c-zst.x86_64-pc-windows-gnu.stderr | 2 ++ tests/ui/abi/debug.generic.stderr | 24 +++++++++++++++ tests/ui/abi/debug.loongarch64.stderr | 24 +++++++++++++++ tests/ui/abi/debug.riscv64.stderr | 24 +++++++++++++++ .../x86-64-sysv64-arg-ext.other.stderr | 12 ++++++++ tests/ui/abi/pass-indirectly-attr.stderr | 4 +++ tests/ui/abi/sysv64-zst.stderr | 2 ++ .../pass-by-value-abi.aarch64.stderr | 2 ++ .../pass-by-value-abi.x86_64.stderr | 6 ++++ .../enum-discriminant/wrapping_niche.stderr | 6 ++++ tests/ui/layout/debug.stderr | 16 ++++++++++ tests/ui/layout/hexagon-enum.stderr | 5 ++++ ...-scalarpair-payload-might-be-uninit.stderr | 12 ++++++++ .../issue-96185-overaligned-enum.stderr | 4 +++ tests/ui/layout/thumb-enum.stderr | 5 ++++ .../layout/zero-sized-array-enum-niche.stderr | 9 ++++++ ...-variants.aarch64-unknown-linux-gnu.stderr | 5 ++++ ...-c-dead-variants.armebv7r-none-eabi.stderr | 5 ++++ ...-dead-variants.i686-pc-windows-msvc.stderr | 5 ++++ ...d-variants.x86_64-unknown-linux-gnu.stderr | 5 ++++ tests/ui/repr/repr-c-int-dead-variants.stderr | 5 ++++ tests/ui/type/pattern_types/non_null.stderr | 4 +++ .../ui/type/pattern_types/or_patterns.stderr | 2 ++ .../type/pattern_types/range_patterns.stderr | 9 ++++++ 64 files changed, 348 insertions(+), 94 deletions(-) diff --git a/compiler/rustc_abi/src/callconv.rs b/compiler/rustc_abi/src/callconv.rs index 5b43a6c5881d5..5384f177188f6 100644 --- a/compiler/rustc_abi/src/callconv.rs +++ b/compiler/rustc_abi/src/callconv.rs @@ -145,7 +145,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { let (mut result, mut total) = from_fields_at(*self, Size::ZERO)?; match &self.variants { - Variants::Single { .. } | Variants::Empty => {} + Variants::Single { .. } | Variants::Empty { .. } => {} Variants::Multiple { variants, .. } => { // Treat enum variants like union members. // HACK(eddyb) pretend the `enum` field (discriminant) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 4f1594d02a82e..228a98f49c5bc 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -130,7 +130,7 @@ impl LayoutCalculator { element.size.checked_mul(count, &self.cx).ok_or(LayoutCalculatorError::SizeOverflow)?; Ok(LayoutData { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: VariantIdx::new(0), variants: None }, fields: FieldsShape::Array { stride: element.size, count }, backend_repr: BackendRepr::Memory { sized: count_if_sized.is_some() }, largest_niche: element.largest_niche.filter(|_| count != 0), @@ -442,7 +442,7 @@ impl LayoutCalculator { .fold(repr.field_shuffle_seed, |acc, seed| acc.wrapping_add(seed)); Ok(LayoutData { - variants: Variants::Single { index: only_variant_idx }, + variants: Variants::Single { index: only_variant_idx, variants: None }, fields: FieldsShape::Union(union_field_count), backend_repr, largest_niche: None, @@ -483,7 +483,7 @@ impl LayoutCalculator { }; let mut st = self.univariant(&variants[v], repr, kind)?; - st.variants = Variants::Single { index: v }; + st.variants = Variants::Single { index: v, variants: None }; if is_special_no_niche { let hide_niches = |scalar: &mut _| match scalar { @@ -591,7 +591,7 @@ impl LayoutCalculator { .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: j, variants: None }; align = align.max(st.align.abi); max_repr_align = max_repr_align.max(st.max_repr_align); @@ -823,7 +823,7 @@ impl LayoutCalculator { repr, StructKind::Prefixed(min_ity.size(), prefix_align), )?; - st.variants = Variants::Single { index: i }; + st.variants = Variants::Single { index: i, variants: None }; // 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() { @@ -1422,7 +1422,7 @@ impl LayoutCalculator { let seed = field_seed.wrapping_add(repr.field_shuffle_seed); Ok(LayoutData { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: VariantIdx::new(0), variants: None }, fields: FieldsShape::Arbitrary { offsets, in_memory_order }, backend_repr: abi, largest_niche, @@ -1518,7 +1518,7 @@ where let size = size.align_to(align); Ok(LayoutData { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: VariantIdx::new(0), variants: None }, fields: FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), in_memory_order: [FieldIdx::new(0)].into(), diff --git a/compiler/rustc_abi/src/layout/coroutine.rs b/compiler/rustc_abi/src/layout/coroutine.rs index 815cf1e28a08c..07925576f5edc 100644 --- a/compiler/rustc_abi/src/layout/coroutine.rs +++ b/compiler/rustc_abi/src/layout/coroutine.rs @@ -230,7 +230,7 @@ pub(super) fn layout< &ReprOptions::default(), StructKind::Prefixed(prefix_size, prefix_align.abi), )?; - variant.variants = Variants::Single { index }; + variant.variants = Variants::Single { index, variants: None }; let FieldsShape::Arbitrary { offsets, in_memory_order } = variant.fields else { unreachable!(); diff --git a/compiler/rustc_abi/src/layout/simple.rs b/compiler/rustc_abi/src/layout/simple.rs index 3784611b157be..20964782905dd 100644 --- a/compiler/rustc_abi/src/layout/simple.rs +++ b/compiler/rustc_abi/src/layout/simple.rs @@ -13,7 +13,7 @@ impl LayoutData { pub fn unit(cx: &C, sized: bool) -> Self { let dl = cx.data_layout(); LayoutData { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: VariantIdx::new(0), variants: None }, fields: FieldsShape::Arbitrary { offsets: IndexVec::new(), in_memory_order: IndexVec::new(), @@ -33,7 +33,7 @@ impl LayoutData { let dl = cx.data_layout(); // This is also used for uninhabited enums, so we use `Variants::Empty`. LayoutData { - variants: Variants::Empty, + variants: Variants::Empty { variants: None }, fields: FieldsShape::Primitive, backend_repr: BackendRepr::Memory { sized: true }, largest_niche: None, @@ -75,7 +75,7 @@ impl LayoutData { .wrapping_add((range.end as u64).rotate_right(16)); LayoutData { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: VariantIdx::new(0), variants: None }, fields: FieldsShape::Primitive, backend_repr: BackendRepr::Scalar(scalar), largest_niche, @@ -105,7 +105,7 @@ impl LayoutData { let combined_seed = a.size(dl).bytes().wrapping_add(b.size(dl).bytes()); LayoutData { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: VariantIdx::new(0), variants: None }, fields: FieldsShape::Arbitrary { offsets: [Size::ZERO, b_offset].into(), in_memory_order: [FieldIdx::new(0), FieldIdx::new(1)].into(), @@ -121,14 +121,14 @@ impl LayoutData { } } - /// Returns a dummy layout for an uninhabited variant. + /// Returns a dummy layout for an absent variant. /// - /// Uninhabited variants get pruned as part of the layout calculation, + /// Absent variants get pruned as part of the layout calculation, /// so this can be used after the fact to reconstitute a layout. - pub fn uninhabited_variant(cx: &C, index: VariantIdx, fields: usize) -> Self { + pub fn absent_variant(cx: &C, index: VariantIdx, fields: usize) -> Self { let dl = cx.data_layout(); LayoutData { - variants: Variants::Single { index }, + variants: Variants::Single { index, variants: None }, fields: match NonZero::new(fields) { Some(fields) => FieldsShape::Union(fields), None => FieldsShape::Arbitrary { diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 061ad8617893c..f35dc87cb1077 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1857,12 +1857,27 @@ impl BackendRepr { #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] pub enum Variants { /// A type with no valid variants. Must be uninhabited. - Empty, + /// + /// We still need to hold variant layout information for `offset_of!` + /// on uninhabited enum variants with non-zero-sized fields. + Empty { + /// Always `None` for non-enums. + /// For enums, this is `None` if all variants are "absent" + /// (have no non-1-ZST fields), and is `Some` otherwise. + variants: Option>>, + }, - /// Single enum variants, structs/tuples, unions, and all non-ADTs. + /// Enums with one inhabited variant and no tag, structs/tuples, unions, and all non-ADTs. + /// + /// We still need to hold variant layout information for `offset_of!` + /// on uninhabited enum variants with non-zero-sized fields. Single { /// Always `0` for types that cannot have multiple variants. index: VariantIdx, + /// Always `None` for non-enums. + /// For enums, this is `None` if all uninhabited variants are "absent" + /// (have no non-1-ZST fields), and is `Some` otherwise. + variants: Option>>, }, /// Enum-likes with more than one variant: each variant comes with diff --git a/compiler/rustc_codegen_cranelift/src/discriminant.rs b/compiler/rustc_codegen_cranelift/src/discriminant.rs index a08b0e0cbfc59..86e4e03f97345 100644 --- a/compiler/rustc_codegen_cranelift/src/discriminant.rs +++ b/compiler/rustc_codegen_cranelift/src/discriminant.rs @@ -18,8 +18,8 @@ pub(crate) fn codegen_set_discriminant<'tcx>( return; } match layout.variants { - Variants::Empty => unreachable!("we already handled uninhabited types"), - Variants::Single { index } => { + Variants::Empty { .. } => unreachable!("we already handled uninhabited types"), + Variants::Single { index, .. } => { assert_eq!(index, variant_index); } Variants::Multiple { @@ -86,8 +86,8 @@ pub(crate) fn codegen_get_discriminant<'tcx>( } let (tag_scalar, tag_field, tag_encoding) = match &layout.variants { - Variants::Empty => unreachable!("we already handled uninhabited types"), - Variants::Single { index } => { + Variants::Empty { .. } => unreachable!("we already handled uninhabited types"), + Variants::Single { index, .. } => { let discr_val = layout .ty .discriminant_for_variant(fx.tcx, *index) diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs index 68fca5a17ad34..a0ee00501bc77 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -101,14 +101,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, .. }) = (layout.ty.kind(), &layout.variants) && 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, .. }) = (layout.ty.kind(), &layout.variants) { write!(&mut name, "::{}", ty::CoroutineArgs::variant_name(index)).unwrap(); @@ -232,7 +232,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, .. } => Some(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 4ecc3086e1bdf..d200b1f8cb0c5 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::Empty => { + Variants::Empty { .. } => { // We don't generate any members for uninhabited types. return smallvec![]; } - Variants::Single { index: variant_index } => build_single_variant_union_fields( + Variants::Single { index: variant_index, .. } => build_single_variant_union_fields( cx, enum_adt_def, enum_type_and_layout, @@ -300,7 +300,7 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>( ) } Variants::Single { .. } - | Variants::Empty + | Variants::Empty { .. } | Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, .. } => { bug!( "Encountered coroutine with non-direct-tag layout: {:?}", diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index caff358607974..a998e9ec41018 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -393,7 +393,7 @@ fn compute_discriminant_value<'ll, 'tcx>( variant_index: VariantIdx, ) -> DiscrResult { match enum_type_and_layout.layout.variants() { - &Variants::Single { .. } | &Variants::Empty => DiscrResult::NoDiscriminant, + &Variants::Single { .. } | &Variants::Empty { .. } => DiscrResult::NoDiscriminant, &Variants::Multiple { tag_encoding: TagEncoding::Direct, .. } => DiscrResult::Value( enum_type_and_layout.ty.discriminant_for_variant(cx.tcx, variant_index).unwrap().val, ), diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs index 1ae6e6e5eecab..9bc6607428114 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs @@ -357,7 +357,7 @@ fn build_discr_member_di_node<'ll, 'tcx>( match enum_or_coroutine_type_and_layout.layout.variants() { // A single-variant or no-variant enum has no discriminant. - &Variants::Single { .. } | &Variants::Empty => None, + &Variants::Single { .. } | &Variants::Empty { .. } => None, &Variants::Multiple { tag_field, .. } => { let tag_base_type = tag_base_type(cx.tcx, enum_or_coroutine_type_and_layout); diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index 1ed06fbd28219..bffb6adc8e6e9 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -45,14 +45,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, .. }) = (layout.ty.kind(), &layout.variants) { 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, .. }) = (layout.ty.kind(), &layout.variants) { write!(&mut name, "::{}", ty::CoroutineArgs::variant_name(index)).unwrap(); @@ -230,7 +230,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, .. } => Some(index), _ => None, }; if let Some(llty) = cx.type_lowering.borrow().get(&(self.ty, variant_index)) { diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs b/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs index 7c62c03d574c1..83a293c2a2deb 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs @@ -66,7 +66,7 @@ fn tag_base_type_opt<'tcx>( match enum_type_and_layout.layout.variants() { // A single-variant or no-variant enum has no discriminant. - Variants::Single { .. } | Variants::Empty => None, + Variants::Single { .. } | Variants::Empty { .. } => None, Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, tag, .. } => { // Niche tags are always normalized to unsized integers of the correct size. diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index de755d5617801..90d3986a76306 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -144,7 +144,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> LocalAnalyzer<'a, 'b, 'tcx, Bx> layout = match *elem { mir::PlaceElem::Field(fidx, ..) => layout.field(self.fx.cx, fidx.as_usize()), mir::PlaceElem::Downcast(_, vidx) - if let abi::Variants::Single { index: single_variant } = + if let abi::Variants::Single { index: single_variant, .. } = layout.variants && vidx == single_variant => { diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 78dfecdd1818c..42970384ad78f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -434,8 +434,8 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { } let (tag_scalar, tag_encoding, tag_field) = match self.layout.variants { - Variants::Empty => unreachable!("we already handled uninhabited types"), - Variants::Single { index } => { + Variants::Empty { .. } => unreachable!("we already handled uninhabited types"), + Variants::Single { index, .. } => { let discr_val = if let Some(discr) = self.layout.ty.discriminant_for_variant(bx.tcx(), index) { discr.val @@ -986,10 +986,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { o = o.extract_field(self, bx, f.index()); } mir::PlaceElem::Downcast(_, vidx) => { - debug_assert_eq!( - o.layout.variants, - abi::Variants::Single { index: vidx }, - ); + if cfg!(debug_assertions) { + match o.layout.variants { + abi::Variants::Single { index, .. } if index == vidx => {} + ref v => bug!( + "expected Variants::Single {{ index: {vidx:?}, .. }}, got {v:?}" + ), + } + } let layout = o.layout.for_variant(bx.cx(), vidx); o = OperandRef { layout, ..o } } diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index d62e622b6fed3..704132a74f240 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -474,8 +474,8 @@ pub(super) fn codegen_tag_value<'tcx, V>( } Ok(match layout.variants { - Variants::Empty => unreachable!("we already handled uninhabited types"), - Variants::Single { index } => { + Variants::Empty { .. } => unreachable!("we already handled uninhabited types"), + Variants::Single { index, .. } => { assert_eq!(index, variant_index); None } diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index b7e7f65c95c78..6e97684380609 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -65,10 +65,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // We use "tag" to refer to how the discriminant is encoded in memory, which can be either // straight-forward (`TagEncoding::Direct`) or with a niche (`TagEncoding::Niche`). let (tag_scalar_layout, tag_encoding, tag_field) = match op.layout().variants { - Variants::Empty => { + Variants::Empty { .. } => { throw_ub!(UninhabitedEnumVariantRead(None)); } - Variants::Single { index } => { + Variants::Single { 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 @@ -241,7 +241,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } match layout.variants { - abi::Variants::Empty => unreachable!("we already handled uninhabited types"), + abi::Variants::Empty { .. } => unreachable!("we already handled uninhabited types"), abi::Variants::Single { .. } => { // The tag of a `Single` enum is like the tag of the niched // variant: there's no tag as the discriminant is encoded diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 5d8ae42f5eccd..57e01825e580d 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -303,7 +303,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { }; } } - Variants::Single { .. } | Variants::Empty => {} + Variants::Single { .. } | Variants::Empty { .. } => {} } // Now we know we are projecting to a field, so figure out which one. @@ -341,11 +341,11 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { ty::Adt(def, ..) if def.is_enum() => { // we might be projecting *to* a variant, or to a field *in* a variant. match layout.variants { - Variants::Single { index } => { + Variants::Single { index, .. } => { // Inside a variant PathElem::Field(def.variant(index).fields[FieldIdx::from_usize(field)].name) } - Variants::Empty => panic!("there is no field in Variants::Empty types"), + Variants::Empty { .. } => panic!("there is no field in Variants::Empty types"), Variants::Multiple { .. } => bug!("we handled variants above"), } } @@ -1016,7 +1016,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { } // Don't forget potential other variants. match &layout.variants { - Variants::Single { .. } | Variants::Empty => { + Variants::Single { .. } | Variants::Empty { .. } => { // Fully handled above. } Variants::Multiple { variants, .. } => { diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index a8d472bc2ea23..aabccd8fd9718 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -187,7 +187,7 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { self.visit_variant(v, idx, &inner)?; } // For single-variant layouts, we already did everything there is to do. - Variants::Single { .. } | Variants::Empty => {} + Variants::Single { .. } | Variants::Empty { .. } => {} } interp_ok(()) diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs index 939f9151680bb..5f5b6130e0c8c 100644 --- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs +++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs @@ -159,7 +159,7 @@ fn check_validity_requirement_lax<'tcx>( } match &this.variants { - Variants::Empty => return Ok(false), + Variants::Empty { .. } => return Ok(false), Variants::Single { .. } => { // All fields of this single variant have already been checked above, there is nothing // else to do. diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 81b8142d03f37..7b4d0cbe92913 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -776,14 +776,17 @@ where ) -> TyAndLayout<'tcx> { let layout = match this.variants { // If all variants but one are uninhabited, the variant layout is the enum layout. - Variants::Single { index } if index == variant_index => { + Variants::Single { index, .. } if index == variant_index => { return this; } - Variants::Single { .. } | Variants::Empty => { + Variants::Single { variants: None, .. } | Variants::Empty { variants: None } => { // Single-variant and no-variant enums *can* have other variants, but those are - // uninhabited. Produce a layout that has the right fields for that variant, so that - // the rest of the compiler can project fields etc as usual. + // uninhabited. For such enums, `variants` will only be `None` if all such + // variants are "absent", i.e. only consist of 1-ZSTs. + // (If any is not absent, then `variants` would be `Some` and we'd not be here.) + // Produce a layout that has the right fields for that variant, all at offset 0, + // so that the rest of the compiler can project fields etc as usual. let tcx = cx.tcx(); let typing_env = cx.typing_env(); @@ -800,15 +803,17 @@ where ty::Adt(def, _) => def.variant(variant_index).fields.len(), _ => bug!("`ty_and_layout_for_variant` on unexpected type {}", this.ty), }; - tcx.mk_layout(LayoutData::uninhabited_variant(cx, variant_index, fields)) + tcx.mk_layout(LayoutData::absent_variant(cx, variant_index, fields)) } - Variants::Multiple { ref variants, .. } => { + Variants::Single { variants: Some(ref variants), .. } + | Variants::Empty { variants: Some(ref variants) } + | 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: variant_index, variants: None }); TyAndLayout { ty: this.ty, layout } } @@ -949,8 +954,8 @@ where ), ty::Coroutine(def_id, args) => match this.variants { - Variants::Empty => unreachable!(), - Variants::Single { index } => TyMaybeWithLayout::Ty( + Variants::Empty { .. } => unreachable!(), + Variants::Single { index, .. } => TyMaybeWithLayout::Ty( args.as_coroutine() .state_tys(def_id, tcx) .nth(index.as_usize()) @@ -971,11 +976,13 @@ where // ADTs. ty::Adt(def, args) => { match this.variants { - Variants::Single { index } => { + Variants::Single { index, .. } => { let field = &def.variant(index).fields[FieldIdx::from_usize(i)]; TyMaybeWithLayout::Ty(field.ty(tcx, args)) } - Variants::Empty => panic!("there is no field in Variants::Empty types"), + Variants::Empty { .. } => { + panic!("there is no field in Variants::Empty types") + } // Discriminant field for enums (where applicable). Variants::Multiple { tag, .. } => { diff --git a/compiler/rustc_mir_transform/src/check_enums.rs b/compiler/rustc_mir_transform/src/check_enums.rs index 12447dc7cbb0c..af6df52bbb1a7 100644 --- a/compiler/rustc_mir_transform/src/check_enums.rs +++ b/compiler/rustc_mir_transform/src/check_enums.rs @@ -186,10 +186,10 @@ impl<'a, 'tcx> Visitor<'tcx> for EnumFinder<'a, 'tcx> { }; match enum_layout.variants { - Variants::Empty if op_layout.is_uninhabited() => return, + Variants::Empty { .. } if op_layout.is_uninhabited() => return, // An empty enum that tries to be constructed from an inhabited value, this // is never correct. - Variants::Empty => { + Variants::Empty { .. } => { // The enum layout is uninhabited but we construct it from sth inhabited. // This is always UB. self.enums.push(EnumCheckType::Uninhabited); diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 820998eed1005..014eb12fde5e4 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1675,7 +1675,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { variant: VariantIdx, ) -> Option<(FieldIdx, Ty<'tcx>)> { if let Ok(layout) = self.ecx.layout_of(ty) - && let abi::Variants::Single { index } = layout.variants + && let abi::Variants::Single { index, .. } = layout.variants && index == variant && let Some((field_idx, field_layout)) = layout.non_1zst_field(&self.ecx) && layout.size == field_layout.size diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index 89bd91e7013da..2044a22c21391 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -179,7 +179,7 @@ impl EnumSizeOpt { }; let layout = tcx.layout_of(typing_env.as_query_input(ty)).ok()?; let variants = match &layout.variants { - Variants::Single { .. } | Variants::Empty => return None, + Variants::Single { .. } | Variants::Empty { .. } => return None, Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, .. } => return None, Variants::Multiple { variants, .. } if variants.len() <= 1 => return None, diff --git a/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs b/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs index 6ccec5b6f2129..95cfc8d9ddd59 100644 --- a/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs +++ b/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs @@ -55,11 +55,11 @@ fn variant_discriminants<'tcx>( tcx: TyCtxt<'tcx>, ) -> FxHashSet { match &layout.variants { - Variants::Empty => { + Variants::Empty { .. } => { // Uninhabited, no valid discriminant. FxHashSet::default() } - Variants::Single { index } => { + Variants::Single { index, .. } => { let mut res = FxHashSet::default(); res.insert( ty.discriminant_for_variant(tcx, *index) diff --git a/compiler/rustc_public/src/abi.rs b/compiler/rustc_public/src/abi.rs index aced39059f6ba..1ce3ecd583aea 100644 --- a/compiler/rustc_public/src/abi.rs +++ b/compiler/rustc_public/src/abi.rs @@ -173,10 +173,27 @@ impl FieldsShape { #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum VariantsShape { /// A type with no valid variants. Must be uninhabited. - Empty, + /// + /// We still need to hold variant layout information for `offset_of!` + /// on uninhabited enum variants with non-zero-sized fields. + Empty { + /// Always `None` for non-enums. + /// For enums, this is `None` if all variants are "absent" + /// (have no non-1-ZST fields), and is `Some` otherwise. + variants: Option>, + }, /// Single enum variants, structs/tuples, unions, and all non-ADTs. - Single { index: VariantIdx }, + /// + /// We still need to hold variant layout information for `offset_of!` + /// on uninhabited enum variants with non-zero-sized fields. + Single { + index: VariantIdx, + /// Always `None` for non-enums. + /// For enums, this is `None` if all uninhabited variants are "absent" + /// (have no non-1-ZST fields), and is `Some` otherwise. + variants: Option>, + }, /// Enum-likes with more than one inhabited variant: each variant comes with /// a *discriminant* (usually the same as the variant index but the user can diff --git a/compiler/rustc_public/src/unstable/convert/stable/abi.rs b/compiler/rustc_public/src/unstable/convert/stable/abi.rs index 03328d084ee94..b6ce8b39de2f0 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/abi.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/abi.rs @@ -203,10 +203,13 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Variants, ) -> Self::T { match self { - rustc_abi::Variants::Single { index } => { - VariantsShape::Single { index: index.stable(tables, cx) } - } - rustc_abi::Variants::Empty => VariantsShape::Empty, + rustc_abi::Variants::Single { index, variants } => VariantsShape::Single { + index: index.stable(tables, cx), + variants: variants.as_ref().map(|v| v.iter().as_slice().stable(tables, cx)), + }, + rustc_abi::Variants::Empty { variants } => VariantsShape::Empty { + variants: variants.as_ref().map(|v| v.iter().as_slice().stable(tables, cx)), + }, rustc_abi::Variants::Multiple { tag, tag_encoding, tag_field, variants } => { VariantsShape::Multiple { tag: tag.stable(tables, cx), diff --git a/compiler/rustc_target/src/callconv/loongarch.rs b/compiler/rustc_target/src/callconv/loongarch.rs index d74d15446eaf6..041b5de295976 100644 --- a/compiler/rustc_target/src/callconv/loongarch.rs +++ b/compiler/rustc_target/src/callconv/loongarch.rs @@ -127,7 +127,7 @@ where FieldsShape::Arbitrary { .. } => { match arg_layout.variants { Variants::Multiple { .. } => return Err(CannotUseFpConv), - Variants::Single { .. } | Variants::Empty => (), + Variants::Single { .. } | Variants::Empty { .. } => (), } for i in arg_layout.fields.index_by_increasing_offset() { let field = arg_layout.field(cx, i); diff --git a/compiler/rustc_target/src/callconv/riscv.rs b/compiler/rustc_target/src/callconv/riscv.rs index f166b83305165..f77a0b893e6a4 100644 --- a/compiler/rustc_target/src/callconv/riscv.rs +++ b/compiler/rustc_target/src/callconv/riscv.rs @@ -132,7 +132,7 @@ where FieldsShape::Arbitrary { .. } => { match arg_layout.variants { Variants::Multiple { .. } => return Err(CannotUseFpConv), - Variants::Single { .. } | Variants::Empty => (), + Variants::Single { .. } | Variants::Empty { .. } => (), } for i in arg_layout.fields.index_by_increasing_offset() { let field = arg_layout.field(cx, i); diff --git a/compiler/rustc_target/src/callconv/x86_64.rs b/compiler/rustc_target/src/callconv/x86_64.rs index 8fab4e444228c..2d77f3ca82a2d 100644 --- a/compiler/rustc_target/src/callconv/x86_64.rs +++ b/compiler/rustc_target/src/callconv/x86_64.rs @@ -68,7 +68,7 @@ where } match &layout.variants { - Variants::Single { .. } | Variants::Empty => {} + Variants::Single { .. } | Variants::Empty { .. } => {} Variants::Multiple { variants, .. } => { // Treat enum variants like union members. for variant_idx in variants.indices() { diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index 1202ed2384315..8d1922ae9b57c 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -445,8 +445,8 @@ pub(crate) mod rustc { }; match layout.variants() { - Variants::Empty => Ok(Self::uninhabited()), - Variants::Single { index } => { + Variants::Empty { .. } => Ok(Self::uninhabited()), + Variants::Single { index, .. } => { // `Variants::Single` on enums with variants denotes that // the enum delegates its layout to the variant at `index`. layout_of_variant(*index, None) @@ -607,11 +607,11 @@ pub(crate) mod rustc { match ty.kind() { ty::Adt(def, args) => { match layout.variants { - Variants::Single { index } => { + Variants::Single { index, .. } => { let field = &def.variant(index).fields[i]; field.ty(cx.tcx(), args) } - Variants::Empty => panic!("there is no field in Variants::Empty types"), + Variants::Empty { .. } => panic!("there is no field in Variants::Empty types"), // Discriminant field for enums (where applicable). Variants::Multiple { tag, .. } => { assert_eq!(i.as_usize(), 0); diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 62f3667ad7f4f..09d6809081cab 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -868,9 +868,10 @@ fn variant_info_for_adt<'tcx>( }; match layout.variants { - Variants::Empty => (vec![], None), + // FIXME: handle uninhabited non-absent enum variants. + Variants::Empty { .. } => (vec![], None), - Variants::Single { index } => { + Variants::Single { index, .. } => { 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 b013902f3fe3c..73d1957f52b6a 100644 --- a/compiler/rustc_ty_utils/src/layout/invariant.rs +++ b/compiler/rustc_ty_utils/src/layout/invariant.rs @@ -257,10 +257,10 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou check_layout_abi(cx, layout); match &layout.variants { - Variants::Empty => { + Variants::Empty { .. } => { assert!(layout.is_uninhabited()); } - Variants::Single { index } => { + Variants::Single { index, .. } => { if let Some(variants) = layout.ty.variant_range(tcx) { assert!(variants.contains(index)); } else { diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index f4fc478481a7a..020b424e48931 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -617,7 +617,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `UnsafeCell` action. (self.unsafe_cell_action)(v) } - Variants::Single { .. } | Variants::Empty => { + Variants::Single { .. } | Variants::Empty { .. } => { // Proceed further, try to find where exactly that `UnsafeCell` // is hiding. self.walk_value(v) 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 5de08313f418d..ab941ba1809bf 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 @@ -838,7 +838,7 @@ impl<'db> Evaluator<'db> { ProjectionElem::Field(Either::Left(f)) => { let layout = self.layout(prev_ty)?; let variant_layout = match &layout.variants { - Variants::Single { .. } | Variants::Empty => &layout, + Variants::Single { .. } | Variants::Empty { .. } => &layout, Variants::Multiple { variants, .. } => { &variants[match f.parent { hir_def::VariantId::EnumVariantId(it) => { @@ -1665,8 +1665,8 @@ impl<'db> Evaluator<'db> { return Ok(0); }; match &layout.variants { - Variants::Empty => unreachable!(), - Variants::Single { index } => { + Variants::Empty { .. } => unreachable!(), + Variants::Single { index, .. } => { let r = self.const_eval_discriminant(e.enum_variants(self.db).variants[index.0].0)?; Ok(r) @@ -1829,7 +1829,7 @@ impl<'db> Evaluator<'db> { } let layout = self.layout_adt(adt, subst)?; Ok(match &layout.variants { - Variants::Single { .. } | Variants::Empty => (layout.size.bytes_usize(), layout, None), + Variants::Single { .. } | Variants::Empty { .. } => (layout.size.bytes_usize(), layout, None), Variants::Multiple { variants, tag, tag_encoding, .. } => { let enum_variant_id = match it { VariantId::EnumVariantId(it) => it, 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 7dd73f1e7aa01..c8b01d5d4292f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs @@ -190,8 +190,8 @@ pub(crate) fn detect_variant_from_bytes<'a>( e: EnumId, ) -> Option<(EnumVariantId, &'a Layout)> { let (var_id, var_layout) = match &layout.variants { - hir_def::layout::Variants::Empty => unreachable!(), - hir_def::layout::Variants::Single { index } => { + hir_def::layout::Variants::Empty { .. } => unreachable!(), + hir_def::layout::Variants::Single { index, .. } => { (e.enum_variants(db).variants[index.0].0, layout) } hir_def::layout::Variants::Multiple { tag, tag_encoding, variants, .. } => { diff --git a/tests/ui/abi/c-zst.aarch64-darwin.stderr b/tests/ui/abi/c-zst.aarch64-darwin.stderr index 6d2ac90c0c975..77651db7e070b 100644 --- a/tests/ui/abi/c-zst.aarch64-darwin.stderr +++ b/tests/ui/abi/c-zst.aarch64-darwin.stderr @@ -19,6 +19,7 @@ error: fn_abi_of(pass_zst) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -47,6 +48,7 @@ error: fn_abi_of(pass_zst) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, 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 f297aa984dd2e..aa86c31dfb74d 100644 --- a/tests/ui/abi/c-zst.powerpc-linux.stderr +++ b/tests/ui/abi/c-zst.powerpc-linux.stderr @@ -19,6 +19,7 @@ error: fn_abi_of(pass_zst) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -58,6 +59,7 @@ error: fn_abi_of(pass_zst) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, 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 f297aa984dd2e..aa86c31dfb74d 100644 --- a/tests/ui/abi/c-zst.s390x-linux.stderr +++ b/tests/ui/abi/c-zst.s390x-linux.stderr @@ -19,6 +19,7 @@ error: fn_abi_of(pass_zst) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -58,6 +59,7 @@ error: fn_abi_of(pass_zst) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, 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 f297aa984dd2e..aa86c31dfb74d 100644 --- a/tests/ui/abi/c-zst.sparc64-linux.stderr +++ b/tests/ui/abi/c-zst.sparc64-linux.stderr @@ -19,6 +19,7 @@ error: fn_abi_of(pass_zst) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -58,6 +59,7 @@ error: fn_abi_of(pass_zst) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, 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 6d2ac90c0c975..77651db7e070b 100644 --- a/tests/ui/abi/c-zst.x86_64-linux.stderr +++ b/tests/ui/abi/c-zst.x86_64-linux.stderr @@ -19,6 +19,7 @@ error: fn_abi_of(pass_zst) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -47,6 +48,7 @@ error: fn_abi_of(pass_zst) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, 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 f297aa984dd2e..aa86c31dfb74d 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 @@ -19,6 +19,7 @@ error: fn_abi_of(pass_zst) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -58,6 +59,7 @@ error: fn_abi_of(pass_zst) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, diff --git a/tests/ui/abi/debug.generic.stderr b/tests/ui/abi/debug.generic.stderr index 8a031b79780a8..e9b74057e75e1 100644 --- a/tests/ui/abi/debug.generic.stderr +++ b/tests/ui/abi/debug.generic.stderr @@ -22,6 +22,7 @@ error: fn_abi_of(test) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -69,6 +70,7 @@ error: fn_abi_of(test) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -127,6 +129,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -165,6 +168,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -215,6 +219,7 @@ error: fn_abi_of(test_generic) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -250,6 +255,7 @@ error: fn_abi_of(test_generic) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -299,6 +305,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -334,6 +341,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -371,6 +379,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -406,6 +415,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -446,6 +456,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -485,6 +496,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -519,6 +531,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -558,6 +571,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -600,6 +614,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -635,6 +650,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -672,6 +688,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -707,6 +724,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -750,6 +768,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -785,6 +804,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -822,6 +842,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -857,6 +878,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -931,6 +953,7 @@ error: fn_abi_of(assoc_test) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -968,6 +991,7 @@ error: fn_abi_of(assoc_test) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, diff --git a/tests/ui/abi/debug.loongarch64.stderr b/tests/ui/abi/debug.loongarch64.stderr index 00bd3febde4ec..8b1de55f9cce2 100644 --- a/tests/ui/abi/debug.loongarch64.stderr +++ b/tests/ui/abi/debug.loongarch64.stderr @@ -22,6 +22,7 @@ error: fn_abi_of(test) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -69,6 +70,7 @@ error: fn_abi_of(test) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -127,6 +129,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -165,6 +168,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -215,6 +219,7 @@ error: fn_abi_of(test_generic) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -250,6 +255,7 @@ error: fn_abi_of(test_generic) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -299,6 +305,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -334,6 +341,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -371,6 +379,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -406,6 +415,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -446,6 +456,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -485,6 +496,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -519,6 +531,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -558,6 +571,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -600,6 +614,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -635,6 +650,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -672,6 +688,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -707,6 +724,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -750,6 +768,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -785,6 +804,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -822,6 +842,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -857,6 +878,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -931,6 +953,7 @@ error: fn_abi_of(assoc_test) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -968,6 +991,7 @@ error: fn_abi_of(assoc_test) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, diff --git a/tests/ui/abi/debug.riscv64.stderr b/tests/ui/abi/debug.riscv64.stderr index 00bd3febde4ec..8b1de55f9cce2 100644 --- a/tests/ui/abi/debug.riscv64.stderr +++ b/tests/ui/abi/debug.riscv64.stderr @@ -22,6 +22,7 @@ error: fn_abi_of(test) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -69,6 +70,7 @@ error: fn_abi_of(test) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -127,6 +129,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -165,6 +168,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -215,6 +219,7 @@ error: fn_abi_of(test_generic) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -250,6 +255,7 @@ error: fn_abi_of(test_generic) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -299,6 +305,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -334,6 +341,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -371,6 +379,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -406,6 +415,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -446,6 +456,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -485,6 +496,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -519,6 +531,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -558,6 +571,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -600,6 +614,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -635,6 +650,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -672,6 +688,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -707,6 +724,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -750,6 +768,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -785,6 +804,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -822,6 +842,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -857,6 +878,7 @@ error: ABIs are not compatible uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -931,6 +953,7 @@ error: fn_abi_of(assoc_test) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -968,6 +991,7 @@ error: fn_abi_of(assoc_test) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, diff --git a/tests/ui/abi/numbers-arithmetic/x86-64-sysv64-arg-ext.other.stderr b/tests/ui/abi/numbers-arithmetic/x86-64-sysv64-arg-ext.other.stderr index 9bb2ab45d9841..e8da59d09a31c 100644 --- a/tests/ui/abi/numbers-arithmetic/x86-64-sysv64-arg-ext.other.stderr +++ b/tests/ui/abi/numbers-arithmetic/x86-64-sysv64-arg-ext.other.stderr @@ -22,6 +22,7 @@ error: fn_abi_of(i8) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -60,6 +61,7 @@ error: fn_abi_of(i8) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -111,6 +113,7 @@ error: fn_abi_of(u8) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -149,6 +152,7 @@ error: fn_abi_of(u8) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -200,6 +204,7 @@ error: fn_abi_of(i16) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), @@ -238,6 +243,7 @@ error: fn_abi_of(i16) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), @@ -289,6 +295,7 @@ error: fn_abi_of(u16) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), @@ -327,6 +334,7 @@ error: fn_abi_of(u16) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), @@ -378,6 +386,7 @@ error: fn_abi_of(i32) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -416,6 +425,7 @@ error: fn_abi_of(i32) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -467,6 +477,7 @@ error: fn_abi_of(u32) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -505,6 +516,7 @@ error: fn_abi_of(u32) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), diff --git a/tests/ui/abi/pass-indirectly-attr.stderr b/tests/ui/abi/pass-indirectly-attr.stderr index 03fe9ea46a4b7..12a4cfe141b12 100644 --- a/tests/ui/abi/pass-indirectly-attr.stderr +++ b/tests/ui/abi/pass-indirectly-attr.stderr @@ -32,6 +32,7 @@ error: fn_abi_of(extern_c) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -71,6 +72,7 @@ error: fn_abi_of(extern_c) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -114,6 +116,7 @@ error: fn_abi_of(extern_rust) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -171,6 +174,7 @@ error: fn_abi_of(extern_rust) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), diff --git a/tests/ui/abi/sysv64-zst.stderr b/tests/ui/abi/sysv64-zst.stderr index 82d3793c35328..95334a8158929 100644 --- a/tests/ui/abi/sysv64-zst.stderr +++ b/tests/ui/abi/sysv64-zst.stderr @@ -19,6 +19,7 @@ error: fn_abi_of(pass_zst) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, @@ -47,6 +48,7 @@ error: fn_abi_of(pass_zst) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, diff --git a/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr b/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr index 584416f58f861..43f54d0db39f8 100644 --- a/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr +++ b/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr @@ -19,6 +19,7 @@ error: fn_abi_of(take_va_list) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), @@ -58,6 +59,7 @@ error: fn_abi_of(take_va_list) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), diff --git a/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr b/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr index b5e0e8589af16..669f4bfbef3ec 100644 --- a/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr +++ b/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr @@ -19,6 +19,7 @@ error: fn_abi_of(take_va_list) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), @@ -58,6 +59,7 @@ error: fn_abi_of(take_va_list) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -97,6 +99,7 @@ error: fn_abi_of(take_va_list_sysv64) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), @@ -136,6 +139,7 @@ error: fn_abi_of(take_va_list_sysv64) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -177,6 +181,7 @@ error: fn_abi_of(take_va_list_win64) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), @@ -216,6 +221,7 @@ error: fn_abi_of(take_va_list_win64) = FnAbi { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), diff --git a/tests/ui/enum-discriminant/wrapping_niche.stderr b/tests/ui/enum-discriminant/wrapping_niche.stderr index 9b97ad4aeac7e..e5328a34dd2d7 100644 --- a/tests/ui/enum-discriminant/wrapping_niche.stderr +++ b/tests/ui/enum-discriminant/wrapping_niche.stderr @@ -58,6 +58,7 @@ error: layout_of(UnsignedAroundZero) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), @@ -79,6 +80,7 @@ error: layout_of(UnsignedAroundZero) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), @@ -100,6 +102,7 @@ error: layout_of(UnsignedAroundZero) = Layout { uninhabited: false, variants: Single { index: 2, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), @@ -176,6 +179,7 @@ error: layout_of(SignedAroundZero) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), @@ -197,6 +201,7 @@ error: layout_of(SignedAroundZero) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), @@ -218,6 +223,7 @@ error: layout_of(SignedAroundZero) = Layout { uninhabited: false, variants: Single { index: 2, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index 79ce21eb532b0..2dc2a961999d2 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -58,6 +58,7 @@ error: layout_of(E) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -87,6 +88,7 @@ error: layout_of(E) = Layout { uninhabited: true, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -140,6 +142,7 @@ error: layout_of(S) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -165,6 +168,7 @@ error: layout_of(U) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -259,6 +263,7 @@ error: layout_of(Result) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -297,6 +302,7 @@ error: layout_of(Result) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -332,6 +338,7 @@ error: layout_of(i32) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -357,6 +364,7 @@ error: layout_of(V) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), @@ -382,6 +390,7 @@ error: layout_of(W) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), @@ -407,6 +416,7 @@ error: layout_of(Y) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), @@ -432,6 +442,7 @@ error: layout_of(P1) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -457,6 +468,7 @@ error: layout_of(P2) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -482,6 +494,7 @@ error: layout_of(P3) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -507,6 +520,7 @@ error: layout_of(P4) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -537,6 +551,7 @@ error: layout_of(P5) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -567,6 +582,7 @@ error: layout_of(MaybeUninit) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, 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 20e0a8642a66f..6aa3bbf008006 100644 --- a/tests/ui/layout/hexagon-enum.stderr +++ b/tests/ui/layout/hexagon-enum.stderr @@ -58,6 +58,7 @@ error: layout_of(A) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -134,6 +135,7 @@ error: layout_of(B) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -210,6 +212,7 @@ error: layout_of(C) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), @@ -286,6 +289,7 @@ error: layout_of(P) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -362,6 +366,7 @@ error: layout_of(T) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, 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 61cfcbdc07f75..f820e28c76c02 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 @@ -80,6 +80,7 @@ error: layout_of(MissingPayloadField) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -101,6 +102,7 @@ error: layout_of(MissingPayloadField) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -201,6 +203,7 @@ error: layout_of(CommonPayloadField) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -239,6 +242,7 @@ error: layout_of(CommonPayloadField) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -337,6 +341,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -374,6 +379,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -488,6 +494,7 @@ error: layout_of(NicheFirst) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -509,6 +516,7 @@ error: layout_of(NicheFirst) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -530,6 +538,7 @@ error: layout_of(NicheFirst) = Layout { uninhabited: false, variants: Single { index: 2, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -644,6 +653,7 @@ error: layout_of(NicheSecond) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -665,6 +675,7 @@ error: layout_of(NicheSecond) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -686,6 +697,7 @@ error: layout_of(NicheSecond) = Layout { uninhabited: false, variants: Single { index: 2, + variants: None, }, 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 64e2f42c042f1..74cc5083bc422 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.stderr +++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr @@ -52,6 +52,7 @@ error: layout_of(Aligned1) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: Some( Align(8 bytes), @@ -75,6 +76,7 @@ error: layout_of(Aligned1) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: Some( Align(8 bytes), @@ -155,6 +157,7 @@ error: layout_of(Aligned2) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: Some( Align(1 bytes), @@ -178,6 +181,7 @@ error: layout_of(Aligned2) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: Some( Align(1 bytes), diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr index a6e603652123b..9eaa5957b1184 100644 --- a/tests/ui/layout/thumb-enum.stderr +++ b/tests/ui/layout/thumb-enum.stderr @@ -58,6 +58,7 @@ error: layout_of(A) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -134,6 +135,7 @@ error: layout_of(B) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -210,6 +212,7 @@ error: layout_of(C) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), @@ -286,6 +289,7 @@ error: layout_of(P) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -362,6 +366,7 @@ error: layout_of(T) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, 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 23f9092778085..4e436a816b78c 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.stderr +++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr @@ -56,6 +56,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -90,6 +91,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -164,6 +166,7 @@ error: layout_of(MultipleAlignments) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), @@ -189,6 +192,7 @@ error: layout_of(MultipleAlignments) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -223,6 +227,7 @@ error: layout_of(MultipleAlignments) = Layout { uninhabited: false, variants: Single { index: 2, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -297,6 +302,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -331,6 +337,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -409,6 +416,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -443,6 +451,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, 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 62f6ec92d493c..7f193d11f4e74 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 @@ -68,6 +68,7 @@ error: layout_of(Univariant) = Layout { uninhabited: true, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -166,6 +167,7 @@ error: layout_of(TwoVariants) = Layout { uninhabited: true, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -203,6 +205,7 @@ error: layout_of(TwoVariants) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -279,6 +282,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { uninhabited: true, variants: Single { index: 0, + variants: None, }, max_repr_align: Some( Align(8 bytes), @@ -306,6 +310,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, 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 3e0efad974cd2..d08600c20a326 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 @@ -68,6 +68,7 @@ error: layout_of(Univariant) = Layout { uninhabited: true, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -166,6 +167,7 @@ error: layout_of(TwoVariants) = Layout { uninhabited: true, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -203,6 +205,7 @@ error: layout_of(TwoVariants) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -279,6 +282,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { uninhabited: true, variants: Single { index: 0, + variants: None, }, max_repr_align: Some( Align(8 bytes), @@ -306,6 +310,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, 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 62f6ec92d493c..7f193d11f4e74 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 @@ -68,6 +68,7 @@ error: layout_of(Univariant) = Layout { uninhabited: true, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -166,6 +167,7 @@ error: layout_of(TwoVariants) = Layout { uninhabited: true, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -203,6 +205,7 @@ error: layout_of(TwoVariants) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -279,6 +282,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { uninhabited: true, variants: Single { index: 0, + variants: None, }, max_repr_align: Some( Align(8 bytes), @@ -306,6 +310,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, 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 62f6ec92d493c..7f193d11f4e74 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 @@ -68,6 +68,7 @@ error: layout_of(Univariant) = Layout { uninhabited: true, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -166,6 +167,7 @@ error: layout_of(TwoVariants) = Layout { uninhabited: true, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -203,6 +205,7 @@ error: layout_of(TwoVariants) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -279,6 +282,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { uninhabited: true, variants: Single { index: 0, + variants: None, }, max_repr_align: Some( Align(8 bytes), @@ -306,6 +310,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, 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 b25e4a9b7b6f5..f31aac5438185 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.stderr +++ b/tests/ui/repr/repr-c-int-dead-variants.stderr @@ -68,6 +68,7 @@ error: layout_of(UnivariantU8) = Layout { uninhabited: true, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -166,6 +167,7 @@ error: layout_of(TwoVariantsU8) = Layout { uninhabited: true, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -203,6 +205,7 @@ error: layout_of(TwoVariantsU8) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -279,6 +282,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { uninhabited: true, variants: Single { index: 0, + variants: None, }, max_repr_align: Some( Align(8 bytes), @@ -306,6 +310,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), diff --git a/tests/ui/type/pattern_types/non_null.stderr b/tests/ui/type/pattern_types/non_null.stderr index 0847af2d086fa..97b8d9e9facfe 100644 --- a/tests/ui/type/pattern_types/non_null.stderr +++ b/tests/ui/type/pattern_types/non_null.stderr @@ -35,6 +35,7 @@ error: layout_of((*const T) is !null) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), @@ -102,6 +103,7 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -144,6 +146,7 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), @@ -204,6 +207,7 @@ error: layout_of((*const [u8]) is !null) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), diff --git a/tests/ui/type/pattern_types/or_patterns.stderr b/tests/ui/type/pattern_types/or_patterns.stderr index 7206c570187b4..d277d6b567efb 100644 --- a/tests/ui/type/pattern_types/or_patterns.stderr +++ b/tests/ui/type/pattern_types/or_patterns.stderr @@ -74,6 +74,7 @@ error: layout_of((i8) is (i8::MIN..=-1 | 1..)) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -119,6 +120,7 @@ error: layout_of((i8) is (i8::MIN..=-2 | 0..)) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index 6c9acac7eb7b8..4006eb571e589 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -33,6 +33,7 @@ error: layout_of(NonZero) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -78,6 +79,7 @@ error: layout_of((u32) is 1..) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -143,6 +145,7 @@ error: layout_of(Option<(u32) is 1..>) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -183,6 +186,7 @@ error: layout_of(Option<(u32) is 1..>) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -254,6 +258,7 @@ error: layout_of(Option>) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -294,6 +299,7 @@ error: layout_of(Option>) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -345,6 +351,7 @@ error: layout_of(NonZeroU32New) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -418,6 +425,7 @@ error: layout_of((i8) is -10..=10) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -463,6 +471,7 @@ error: layout_of((i8) is i8::MIN..=0) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), From acdd124b8e029784805a34df7e4818ec18d7ebd0 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Tue, 12 Aug 2025 21:15:17 -0500 Subject: [PATCH 2/6] Add/extend tests for offset_of! for enums with uninhabited variants --- tests/ui/offset-of/offset-of-enum-valid.rs | 61 ++++++++++++++++++++++ tests/ui/offset-of/offset-of-enum.rs | 7 +++ tests/ui/offset-of/offset-of-enum.stderr | 20 ++++--- 3 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 tests/ui/offset-of/offset-of-enum-valid.rs diff --git a/tests/ui/offset-of/offset-of-enum-valid.rs b/tests/ui/offset-of/offset-of-enum-valid.rs new file mode 100644 index 0000000000000..154b5f9b39531 --- /dev/null +++ b/tests/ui/offset-of/offset-of-enum-valid.rs @@ -0,0 +1,61 @@ +//@ run-pass +#![feature(offset_of_enum)] +#![allow(unused)] + +use std::mem::offset_of; + +enum Never {} + +#[repr(align(2))] +struct AlignedNever(Never); + +enum Alpha { + One(u8), + Two(u8), + Three(u8, u8, Never), +} + +enum Beta { + One(u8), + Two(u8, Never), +} + +enum Gamma { + One(u32), + Two(u8, u8, u8, Never), +} + +enum Delta { + One(u8, Never), + Two(u8, u8, Never), +} + +fn main() { + assert!(offset_of!(Alpha, One.0) <= size_of::() - size_of::()); + assert!(offset_of!(Alpha, Two.0) <= size_of::() - size_of::()); + assert!(offset_of!(Alpha, Three.0) <= size_of::() - size_of::()); + assert!(offset_of!(Alpha, Three.1) <= size_of::() - size_of::()); + assert!(offset_of!(Alpha, Three.2) <= size_of::() - size_of::()); + assert!(offset_of!(Alpha, Three.0) != offset_of!(Alpha, Three.1)); + + assert!(offset_of!(Beta, One.0) <= size_of::() - size_of::()); + assert!(offset_of!(Beta, Two.0) <= size_of::() - size_of::()); + assert!(offset_of!(Beta, Two.1) <= size_of::() - size_of::()); + + assert!(offset_of!(Gamma, One.0) <= size_of::() - size_of::()); + assert!(offset_of!(Gamma, Two.0) <= size_of::() - size_of::()); + assert!(offset_of!(Gamma, Two.1) <= size_of::() - size_of::()); + assert!(offset_of!(Gamma, Two.2) <= size_of::() - size_of::()); + assert!(offset_of!(Gamma, Two.3) <= size_of::() - size_of::()); + assert!(offset_of!(Gamma, Two.0) != offset_of!(Gamma, Two.1)); + assert!(offset_of!(Gamma, Two.0) != offset_of!(Gamma, Two.2)); + assert!(offset_of!(Gamma, Two.1) != offset_of!(Gamma, Two.2)); + + assert!(offset_of!(Delta, One.0) <= size_of::() - size_of::()); + assert!(offset_of!(Delta, One.1) <= size_of::() - size_of::()); + assert!(offset_of!(Delta, Two.0) <= size_of::() - size_of::()); + assert!(offset_of!(Delta, Two.0) <= size_of::() - size_of::()); + assert!(offset_of!(Delta, Two.1) <= size_of::() - size_of::()); + assert!(offset_of!(Delta, Two.2) <= size_of::() - size_of::()); + assert!(offset_of!(Delta, Two.0) != offset_of!(Delta, Two.1)); +} diff --git a/tests/ui/offset-of/offset-of-enum.rs b/tests/ui/offset-of/offset-of-enum.rs index 10f1353ac31f6..12ee0fa28731f 100644 --- a/tests/ui/offset-of/offset-of-enum.rs +++ b/tests/ui/offset-of/offset-of-enum.rs @@ -3,9 +3,12 @@ use std::mem::offset_of; +enum Never {} + enum Alpha { One(u8), Two(u8), + Three(u8, u8, Never), } fn main() { @@ -16,4 +19,8 @@ fn main() { offset_of!(Alpha, Two.foo); //~ ERROR no field named `foo` on enum variant `Alpha::Two` offset_of!(Alpha, NonExistent); //~ ERROR no variant named `NonExistent` found for enum `Alpha` offset_of!(Beta, One); //~ ERROR cannot find type `Beta` in this scope + offset_of!(Alpha, Three.0); + offset_of!(Alpha, Three.1); + offset_of!(Alpha, Three.2); + offset_of!(Alpha, Three.2.NonExistent); //~ ERROR no variant named `NonExistent` found for enum `Never` } diff --git a/tests/ui/offset-of/offset-of-enum.stderr b/tests/ui/offset-of/offset-of-enum.stderr index cc1b1aa10d244..c9faaeabc1c2f 100644 --- a/tests/ui/offset-of/offset-of-enum.stderr +++ b/tests/ui/offset-of/offset-of-enum.stderr @@ -1,5 +1,5 @@ error[E0573]: expected type, found variant `Alpha::One` - --> $DIR/offset-of-enum.rs:12:16 + --> $DIR/offset-of-enum.rs:15:16 | LL | offset_of!(Alpha::One, 0); | ^^^^^^^^^^ @@ -8,19 +8,19 @@ LL | offset_of!(Alpha::One, 0); | help: try using the variant's enum: `Alpha` error[E0425]: cannot find type `Beta` in this scope - --> $DIR/offset-of-enum.rs:18:16 + --> $DIR/offset-of-enum.rs:21:16 | LL | offset_of!(Beta, One); | ^^^^ not found in this scope error[E0795]: `One` is an enum variant; expected field at end of `offset_of` - --> $DIR/offset-of-enum.rs:13:23 + --> $DIR/offset-of-enum.rs:16:23 | LL | offset_of!(Alpha, One); | ^^^ enum variant error[E0609]: no field named `1` on enum variant `Alpha::Two` - --> $DIR/offset-of-enum.rs:15:23 + --> $DIR/offset-of-enum.rs:18:23 | LL | offset_of!(Alpha, Two.1); | ^^^ - ...does not have this field @@ -28,7 +28,7 @@ LL | offset_of!(Alpha, Two.1); | this enum variant... error[E0609]: no field named `foo` on enum variant `Alpha::Two` - --> $DIR/offset-of-enum.rs:16:23 + --> $DIR/offset-of-enum.rs:19:23 | LL | offset_of!(Alpha, Two.foo); | ^^^ --- ...does not have this field @@ -36,12 +36,18 @@ LL | offset_of!(Alpha, Two.foo); | this enum variant... error[E0599]: no variant named `NonExistent` found for enum `Alpha` - --> $DIR/offset-of-enum.rs:17:23 + --> $DIR/offset-of-enum.rs:20:23 | LL | offset_of!(Alpha, NonExistent); | ^^^^^^^^^^^ variant not found -error: aborting due to 6 previous errors +error[E0599]: no variant named `NonExistent` found for enum `Never` + --> $DIR/offset-of-enum.rs:25:31 + | +LL | offset_of!(Alpha, Three.2.NonExistent); + | ^^^^^^^^^^^ variant not found + +error: aborting due to 7 previous errors Some errors have detailed explanations: E0425, E0573, E0599, E0609, E0795. For more information about an error, try `rustc --explain E0425`. From a250bab2cd4a53f1fdc8362fc351df5657b657b4 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Tue, 12 Aug 2025 22:37:52 -0500 Subject: [PATCH 3/6] Add tests for Result layout. The comments will be accurate after the commits which add the relevant layout optimizations. --- tests/ui/consts/const-eval/ub-enum.rs | 5 +++++ tests/ui/consts/const-eval/ub-enum.stderr | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/ui/consts/const-eval/ub-enum.rs b/tests/ui/consts/const-eval/ub-enum.rs index 9c78bb6efed7e..b60116aa553f7 100644 --- a/tests/ui/consts/const-eval/ub-enum.rs +++ b/tests/ui/consts/const-eval/ub-enum.rs @@ -100,6 +100,11 @@ const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem: const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; //~^ ERROR uninhabited enum variant +// All variants have same-size data but only one inhabited. +// Use `0` as constant to make behavior endianness-independent. +const GOOD_SEMIINHABITED_WITH_DATA1: Result = unsafe { mem::transmute(0u64) }; +const GOOD_SEMIINHABITED_WITH_DATA2: Result<(i32, !), i32> = unsafe { mem::transmute(1u64) }; + const TEST_ICE_89765: () = { // This is a regression test for https://github.com/rust-lang/rust/issues/89765. unsafe { diff --git a/tests/ui/consts/const-eval/ub-enum.stderr b/tests/ui/consts/const-eval/ub-enum.stderr index 1efd93832291e..ffb6d2bc27e5a 100644 --- a/tests/ui/consts/const-eval/ub-enum.stderr +++ b/tests/ui/consts/const-eval/ub-enum.stderr @@ -121,7 +121,7 @@ LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { | ^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_UNINHABITED_WITH_DATA2` failed here error[E0080]: read discriminant of an uninhabited enum variant - --> $DIR/ub-enum.rs:106:9 + --> $DIR/ub-enum.rs:111:9 | LL | std::mem::discriminant(&*(&() as *const () as *const Never)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `TEST_ICE_89765` failed inside this call From 1d4c51074fc42320dde75ccfe779069aae95413b Mon Sep 17 00:00:00 2001 From: Zachary S Date: Tue, 12 Aug 2025 21:52:56 -0500 Subject: [PATCH 4/6] Add more enum layout tests. The comments will be accurate after the commits which add the relevant layout optimizations. --- tests/ui/layout/enum.rs | 93 +++++++++++++++ tests/ui/layout/enum.stderr | 228 +++++++++++++++++++++++++++++++++++- 2 files changed, 320 insertions(+), 1 deletion(-) diff --git a/tests/ui/layout/enum.rs b/tests/ui/layout/enum.rs index 005faf8ee508d..236f19a75c278 100644 --- a/tests/ui/layout/enum.rs +++ b/tests/ui/layout/enum.rs @@ -22,3 +22,96 @@ enum ScalarPairDifferingSign { //~ERROR: abi: ScalarPair A(u8), B(i8), } + +// Enums with only a single inhabited variant can be laid out as just that variant, +// if the uninhabited variants are all "absent" (only have 1-ZST fields) +#[rustc_layout(size, abi)] +enum AbsentVariantUntagged { //~ERROR: size: Size(4 bytes) + //~^ ERROR: abi: Scalar(Initialized + A(i32), + B((), !), +} + +// Even if uninhabited variants are not absent, the enum can still be laid out without +// a tag. +#[rustc_layout(size, abi)] +enum UninhabitedVariantUntagged { //~ERROR: size: Size(8 bytes) + //~^ ERROR: abi: ScalarPair(Initialized + A(i32), + B(i32, !), +} + +// A single-inhabited-variant enum may still be laid out with a tag, +// if that leads to a better niche for the same size layout. +// This enum uses the tagged representation, since the untagged representation would be +// the same size, but without a niche. +#[rustc_layout(size, abi)] +enum UninhabitedVariantUntaggedBigger { //~ERROR: size: Size(8 bytes) + //~^ ERROR: abi: Memory + A(i32), + B([u8; 5], !), +} + +#[rustc_layout(size, abi)] +enum UninhabitedVariantWithNiche { //~ERROR: size: Size(3 bytes) + //~^ERROR: abi: Memory + A(i8, bool), + B(u8, u8, !), +} + +#[rustc_layout(debug)] +enum UninhabitedVariantLargeWithNiche { + //~^ ERROR: layout_of + //~| ERROR: size: Size(3 bytes) + //~| ERROR: backend_repr: Memory + //~| ERROR: valid_range: 0..=0 + // Should use the tagged representation, since that gives a 255-slot niche, + // instead of a 254-slot niche if it used the niche-filling representation on the `bool` + A(i8, bool), + B(u8, u8, u8, !), +} + +// This uses the tagged layout, but since all variants are uninhabited, none of them store the tag, +// so we only need space for the fields, and the abi is Memory. +#[rustc_layout(size, abi)] +enum AllUninhabitedVariants { //~ERROR: size: Size(3 bytes) + //~^ERROR: abi: Memory + A(i8, bool, !), + B(u8, u8, !), +} + +#[repr(align(2))] +struct AlignedNever(!); + +// Tagged `(i8, padding)` +#[rustc_layout(size, abi)] +enum AlignedI8 { //~ERROR: size: Size(2 bytes) + //~^ERROR: abi: Memory + A(i8), + B(AlignedNever) +} + +// Tagged `(u8, i8, padding, padding)` +#[rustc_layout(size, abi)] +enum TaggedI8 { //~ERROR: size: Size(4 bytes) + //~^ERROR: abi: Memory + A(i8), + B(i8, i8, i8, AlignedNever) +} + + +// Tagged `(u16, i16)` +#[rustc_layout(size, abi)] +enum TaggedI16 { //~ERROR: size: Size(4 bytes) + //~^ERROR: abi: Memory + A(i16), + B(i8, i8, i8, AlignedNever) +} + +// This must not use tagged representation, since it's zero-sized. +#[rustc_layout(size, abi)] +enum AllUninhabitedVariantsAlignedZst { //~ERROR: size: Size(2 bytes) + //~^ERROR: abi: Scalar + A(AlignedNever), + B(AlignedNever), +} diff --git a/tests/ui/layout/enum.stderr b/tests/ui/layout/enum.stderr index f95b577bfc9df..64636fb1ede35 100644 --- a/tests/ui/layout/enum.stderr +++ b/tests/ui/layout/enum.stderr @@ -16,5 +16,231 @@ error: abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=1 } LL | enum ScalarPairDifferingSign { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: size: Size(4 bytes) + --> $DIR/enum.rs:29:1 + | +LL | enum AbsentVariantUntagged { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I32, true), valid_range: 0..=4294967295 }) + --> $DIR/enum.rs:29:1 + | +LL | enum AbsentVariantUntagged { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(8 bytes) + --> $DIR/enum.rs:38:1 + | +LL | enum UninhabitedVariantUntagged { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: ScalarPair(Initialized { value: Int(I32, false), valid_range: 0..=0 }, Initialized { value: Int(I32, true), valid_range: 0..=4294967295 }) + --> $DIR/enum.rs:38:1 + | +LL | enum UninhabitedVariantUntagged { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(8 bytes) + --> $DIR/enum.rs:49:1 + | +LL | enum UninhabitedVariantUntaggedBigger { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: Memory { sized: true } + --> $DIR/enum.rs:49:1 + | +LL | enum UninhabitedVariantUntaggedBigger { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(3 bytes) + --> $DIR/enum.rs:56:1 + | +LL | enum UninhabitedVariantWithNiche { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: Memory { sized: true } + --> $DIR/enum.rs:56:1 + | +LL | enum UninhabitedVariantWithNiche { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: layout_of(UninhabitedVariantLargeWithNiche) = Layout { + size: Size(4 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + in_memory_order: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I8, + false, + ), + valid_range: 0..=0, + }, + ), + uninhabited: false, + variants: Multiple { + tag: Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=0, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + size: Size(3 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(1 bytes), + Size(2 bytes), + ], + in_memory_order: [ + 0, + 1, + ], + }, + largest_niche: Some( + Niche { + offset: Size(2 bytes), + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + ), + uninhabited: false, + variants: Single { + index: 0, + variants: None, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: 17394913183323368564, + }, + Layout { + size: Size(4 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(1 bytes), + Size(2 bytes), + Size(3 bytes), + Size(4 bytes), + ], + in_memory_order: [ + 0, + 1, + 2, + 3, + ], + }, + largest_niche: None, + uninhabited: true, + variants: Single { + index: 1, + variants: None, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: 17538183959353994357, + }, + ], + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: 15362464571658798427, + } + --> $DIR/enum.rs:63:1 + | +LL | enum UninhabitedVariantLargeWithNiche { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(3 bytes) + --> $DIR/enum.rs:77:1 + | +LL | enum AllUninhabitedVariants { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: Memory { sized: true } + --> $DIR/enum.rs:77:1 + | +LL | enum AllUninhabitedVariants { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(2 bytes) + --> $DIR/enum.rs:88:1 + | +LL | enum AlignedI8 { + | ^^^^^^^^^^^^^^ + +error: abi: Memory { sized: true } + --> $DIR/enum.rs:88:1 + | +LL | enum AlignedI8 { + | ^^^^^^^^^^^^^^ + +error: size: Size(4 bytes) + --> $DIR/enum.rs:96:1 + | +LL | enum TaggedI8 { + | ^^^^^^^^^^^^^ + +error: abi: Memory { sized: true } + --> $DIR/enum.rs:96:1 + | +LL | enum TaggedI8 { + | ^^^^^^^^^^^^^ + +error: size: Size(4 bytes) + --> $DIR/enum.rs:105:1 + | +LL | enum TaggedI16 { + | ^^^^^^^^^^^^^^ + +error: abi: Memory { sized: true } + --> $DIR/enum.rs:105:1 + | +LL | enum TaggedI16 { + | ^^^^^^^^^^^^^^ + +error: size: Size(2 bytes) + --> $DIR/enum.rs:113:1 + | +LL | enum AllUninhabitedVariantsAlignedZst { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I16, false), valid_range: 0..=0 }) + --> $DIR/enum.rs:113:1 + | +LL | enum AllUninhabitedVariantsAlignedZst { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 22 previous errors From d30a00cc9247f8e9614917093a74b55e56fb72d8 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Sun, 26 Jan 2025 01:31:57 -0600 Subject: [PATCH 5/6] Don't encode enum tag for uninhabited repr(Rust) enum variants --- compiler/rustc_abi/src/layout.rs | 62 +++++++++++++++++++++-- tests/codegen-llvm/enum/enum-aggregate.rs | 2 +- tests/ui/consts/const-eval/ub-enum.rs | 4 +- tests/ui/consts/const-eval/ub-enum.stderr | 4 +- tests/ui/layout/debug.stderr | 31 ++++++++---- tests/ui/layout/enum.rs | 12 ++--- tests/ui/layout/enum.stderr | 18 +++---- 7 files changed, 99 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 228a98f49c5bc..658d588a02043 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -818,11 +818,15 @@ impl LayoutCalculator { let mut layout_variants = variants .iter_enumerated() .map(|(i, field_layouts)| { - let mut st = self.univariant( - field_layouts, - repr, - StructKind::Prefixed(min_ity.size(), prefix_align), - )?; + let uninhabited = field_layouts.iter().any(|f| f.is_uninhabited()); + // We don't need to encode the tag in uninhabited variants in repr(Rust) enums + let struct_kind = if uninhabited && !repr.inhibit_enum_layout_opt() { + StructKind::AlwaysSized + } else { + StructKind::Prefixed(min_ity.size(), prefix_align) + }; + let mut st = self.univariant(field_layouts, repr, struct_kind)?; + st.variants = Variants::Single { index: i, variants: None }; // Find the first field we can't move later // to make room for a larger discriminant. @@ -892,6 +896,11 @@ impl LayoutCalculator { let old_ity_size = min_ity.size(); let new_ity_size = ity.size(); for variant in &mut layout_variants { + // Don't change field offsets of uninhabited variants in repr(Rust) enums, + // they don't encode the tag and their fields may overlap with the tag. + if variant.is_uninhabited() && !repr.inhibit_enum_layout_opt() { + continue; + } match variant.fields { FieldsShape::Arbitrary { ref mut offsets, .. } => { for i in offsets { @@ -936,6 +945,12 @@ impl LayoutCalculator { let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else { panic!("encountered a non-arbitrary layout during enum layout"); }; + // Don't look in uninhabited variants for repr(Rust) enums, they will never be + // passed over an ABI so they don't matter for the purpose of determining + // BackendRepr. + if layout_variant.is_uninhabited() && !repr.inhibit_enum_layout_opt() { + continue; + } // We skip *all* ZST here and later check if we are good in terms of alignment. // This lets us handle some cases involving aligned ZST. let mut fields = iter::zip(field_layouts, offsets).filter(|p| !p.0.is_zst()); @@ -1052,6 +1067,43 @@ impl LayoutCalculator { .map(|v| v.randomization_seed) .fold(repr.field_shuffle_seed, |acc, seed| acc.wrapping_add(seed)); + // If all variants are uninhabited, the repr does not inhibit layout optimizations, + // and all fields are ZSTs, then the tagged layout will not have room for the tag. + // So in this case, we return an uninhabited layout that is big enough and aligned + // enough for all variant fields, but do not say it has any fields itself. + // Doing this only when the layout is too small to fit the tag gives better error + // messages during const-eval in some cases, "constructing invalid value at .: + // encountered an uninhabited enum variant" instead of "constructing invalid value: + // encountered a value of uninhabited type". + // Note the we only reach this case when there is at least one non-1-aligned ZST field, + // since the all-1-ZST case is handled by the "present_variants" check in + // `layout_of_struct_or_enum`. + if uninhabited && size < tag.size(&self.cx) { + // The only way for the size to be less than the tag's size is for it to be zero, + // which can only occur when the repr does not inhibit layout optimization. + debug_assert!( + size == Size::ZERO, + "size was non-zero but less than tag size: 0 < {size:?} < {:?}", + tag.size(&self.cx) + ); + debug_assert!( + !repr.inhibit_enum_layout_opt(), + "enum size was zero with layout optimizations disabled" + ); + return Ok(LayoutData { + fields: FieldsShape::Arbitrary { offsets: [].into(), in_memory_order: [].into() }, + variants: Variants::Empty { variants: Some(layout_variants) }, + backend_repr: BackendRepr::Memory { sized: true }, + largest_niche: None, + uninhabited: true, + align: AbiAlign::new(align), + size, + max_repr_align, + unadjusted_abi_align, + randomization_seed: combined_seed, + }); + } + let tagged_layout = LayoutData { variants: Variants::Multiple { tag, diff --git a/tests/codegen-llvm/enum/enum-aggregate.rs b/tests/codegen-llvm/enum/enum-aggregate.rs index 89517008c6374..e1feff0bc17b0 100644 --- a/tests/codegen-llvm/enum/enum-aggregate.rs +++ b/tests/codegen-llvm/enum/enum-aggregate.rs @@ -113,7 +113,7 @@ fn make_uninhabited_err_indirectly(n: Never) -> Result { fn make_fully_uninhabited_result(v: u32, n: Never) -> Result<(u32, Never), (Never, u32)> { // Actually reaching this would be UB, so we don't actually build a result. - // CHECK-LABEL: { i32, i32 } @make_fully_uninhabited_result(i32{{( signext)?}} %v) + // CHECK-LABEL: i32 @make_fully_uninhabited_result(i32{{( signext)?}} %v) // CHECK-NEXT: start: // CHECK-NEXT: call void @llvm.trap() // CHECK-NEXT: call void @llvm.trap() diff --git a/tests/ui/consts/const-eval/ub-enum.rs b/tests/ui/consts/const-eval/ub-enum.rs index b60116aa553f7..3dfe0c805151e 100644 --- a/tests/ui/consts/const-eval/ub-enum.rs +++ b/tests/ui/consts/const-eval/ub-enum.rs @@ -95,9 +95,9 @@ const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute // All variants are uninhabited but also have data. // Use `0` as constant to make behavior endianness-independent. -const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; +const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u32) }; //~^ ERROR uninhabited enum variant -const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; +const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u32) }; //~^ ERROR uninhabited enum variant // All variants have same-size data but only one inhabited. diff --git a/tests/ui/consts/const-eval/ub-enum.stderr b/tests/ui/consts/const-eval/ub-enum.stderr index ffb6d2bc27e5a..5701c62fc3516 100644 --- a/tests/ui/consts/const-eval/ub-enum.stderr +++ b/tests/ui/consts/const-eval/ub-enum.stderr @@ -111,13 +111,13 @@ LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::tran error[E0080]: constructing invalid value at .: encountered an uninhabited enum variant --> $DIR/ub-enum.rs:98:77 | -LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; +LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u32) }; | ^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_UNINHABITED_WITH_DATA1` failed here error[E0080]: constructing invalid value at .: encountered an uninhabited enum variant --> $DIR/ub-enum.rs:100:77 | -LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; +LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u32) }; | ^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_UNINHABITED_WITH_DATA2` failed here error[E0080]: read discriminant of an uninhabited enum variant diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index 2dc2a961999d2..479dfc1879c56 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -5,7 +5,7 @@ LL | union EmptyUnion {} | ^^^^^^^^^^^^^^^^^^^ error: layout_of(E) = Layout { - size: Size(12 bytes), + size: Size(8 bytes), align: AbiAlign { abi: Align(4 bytes), }, @@ -65,23 +65,36 @@ error: layout_of(E) = Layout { randomization_seed: $SEED, }, Layout { - size: Size(12 bytes), + size: Size(8 bytes), align: AbiAlign { abi: Align(4 bytes), }, - backend_repr: Memory { - sized: true, - }, + backend_repr: ScalarPair( + Initialized { + value: Int( + I32, + true, + ), + valid_range: 0..=4294967295, + }, + Initialized { + value: Int( + I32, + true, + ), + valid_range: 0..=4294967295, + }, + ), fields: Arbitrary { offsets: [ - Size(4 bytes), - Size(4 bytes), Size(8 bytes), + Size(0 bytes), + Size(4 bytes), ], in_memory_order: [ - 0, 1, 2, + 0, ], }, largest_niche: None, @@ -506,7 +519,7 @@ LL | union P3 { x: F32x4 } | ^^^^^^^^ error: layout_of(P4) = Layout { - size: Size(12 bytes), + size: Size(8 bytes), align: AbiAlign { abi: Align(1 bytes), }, diff --git a/tests/ui/layout/enum.rs b/tests/ui/layout/enum.rs index 236f19a75c278..af224889673cf 100644 --- a/tests/ui/layout/enum.rs +++ b/tests/ui/layout/enum.rs @@ -12,7 +12,7 @@ enum UninhabitedVariantAlign { //~ERROR: abi: Align(2 bytes) } #[rustc_layout(size)] -enum UninhabitedVariantSpace { //~ERROR: size: Size(16 bytes) +enum UninhabitedVariantSpace { //~ERROR: size: Size(15 bytes) A, B([u8; 15], !), // make sure there is space being reserved for this field. } @@ -47,7 +47,7 @@ enum UninhabitedVariantUntagged { //~ERROR: size: Size(8 bytes) // the same size, but without a niche. #[rustc_layout(size, abi)] enum UninhabitedVariantUntaggedBigger { //~ERROR: size: Size(8 bytes) - //~^ ERROR: abi: Memory + //~^ ERROR: abi: ScalarPair A(i32), B([u8; 5], !), } @@ -74,7 +74,7 @@ enum UninhabitedVariantLargeWithNiche { // This uses the tagged layout, but since all variants are uninhabited, none of them store the tag, // so we only need space for the fields, and the abi is Memory. #[rustc_layout(size, abi)] -enum AllUninhabitedVariants { //~ERROR: size: Size(3 bytes) +enum AllUninhabitedVariants { //~ERROR: size: Size(2 bytes) //~^ERROR: abi: Memory A(i8, bool, !), B(u8, u8, !), @@ -103,15 +103,15 @@ enum TaggedI8 { //~ERROR: size: Size(4 bytes) // Tagged `(u16, i16)` #[rustc_layout(size, abi)] enum TaggedI16 { //~ERROR: size: Size(4 bytes) - //~^ERROR: abi: Memory + //~^ERROR: abi: ScalarPair A(i16), B(i8, i8, i8, AlignedNever) } // This must not use tagged representation, since it's zero-sized. #[rustc_layout(size, abi)] -enum AllUninhabitedVariantsAlignedZst { //~ERROR: size: Size(2 bytes) - //~^ERROR: abi: Scalar +enum AllUninhabitedVariantsAlignedZst { //~ERROR: size: Size(0 bytes) + //~^ERROR: abi: Memory A(AlignedNever), B(AlignedNever), } diff --git a/tests/ui/layout/enum.stderr b/tests/ui/layout/enum.stderr index 64636fb1ede35..406ad8bc42734 100644 --- a/tests/ui/layout/enum.stderr +++ b/tests/ui/layout/enum.stderr @@ -4,7 +4,7 @@ error: align: AbiAlign { abi: Align(2 bytes) } LL | enum UninhabitedVariantAlign { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: size: Size(16 bytes) +error: size: Size(15 bytes) --> $DIR/enum.rs:15:1 | LL | enum UninhabitedVariantSpace { @@ -46,7 +46,7 @@ error: size: Size(8 bytes) LL | enum UninhabitedVariantUntaggedBigger { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: abi: Memory { sized: true } +error: abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=0 }, Initialized { value: Int(I32, true), valid_range: 0..=4294967295 }) --> $DIR/enum.rs:49:1 | LL | enum UninhabitedVariantUntaggedBigger { @@ -65,7 +65,7 @@ LL | enum UninhabitedVariantWithNiche { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: layout_of(UninhabitedVariantLargeWithNiche) = Layout { - size: Size(4 bytes), + size: Size(3 bytes), align: AbiAlign { abi: Align(1 bytes), }, @@ -140,7 +140,7 @@ error: layout_of(UninhabitedVariantLargeWithNiche) = Layout { randomization_seed: 17394913183323368564, }, Layout { - size: Size(4 bytes), + size: Size(3 bytes), align: AbiAlign { abi: Align(1 bytes), }, @@ -149,10 +149,10 @@ error: layout_of(UninhabitedVariantLargeWithNiche) = Layout { }, fields: Arbitrary { offsets: [ + Size(0 bytes), Size(1 bytes), Size(2 bytes), Size(3 bytes), - Size(4 bytes), ], in_memory_order: [ 0, @@ -182,7 +182,7 @@ error: layout_of(UninhabitedVariantLargeWithNiche) = Layout { LL | enum UninhabitedVariantLargeWithNiche { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: size: Size(3 bytes) +error: size: Size(2 bytes) --> $DIR/enum.rs:77:1 | LL | enum AllUninhabitedVariants { @@ -224,19 +224,19 @@ error: size: Size(4 bytes) LL | enum TaggedI16 { | ^^^^^^^^^^^^^^ -error: abi: Memory { sized: true } +error: abi: ScalarPair(Initialized { value: Int(I16, false), valid_range: 0..=0 }, Initialized { value: Int(I16, true), valid_range: 0..=65535 }) --> $DIR/enum.rs:105:1 | LL | enum TaggedI16 { | ^^^^^^^^^^^^^^ -error: size: Size(2 bytes) +error: size: Size(0 bytes) --> $DIR/enum.rs:113:1 | LL | enum AllUninhabitedVariantsAlignedZst { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: abi: Scalar(Initialized { value: Int(I16, false), valid_range: 0..=0 }) +error: abi: Memory { sized: true } --> $DIR/enum.rs:113:1 | LL | enum AllUninhabitedVariantsAlignedZst { From aa3a4171278bf28c1688adde82d801ea474a4f1f Mon Sep 17 00:00:00 2001 From: Zachary S Date: Tue, 12 Aug 2025 17:36:06 -0500 Subject: [PATCH 6/6] Do not store tag for single-inhabited-variant enums (if this results in a better layout) --- compiler/rustc_abi/src/layout.rs | 100 +++++++++++++++++++++++--- tests/ui/consts/const-eval/ub-enum.rs | 4 +- tests/ui/layout/enum.rs | 8 +-- tests/ui/layout/enum.stderr | 8 +-- 4 files changed, 99 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 658d588a02043..0fb87f58d7f6a 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -783,6 +783,9 @@ impl LayoutCalculator { }); trace!(?largest_niche); + let single_variant_layout_eligible = + !repr.inhibit_enum_layout_opt() && valid_discriminants.len() == 1; + // `max` is the last valid discriminant before the largest niche // `min` is the first valid discriminant after the largest niche let (max, min) = largest_niche @@ -815,10 +818,15 @@ impl LayoutCalculator { } // Create the set of structs that represent each variant. + let mut single_inhabited_variant_no_tag_layout = None; let mut layout_variants = variants .iter_enumerated() .map(|(i, field_layouts)| { let uninhabited = field_layouts.iter().any(|f| f.is_uninhabited()); + if !uninhabited && single_variant_layout_eligible { + single_inhabited_variant_no_tag_layout = + Some((i, self.univariant(field_layouts, repr, StructKind::AlwaysSized))); + } // We don't need to encode the tag in uninhabited variants in repr(Rust) enums let struct_kind = if uninhabited && !repr.inhibit_enum_layout_opt() { StructKind::AlwaysSized @@ -845,6 +853,62 @@ impl LayoutCalculator { }) .collect::, _>>()?; + // If there is a single uninhabited variant, we can use it mostly unchanged as the layout, + // without using a tag or niche. + // + // We do still need to modify it to make all the uninhabited variants fit so they + // can be partially-initialized. + // + // We keep this as a prospective layout, and don't assume it's better than the tagged + // layout and return it immediately; e.g. it's worse for `enum Foo { A, B(i32, !) }` + // because it has no niche. + let no_tag_layout = if let Some((single_inhabited_variant_idx, Ok(mut st))) = + single_inhabited_variant_no_tag_layout + { + // Keep track of original variant layouts (including the inhabited one) + // for `offset_of!`. + let mut variants = layout_variants.clone(); + variants[single_inhabited_variant_idx] = st.clone(); + + // We know that every other variant is uninhabited, and thus does not have a + // prefix for the tag, so we can use them to find the necessary size. + for (idx, layout) in layout_variants.iter_enumerated() { + if idx != single_inhabited_variant_idx { + st.size = cmp::max(st.size, layout.size); + st.align = st.align.max(layout.align); + st.max_repr_align = st.max_repr_align.max(layout.max_repr_align); + st.unadjusted_abi_align = + st.unadjusted_abi_align.max(layout.unadjusted_abi_align); + } + } + + // Align the maximum variant size to the largest alignment. + st.size = st.size.align_to(st.align.abi); + + // If the inhabited variant's layout would use a non-Memory BackendRepr, + // but we made the enum layout bigger or more-aligned due to uninhabited variants, + // force the enum to be BackendRepr::Memory. + // + // FIXME: does this need to care about `max_repr_align` and `unadjusted_abi_align`? + // The untagged layout is only used for `repr(Rust)` enums, + // so `max_repr_align` and `unadjusted_abi_align` might be irrelevant. + if st.size != variants[single_inhabited_variant_idx].size + || st.align != variants[single_inhabited_variant_idx].align + || st.max_repr_align != variants[single_inhabited_variant_idx].max_repr_align + || st.unadjusted_abi_align + != variants[single_inhabited_variant_idx].unadjusted_abi_align + { + st.backend_repr = BackendRepr::Memory { sized: true }; + } + + st.variants = + Variants::Single { index: single_inhabited_variant_idx, variants: Some(variants) }; + + Some(st) + } else { + None + }; + // Align the maximum variant size to the largest alignment. size = size.align_to(align); @@ -1125,22 +1189,36 @@ impl LayoutCalculator { randomization_seed: combined_seed, }; - let best_layout = match (tagged_layout, niche_filling_layout) { - (tl, Some(nl)) => { - // Pick the smaller layout; otherwise, - // pick the layout with the larger niche; otherwise, - // pick tagged as it has simpler codegen. + // Pick the smallest layout; otherwise, + // pick the layout with the largest niche; otherwise, + // pick no_tag as it has simpler codegen than tagged and niched; otherwise, + // pick tagged as it has simpler codegen than niched. + + let better_layout_or_first = + |l1: LayoutData, l2: LayoutData| { use cmp::Ordering::*; let niche_size = |l: &LayoutData| { l.largest_niche.map_or(0, |n| n.available(dl)) }; - match (tl.size.cmp(&nl.size), niche_size(&tl).cmp(&niche_size(&nl))) { - (Greater, _) => nl, - (Equal, Less) => nl, - _ => tl, + match (l1.size.cmp(&l2.size), niche_size(&l1).cmp(&niche_size(&l2))) { + (Greater, _) => l2, + (Equal, Less) => l2, + _ => l1, } - } - (tl, None) => tl, + }; + + let best_layout = match niche_filling_layout { + None => tagged_layout, + // Prefer tagged over niched if they have the same size and niche size, + // as the tagged layout has simpler codegen. + Some(niched_layout) => better_layout_or_first(tagged_layout, niched_layout), + }; + + let best_layout = match no_tag_layout { + None => best_layout, + // Prefer no-tag over tagged/niched if they have the same size and niche size, + // as the no-tag layout has simpler codegen. + Some(no_tag_layout) => better_layout_or_first(no_tag_layout, best_layout), }; Ok(best_layout) diff --git a/tests/ui/consts/const-eval/ub-enum.rs b/tests/ui/consts/const-eval/ub-enum.rs index 3dfe0c805151e..f0bd6a0bf0711 100644 --- a/tests/ui/consts/const-eval/ub-enum.rs +++ b/tests/ui/consts/const-eval/ub-enum.rs @@ -102,8 +102,8 @@ const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem: // All variants have same-size data but only one inhabited. // Use `0` as constant to make behavior endianness-independent. -const GOOD_SEMIINHABITED_WITH_DATA1: Result = unsafe { mem::transmute(0u64) }; -const GOOD_SEMIINHABITED_WITH_DATA2: Result<(i32, !), i32> = unsafe { mem::transmute(1u64) }; +const GOOD_SEMIINHABITED_WITH_DATA1: Result = unsafe { mem::transmute(0u32) }; +const GOOD_SEMIINHABITED_WITH_DATA2: Result<(i32, !), i32> = unsafe { mem::transmute(0u32) }; const TEST_ICE_89765: () = { // This is a regression test for https://github.com/rust-lang/rust/issues/89765. diff --git a/tests/ui/layout/enum.rs b/tests/ui/layout/enum.rs index af224889673cf..d6e03af6b883a 100644 --- a/tests/ui/layout/enum.rs +++ b/tests/ui/layout/enum.rs @@ -35,8 +35,8 @@ enum AbsentVariantUntagged { //~ERROR: size: Size(4 bytes) // Even if uninhabited variants are not absent, the enum can still be laid out without // a tag. #[rustc_layout(size, abi)] -enum UninhabitedVariantUntagged { //~ERROR: size: Size(8 bytes) - //~^ ERROR: abi: ScalarPair(Initialized +enum UninhabitedVariantUntagged { //~ERROR: size: Size(4 bytes) + //~^ ERROR: abi: Scalar(Initialized A(i32), B(i32, !), } @@ -53,8 +53,8 @@ enum UninhabitedVariantUntaggedBigger { //~ERROR: size: Size(8 bytes) } #[rustc_layout(size, abi)] -enum UninhabitedVariantWithNiche { //~ERROR: size: Size(3 bytes) - //~^ERROR: abi: Memory +enum UninhabitedVariantWithNiche { //~ERROR: size: Size(2 bytes) + //~^ERROR: abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=1 }, Initialized { value: Int(I8, true), valid_range: 0..=255 }) A(i8, bool), B(u8, u8, !), } diff --git a/tests/ui/layout/enum.stderr b/tests/ui/layout/enum.stderr index 406ad8bc42734..565e72f858f81 100644 --- a/tests/ui/layout/enum.stderr +++ b/tests/ui/layout/enum.stderr @@ -28,13 +28,13 @@ error: abi: Scalar(Initialized { value: Int(I32, true), valid_range: 0..=4294967 LL | enum AbsentVariantUntagged { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: size: Size(8 bytes) +error: size: Size(4 bytes) --> $DIR/enum.rs:38:1 | LL | enum UninhabitedVariantUntagged { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: abi: ScalarPair(Initialized { value: Int(I32, false), valid_range: 0..=0 }, Initialized { value: Int(I32, true), valid_range: 0..=4294967295 }) +error: abi: Scalar(Initialized { value: Int(I32, true), valid_range: 0..=4294967295 }) --> $DIR/enum.rs:38:1 | LL | enum UninhabitedVariantUntagged { @@ -52,13 +52,13 @@ error: abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=0 } LL | enum UninhabitedVariantUntaggedBigger { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: size: Size(3 bytes) +error: size: Size(2 bytes) --> $DIR/enum.rs:56:1 | LL | enum UninhabitedVariantWithNiche { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: abi: Memory { sized: true } +error: abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=1 }, Initialized { value: Int(I8, true), valid_range: 0..=255 }) --> $DIR/enum.rs:56:1 | LL | enum UninhabitedVariantWithNiche {