diff --git a/compiler/rustc_abi/src/callconv.rs b/compiler/rustc_abi/src/callconv.rs index a21e1aee9b08a..1871d7b84cdac 100644 --- a/compiler/rustc_abi/src/callconv.rs +++ b/compiler/rustc_abi/src/callconv.rs @@ -140,7 +140,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 14356813b7bb0..3133856d8c2f8 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), @@ -181,7 +181,7 @@ impl LayoutCalculator { 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(), memory_index: [0].into(), @@ -197,6 +197,54 @@ impl LayoutCalculator { }) } + pub fn simd_type_for_scalar( + &self, + element: Scalar, + count: u64, + repr_packed: bool, + ) -> LayoutCalculatorResult { + let elt = element; + if count == 0 { + return Err(LayoutCalculatorError::ZeroLengthSimdType); + } else if count > crate::MAX_SIMD_LANES { + return Err(LayoutCalculatorError::OversizedSimdType { + max_lanes: crate::MAX_SIMD_LANES, + }); + } + + // Compute the size and alignment of the vector + let dl = self.cx.data_layout(); + let size = elt + .size(&self.cx) + .checked_mul(count, dl) + .ok_or_else(|| LayoutCalculatorError::SizeOverflow)?; + let (repr, align) = if repr_packed && !count.is_power_of_two() { + // Non-power-of-two vectors have padding up to the next power-of-two. + // If we're a packed repr, remove the padding while keeping the alignment as close + // to a vector as possible. + (BackendRepr::Memory { sized: true }, Align::max_aligned_factor(size)) + } else { + (BackendRepr::SimdVector { element, count }, dl.llvmlike_vector_align(size)) + }; + let size = size.align_to(align); + + Ok(LayoutData { + variants: Variants::Single { index: VariantIdx::new(0), variants: None }, + fields: FieldsShape::Arbitrary { + offsets: [Size::ZERO].into(), + memory_index: [0].into(), + }, + backend_repr: repr, + largest_niche: None, + uninhabited: false, + size, + align: AbiAlign::new(align), + max_repr_align: None, + unadjusted_abi_align: elt.align(&self.cx).abi, + randomization_seed: (Hash64::new(count)), + }) + } + /// Compute the layout for a coroutine. /// /// This uses dedicated code instead of [`Self::layout_of_struct_or_enum`], as coroutine @@ -467,7 +515,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, @@ -508,7 +556,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 { @@ -598,7 +646,10 @@ impl LayoutCalculator { return Err(LayoutCalculatorError::ReprConflict); } - let calculate_niche_filling_layout = || -> Option> { + // Returns `(layout, is_this_maybe_npo)`. + // If `is_this_maybe_npo` is true, this layout is preferred over the tagged and + // no-tag layouts. + let calculate_niche_filling_layout = || -> Option<(LayoutData<_, _>, bool)> { if repr.inhibit_enum_layout_opt() { return None; } @@ -615,7 +666,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); @@ -625,30 +676,74 @@ impl LayoutCalculator { }) .collect::>>()?; + // Choose the largest variant, picking an inhabited variant in a tie. + // We still need to compute the niche-filling layout even if the largest variant + // is uninhabited, because `Result` needs to + // still be NPO-optimized. let largest_variant_index = variant_layouts .iter_enumerated() - .max_by_key(|(_i, layout)| layout.size.bytes()) + .max_by_key(|(_i, layout)| (layout.size.bytes(), !layout.uninhabited)) .map(|(i, _layout)| i)?; + // Use the largest niche in the largest variant. + let niche = variant_layouts[largest_variant_index].largest_niche?; + let niche_offset = niche.offset; + let niche_size = niche.value.size(dl); + let size = variant_layouts[largest_variant_index].size.align_to(align); + // If the niche occupies the whole size of the enum, + // this could be a case of NPO, so we should prefer this layout over the + // tagged and no-tag layouts, even if it has a worse niche (due to the + // niched variant being uninhabited) + let is_maybe_npo = niche_size == size; + let all_indices = variants.indices(); - let needs_disc = - |index: VariantIdx| index != largest_variant_index && !absent(&variants[index]); - let niche_variants = all_indices.clone().find(|v| needs_disc(*v)).unwrap() - ..=all_indices.rev().find(|v| needs_disc(*v)).unwrap(); + let needs_disc = |index: VariantIdx| { + index != largest_variant_index && !variant_layouts[index].uninhabited + }; + let first_niche_variant = all_indices.clone().find(|v| needs_disc(*v)); + let last_niche_variant = all_indices.clone().rev().find(|v| needs_disc(*v)); + let niche_variants = match Option::zip(first_niche_variant, last_niche_variant) { + Some((f, l)) => f..=l, + // All non-largest variants are uninhabited. + // If there are exactly 2 variants, and the largest variant's niche covers its + // whole size, and the non-largest variant is 1-aligned and zero-sized, + // this could be NPO. + // However, that only happens if the non-largest variant is "absent", + // which was already handled in `layout_of_struct_or_enum`, so we just debug_assert + // that that is not the case. + None if variants.len() == 2 && is_maybe_npo => { + if cfg!(debug_assertions) { + let non_largest_variant_index = + all_indices.clone().find(|v| *v != largest_variant_index).unwrap(); + let non_largest_variant_layout = + &variant_layouts[non_largest_variant_index]; + debug_assert!( + non_largest_variant_layout.size > Size::ZERO + || non_largest_variant_layout.align.abi > Align::ONE + ); + } + // The non-largest variant is not 1-ZST, this cannot be NPO, + // use the no-tag layout. + return None; + } + // All non-largest variants are uninhabited. + // This cannot be NPO, use the no-tag layout. + None => return None, + }; let count = (niche_variants.end().index() as u128 - niche_variants.start().index() as u128) + 1; - // Use the largest niche in the largest variant. - let niche = variant_layouts[largest_variant_index].largest_niche?; + // Calculate the new niche. let (niche_start, niche_scalar) = niche.reserve(dl, count)?; - let niche_offset = niche.offset; - let niche_size = niche.value.size(dl); - let size = variant_layouts[largest_variant_index].size.align_to(align); let all_variants_fit = variant_layouts.iter_enumerated_mut().all(|(i, layout)| { if i == largest_variant_index { return true; + } else if layout.uninhabited { + // This variant doesn't need to hold space for the niche, + // it just needs to be at-most-as big and aligned as the enum. + return layout.size <= size && layout.align.abi <= align; } layout.largest_niche = None; @@ -693,14 +788,14 @@ impl LayoutCalculator { let largest_niche = Niche::from_scalar(dl, niche_offset, niche_scalar); - let others_zst = variant_layouts - .iter_enumerated() - .all(|(i, layout)| i == largest_variant_index || layout.size == Size::ZERO); + let others_zst_or_uninhabited = variant_layouts.iter_enumerated().all(|(i, layout)| { + i == largest_variant_index || layout.size == Size::ZERO || layout.uninhabited + }); let same_size = size == variant_layouts[largest_variant_index].size; let same_align = align == variant_layouts[largest_variant_index].align.abi; let uninhabited = variant_layouts.iter().all(|v| v.is_uninhabited()); - let abi = if same_size && same_align && others_zst { + let abi = if same_size && same_align && others_zst_or_uninhabited { match variant_layouts[largest_variant_index].backend_repr { // When the total alignment and size match, we can use the // same ABI as the scalar variant with the reserved niche. @@ -750,10 +845,19 @@ impl LayoutCalculator { randomization_seed: combined_seed, }; - Some(layout) + Some((layout, is_maybe_npo)) }; - let niche_filling_layout = calculate_niche_filling_layout(); + let niche_filling_layout = match calculate_niche_filling_layout() { + // If this is possibly NPO, we prefer this layout over the others, + // even if they might have a better niche. + // (They could never be smaller, since possibly-npo only occurs + // when the niche fills the whole size of the enum.) + Some((layout, true)) => return Ok(layout), + // This is definitely not NPO, try the other layouts. + Some((layout, false)) => Some(layout), + None => None, + }; let discr_type = repr.discr_type(); let discr_int = Integer::from_attr(dl, discr_type); @@ -807,6 +911,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 @@ -839,15 +946,24 @@ 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 mut st = self.univariant( - field_layouts, - repr, - StructKind::Prefixed(min_ity.size(), prefix_align), - )?; - st.variants = Variants::Single { index: i }; + 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 + } 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. for field_idx in st.fields.index_by_increasing_offset() { @@ -865,6 +981,73 @@ 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 single_variant_layout_eligible + && 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 it bigger or more-aligned due to uninhabited variants, + // force it to be BackendRepr::Memory + match st.backend_repr { + BackendRepr::Scalar(..) | BackendRepr::ScalarPair(..) => { + if st.backend_repr.scalar_size(&self.cx) != Some(st.size) + || st.backend_repr.scalar_align(&self.cx) != Some(st.align.abi) + { + st.backend_repr = BackendRepr::Memory { sized: true } + } + } + BackendRepr::SimdVector { element, count } => { + // FIXME: is there a better way to do this than making a copy of + // `LayoutCalculator::simd_type` *just* for this? + let vector_layout = self.simd_type_for_scalar::( + element, + count, + repr.packed(), + )?; + if vector_layout.size != st.size || vector_layout.align != st.align { + st.backend_repr = BackendRepr::Memory { sized: true } + } + } + BackendRepr::Memory { .. } => {} + } + + 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); @@ -916,6 +1099,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 { @@ -960,6 +1148,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()); @@ -1076,6 +1270,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(), memory_index: [].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, @@ -1097,22 +1328,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) @@ -1457,7 +1702,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, memory_index }, backend_repr: abi, largest_niche, diff --git a/compiler/rustc_abi/src/layout/coroutine.rs b/compiler/rustc_abi/src/layout/coroutine.rs index 2b22276d4aed7..c0aa31514016f 100644 --- a/compiler/rustc_abi/src/layout/coroutine.rs +++ b/compiler/rustc_abi/src/layout/coroutine.rs @@ -234,7 +234,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, memory_index } = variant.fields else { unreachable!(); diff --git a/compiler/rustc_abi/src/layout/simple.rs b/compiler/rustc_abi/src/layout/simple.rs index b3807c8727396..83706e8a68ef6 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(), memory_index: 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(), memory_index: [0, 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 de44c8755a078..472d1f637c10c 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1851,12 +1851,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 93202483eed81..4ff729e92de90 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -100,14 +100,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(); @@ -228,7 +228,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 84998b5499bdf..58e51da302ba4 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -36,14 +36,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(); @@ -218,7 +218,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 0a37a904193fa..a822e969e365c 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 88a8e2a844cbc..9cb5f641a5b6c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -411,8 +411,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 @@ -956,10 +956,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 { val: o.val, layout } } diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 50f56f913a51e..e60252e393dc4 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -458,8 +458,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 5f088fe37e80b..5ea1e5ee00f16 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"), } } @@ -1024,7 +1024,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 b5de10c7dcd11..1f97b17515441 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -200,7 +200,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 1dea7e4252d7f..2fdfe20411008 100644 --- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs +++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs @@ -157,7 +157,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 507a25a432594..b97c3a01dbcb9 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -772,14 +772,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(); @@ -796,15 +799,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 } } @@ -941,8 +946,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()) @@ -963,11 +968,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 3ff8dc6dbb378..5ff24d4cfbcd9 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1587,7 +1587,7 @@ impl<'body, 'tcx> VnState<'body, '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 1b90e9158f6b8..f48d2b99464f0 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -182,7 +182,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 7b0882caf1b3e..7f7d61ccbde49 100644 --- a/compiler/rustc_public/src/abi.rs +++ b/compiler/rustc_public/src/abi.rs @@ -181,10 +181,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 782e75a930e07..101c3437aa571 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 bc3c9601fa3d3..3490dfdf60362 100644 --- a/compiler/rustc_target/src/callconv/loongarch.rs +++ b/compiler/rustc_target/src/callconv/loongarch.rs @@ -124,7 +124,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 16de3fe070dd4..2e6f1ff141fd9 100644 --- a/compiler/rustc_target/src/callconv/riscv.rs +++ b/compiler/rustc_target/src/callconv/riscv.rs @@ -130,7 +130,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 d8db7ed6e4c0f..43a8d389f7d8b 100644 --- a/compiler/rustc_target/src/callconv/x86_64.rs +++ b/compiler/rustc_target/src/callconv/x86_64.rs @@ -66,7 +66,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 7f626e8c4e886..d886b77146a76 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -446,8 +446,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) @@ -609,11 +609,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 317d101dafe05..dee0df31777d8 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -811,9 +811,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 b768269215fa2..58308ca0edca5 100644 --- a/compiler/rustc_ty_utils/src/layout/invariant.rs +++ b/compiler/rustc_ty_utils/src/layout/invariant.rs @@ -255,10 +255,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 e0c077e99319a..c5ff7cd72f54c 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -614,7 +614,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 c93165a04c0fb..504715168c891 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 @@ -821,7 +821,7 @@ impl<'db> Evaluator<'db> { ProjectionElem::Field(Either::Left(f)) => { let layout = self.layout(prev_ty.to_nextsolver(interner))?; 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) => { @@ -1656,8 +1656,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) @@ -1825,7 +1825,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 427c4bb68423d..e86a14d02693d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs @@ -328,8 +328,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/codegen-llvm/enum/enum-aggregate.rs b/tests/codegen-llvm/enum/enum-aggregate.rs index 7d450a89e2e3c..07bd6377760ce 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/abi/c-zst.aarch64-darwin.stderr b/tests/ui/abi/c-zst.aarch64-darwin.stderr index 5e09145a27122..0ec4fd5512da8 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 ec6b9b8f02742..10b71c96eb77c 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 ec6b9b8f02742..10b71c96eb77c 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 ec6b9b8f02742..10b71c96eb77c 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 5e09145a27122..0ec4fd5512da8 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 ec6b9b8f02742..10b71c96eb77c 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 47341da221fb3..1b91259692b42 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 94a01a8087314..e77060f4c62fb 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 94a01a8087314..e77060f4c62fb 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/sysv64-zst.stderr b/tests/ui/abi/sysv64-zst.stderr index 2233e8e4f623e..a04782eba1fb1 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/consts/const-eval/ub-enum.rs b/tests/ui/consts/const-eval/ub-enum.rs index 9c78bb6efed7e..f0bd6a0bf0711 100644 --- a/tests/ui/consts/const-eval/ub-enum.rs +++ b/tests/ui/consts/const-eval/ub-enum.rs @@ -95,11 +95,16 @@ 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. +// Use `0` as constant to make behavior endianness-independent. +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. unsafe { diff --git a/tests/ui/consts/const-eval/ub-enum.stderr b/tests/ui/consts/const-eval/ub-enum.stderr index 1efd93832291e..5701c62fc3516 100644 --- a/tests/ui/consts/const-eval/ub-enum.stderr +++ b/tests/ui/consts/const-eval/ub-enum.stderr @@ -111,17 +111,17 @@ 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 - --> $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 diff --git a/tests/ui/enum-discriminant/wrapping_niche.stderr b/tests/ui/enum-discriminant/wrapping_niche.stderr index e3e1755e14dd4..44c64eae754b4 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 b2ce6385ab654..437d2a5b71309 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), }, @@ -58,35 +58,50 @@ error: layout_of(E) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), 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), ], memory_index: [ + 2, 0, 1, - 2, ], }, largest_niche: None, uninhabited: true, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -140,6 +155,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 +181,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 +276,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 +315,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 +351,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 +377,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 +403,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 +429,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 +455,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 +481,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 +507,7 @@ error: layout_of(P3) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -493,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), }, @@ -507,6 +533,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 +564,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 +595,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/enum.bit32.stderr b/tests/ui/layout/enum.bit32.stderr new file mode 100644 index 0000000000000..1228c16aaf939 --- /dev/null +++ b/tests/ui/layout/enum.bit32.stderr @@ -0,0 +1,360 @@ +error: align: AbiAlign { abi: Align(2 bytes) } + --> $DIR/enum.rs:12:1 + | +LL | enum UninhabitedVariantAlign { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(15 bytes) + --> $DIR/enum.rs:18:1 + | +LL | enum UninhabitedVariantSpace { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=1 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }) + --> $DIR/enum.rs:24:1 + | +LL | enum ScalarPairDifferingSign { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(4 bytes) + --> $DIR/enum.rs:32:1 + | +LL | enum AbsentVariantUntagged { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I32, true), valid_range: 0..=4294967295 }) + --> $DIR/enum.rs:32:1 + | +LL | enum AbsentVariantUntagged { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(4 bytes) + --> $DIR/enum.rs:41:1 + | +LL | enum UninhabitedVariantUntagged { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I32, true), valid_range: 0..=4294967295 }) + --> $DIR/enum.rs:41:1 + | +LL | enum UninhabitedVariantUntagged { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(8 bytes) + --> $DIR/enum.rs:52:1 + | +LL | enum UninhabitedVariantUntaggedBigger { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=0 }, Initialized { value: Int(I32, true), valid_range: 0..=4294967295 }) + --> $DIR/enum.rs:52:1 + | +LL | enum UninhabitedVariantUntaggedBigger { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(2 bytes) + --> $DIR/enum.rs:59:1 + | +LL | enum UninhabitedVariantWithNiche { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=1 }, Initialized { value: Int(I8, true), valid_range: 0..=255 }) + --> $DIR/enum.rs:59:1 + | +LL | enum UninhabitedVariantWithNiche { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: layout_of(UninhabitedVariantLargeWithNiche) = Layout { + size: Size(3 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 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), + ], + memory_index: [ + 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(3 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + Size(1 bytes), + Size(2 bytes), + Size(3 bytes), + ], + memory_index: [ + 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:66:1 + | +LL | enum UninhabitedVariantLargeWithNiche { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(2 bytes) + --> $DIR/enum.rs:80:1 + | +LL | enum AllUninhabitedVariants { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: Memory { sized: true } + --> $DIR/enum.rs:80:1 + | +LL | enum AllUninhabitedVariants { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(2 bytes) + --> $DIR/enum.rs:91:1 + | +LL | enum AlignedI8 { + | ^^^^^^^^^^^^^^ + +error: abi: Memory { sized: true } + --> $DIR/enum.rs:91:1 + | +LL | enum AlignedI8 { + | ^^^^^^^^^^^^^^ + +error: size: Size(4 bytes) + --> $DIR/enum.rs:99:1 + | +LL | enum TaggedI8 { + | ^^^^^^^^^^^^^ + +error: abi: Memory { sized: true } + --> $DIR/enum.rs:99:1 + | +LL | enum TaggedI8 { + | ^^^^^^^^^^^^^ + +error: size: Size(4 bytes) + --> $DIR/enum.rs:108:1 + | +LL | enum TaggedI16 { + | ^^^^^^^^^^^^^^ + +error: abi: ScalarPair(Initialized { value: Int(I16, false), valid_range: 0..=0 }, Initialized { value: Int(I16, true), valid_range: 0..=65535 }) + --> $DIR/enum.rs:108:1 + | +LL | enum TaggedI16 { + | ^^^^^^^^^^^^^^ + +error: size: Size(0 bytes) + --> $DIR/enum.rs:116:1 + | +LL | enum AllUninhabitedVariantsAlignedZst { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: Memory { sized: true } + --> $DIR/enum.rs:116:1 + | +LL | enum AllUninhabitedVariantsAlignedZst { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: (..=0) | (1..) }) + --> $DIR/enum.rs:131:1 + | +LL | type NPONever1 = Result; + | ^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: (..=0) | (1..) }) + --> $DIR/enum.rs:135:1 + | +LL | type NPONever2 = Result<(), NPONever>; + | ^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=4294967295 }) + --> $DIR/enum.rs:139:1 + | +LL | type NPONever3 = Result; + | ^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=4294967295 }) + --> $DIR/enum.rs:143:1 + | +LL | type NPONever4 = Result; + | ^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=4294967295 }) + --> $DIR/enum.rs:147:1 + | +LL | type NPONever5 = Result<&'static (), !>; + | ^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=4294967295 }) + --> $DIR/enum.rs:151:1 + | +LL | type NPONever6 = Result; + | ^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I16, true), valid_range: 1..=65535 }) + --> $DIR/enum.rs:155:1 + | +LL | type NPONever7 = Result, !>; + | ^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I16, true), valid_range: 1..=65535 }) + --> $DIR/enum.rs:159:1 + | +LL | type NPONever8 = Result>; + | ^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I16, true), valid_range: 1..=65535 }) + --> $DIR/enum.rs:163:1 + | +LL | type NPONever9 = Result; + | ^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I16, true), valid_range: 1..=65535 }) + --> $DIR/enum.rs:167:1 + | +LL | type NPONever10 = Result; + | ^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I16, true), valid_range: (..=0) | (1..) }) + --> $DIR/enum.rs:171:1 + | +LL | type NPONever11 = Result; + | ^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I16, true), valid_range: (..=0) | (1..) }) + --> $DIR/enum.rs:175:1 + | +LL | type NPONever12 = Result<(), NPONeverI16>; + | ^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=4294967295 }) + --> $DIR/enum.rs:179:1 + | +LL | enum NPONever13 { + | ^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: (..=0) | (1..) }) + --> $DIR/enum.rs:185:1 + | +LL | enum NPONever14 { + | ^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=4294967295 }) + --> $DIR/enum.rs:191:1 + | +LL | enum NPONever15 { + | ^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I32, false), valid_range: 0..=0 }) + --> $DIR/enum.rs:199:1 + | +LL | type NotNPONever1 = Result; + | ^^^^^^^^^^^^^^^^^ + +error: abi: Memory { sized: true } + --> $DIR/enum.rs:203:1 + | +LL | type NotNPONever2 = Result; + | ^^^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=4294967295 }) + --> $DIR/enum.rs:207:1 + | +LL | type NotNPONever3 = Result; + | ^^^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=4294967295 }) + --> $DIR/enum.rs:211:1 + | +LL | type NotNPONever4 = Result<&'static (), AlignedNever>; + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 41 previous errors + diff --git a/tests/ui/layout/enum.bit64.stderr b/tests/ui/layout/enum.bit64.stderr new file mode 100644 index 0000000000000..6d205c7edea56 --- /dev/null +++ b/tests/ui/layout/enum.bit64.stderr @@ -0,0 +1,360 @@ +error: align: AbiAlign { abi: Align(2 bytes) } + --> $DIR/enum.rs:12:1 + | +LL | enum UninhabitedVariantAlign { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(15 bytes) + --> $DIR/enum.rs:18:1 + | +LL | enum UninhabitedVariantSpace { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=1 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }) + --> $DIR/enum.rs:24:1 + | +LL | enum ScalarPairDifferingSign { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(4 bytes) + --> $DIR/enum.rs:32:1 + | +LL | enum AbsentVariantUntagged { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I32, true), valid_range: 0..=4294967295 }) + --> $DIR/enum.rs:32:1 + | +LL | enum AbsentVariantUntagged { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(4 bytes) + --> $DIR/enum.rs:41:1 + | +LL | enum UninhabitedVariantUntagged { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I32, true), valid_range: 0..=4294967295 }) + --> $DIR/enum.rs:41:1 + | +LL | enum UninhabitedVariantUntagged { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(8 bytes) + --> $DIR/enum.rs:52:1 + | +LL | enum UninhabitedVariantUntaggedBigger { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=0 }, Initialized { value: Int(I32, true), valid_range: 0..=4294967295 }) + --> $DIR/enum.rs:52:1 + | +LL | enum UninhabitedVariantUntaggedBigger { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(2 bytes) + --> $DIR/enum.rs:59:1 + | +LL | enum UninhabitedVariantWithNiche { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=1 }, Initialized { value: Int(I8, true), valid_range: 0..=255 }) + --> $DIR/enum.rs:59:1 + | +LL | enum UninhabitedVariantWithNiche { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: layout_of(UninhabitedVariantLargeWithNiche) = Layout { + size: Size(3 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 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), + ], + memory_index: [ + 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(3 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + Size(1 bytes), + Size(2 bytes), + Size(3 bytes), + ], + memory_index: [ + 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:66:1 + | +LL | enum UninhabitedVariantLargeWithNiche { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(2 bytes) + --> $DIR/enum.rs:80:1 + | +LL | enum AllUninhabitedVariants { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: Memory { sized: true } + --> $DIR/enum.rs:80:1 + | +LL | enum AllUninhabitedVariants { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: size: Size(2 bytes) + --> $DIR/enum.rs:91:1 + | +LL | enum AlignedI8 { + | ^^^^^^^^^^^^^^ + +error: abi: Memory { sized: true } + --> $DIR/enum.rs:91:1 + | +LL | enum AlignedI8 { + | ^^^^^^^^^^^^^^ + +error: size: Size(4 bytes) + --> $DIR/enum.rs:99:1 + | +LL | enum TaggedI8 { + | ^^^^^^^^^^^^^ + +error: abi: Memory { sized: true } + --> $DIR/enum.rs:99:1 + | +LL | enum TaggedI8 { + | ^^^^^^^^^^^^^ + +error: size: Size(4 bytes) + --> $DIR/enum.rs:108:1 + | +LL | enum TaggedI16 { + | ^^^^^^^^^^^^^^ + +error: abi: ScalarPair(Initialized { value: Int(I16, false), valid_range: 0..=0 }, Initialized { value: Int(I16, true), valid_range: 0..=65535 }) + --> $DIR/enum.rs:108:1 + | +LL | enum TaggedI16 { + | ^^^^^^^^^^^^^^ + +error: size: Size(0 bytes) + --> $DIR/enum.rs:116:1 + | +LL | enum AllUninhabitedVariantsAlignedZst { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: Memory { sized: true } + --> $DIR/enum.rs:116:1 + | +LL | enum AllUninhabitedVariantsAlignedZst { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: (..=0) | (1..) }) + --> $DIR/enum.rs:131:1 + | +LL | type NPONever1 = Result; + | ^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: (..=0) | (1..) }) + --> $DIR/enum.rs:135:1 + | +LL | type NPONever2 = Result<(), NPONever>; + | ^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }) + --> $DIR/enum.rs:139:1 + | +LL | type NPONever3 = Result; + | ^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }) + --> $DIR/enum.rs:143:1 + | +LL | type NPONever4 = Result; + | ^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }) + --> $DIR/enum.rs:147:1 + | +LL | type NPONever5 = Result<&'static (), !>; + | ^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }) + --> $DIR/enum.rs:151:1 + | +LL | type NPONever6 = Result; + | ^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I16, true), valid_range: 1..=65535 }) + --> $DIR/enum.rs:155:1 + | +LL | type NPONever7 = Result, !>; + | ^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I16, true), valid_range: 1..=65535 }) + --> $DIR/enum.rs:159:1 + | +LL | type NPONever8 = Result>; + | ^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I16, true), valid_range: 1..=65535 }) + --> $DIR/enum.rs:163:1 + | +LL | type NPONever9 = Result; + | ^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I16, true), valid_range: 1..=65535 }) + --> $DIR/enum.rs:167:1 + | +LL | type NPONever10 = Result; + | ^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I16, true), valid_range: (..=0) | (1..) }) + --> $DIR/enum.rs:171:1 + | +LL | type NPONever11 = Result; + | ^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I16, true), valid_range: (..=0) | (1..) }) + --> $DIR/enum.rs:175:1 + | +LL | type NPONever12 = Result<(), NPONeverI16>; + | ^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }) + --> $DIR/enum.rs:179:1 + | +LL | enum NPONever13 { + | ^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: (..=0) | (1..) }) + --> $DIR/enum.rs:185:1 + | +LL | enum NPONever14 { + | ^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }) + --> $DIR/enum.rs:191:1 + | +LL | enum NPONever15 { + | ^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Int(I64, false), valid_range: 0..=0 }) + --> $DIR/enum.rs:199:1 + | +LL | type NotNPONever1 = Result; + | ^^^^^^^^^^^^^^^^^ + +error: abi: Memory { sized: true } + --> $DIR/enum.rs:203:1 + | +LL | type NotNPONever2 = Result; + | ^^^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }) + --> $DIR/enum.rs:207:1 + | +LL | type NotNPONever3 = Result; + | ^^^^^^^^^^^^^^^^^ + +error: abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }) + --> $DIR/enum.rs:211:1 + | +LL | type NotNPONever4 = Result<&'static (), AlignedNever>; + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 41 previous errors + diff --git a/tests/ui/layout/enum.rs b/tests/ui/layout/enum.rs index 005faf8ee508d..81ad547e2013a 100644 --- a/tests/ui/layout/enum.rs +++ b/tests/ui/layout/enum.rs @@ -1,4 +1,7 @@ //@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ revisions: bit32 bit64 +//@[bit32] only-32bit +//@[bit64] only-64bit //! Various enum layout tests. #![feature(rustc_attrs)] @@ -12,7 +15,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. } @@ -22,3 +25,188 @@ 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(4 bytes) + //~^ ERROR: abi: Scalar(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: ScalarPair + A(i32), + B([u8; 5], !), +} + +#[rustc_layout(size, abi)] +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, !), +} + +#[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(2 bytes) + //~^ERROR: abi: Memory + A(i8, bool, !), + B(u8, u8, !), +} + +#[repr(align(2))] +struct AlignedNever(!); + +// Tagged `(u8, i8)` +#[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: 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(0 bytes) + //~^ERROR: abi: Memory + A(AlignedNever), + B(AlignedNever), +} + + +#[repr(transparent)] +struct NPONever(&'static (), !); + +#[repr(transparent)] +struct NPONeverI16(std::num::NonZero, !); + +// All of these should be NPO-optimized, despite uninhabitedness of one or more variants +#[rustc_layout(abi)] +type NPONever1 = Result; +//~^ ERROR: abi: Scalar(Initialized { value: Pointer + +#[rustc_layout(abi)] +type NPONever2 = Result<(), NPONever>; +//~^ ERROR: abi: Scalar(Initialized { value: Pointer + +#[rustc_layout(abi)] +type NPONever3 = Result; +//~^ ERROR: abi: Scalar(Initialized { value: Pointer + +#[rustc_layout(abi)] +type NPONever4 = Result; +//~^ ERROR: abi: Scalar(Initialized { value: Pointer + +#[rustc_layout(abi)] +type NPONever5 = Result<&'static (), !>; +//~^ ERROR: abi: Scalar(Initialized { value: Pointer + +#[rustc_layout(abi)] +type NPONever6 = Result; +//~^ ERROR: abi: Scalar(Initialized { value: Pointer + +#[rustc_layout(abi)] +type NPONever7 = Result, !>; +//~^ERROR: abi: Scalar(Initialized { value: Int(I16 + +#[rustc_layout(abi)] +type NPONever8 = Result>; +//~^ERROR: abi: Scalar(Initialized { value: Int(I16 + +#[rustc_layout(abi)] +type NPONever9 = Result; +//~^ERROR: abi: Scalar(Initialized { value: Int(I16 + +#[rustc_layout(abi)] +type NPONever10 = Result; +//~^ERROR: abi: Scalar(Initialized { value: Int(I16 + +#[rustc_layout(abi)] +type NPONever11 = Result; +//~^ERROR: abi: Scalar(Initialized { value: Int(I16 + +#[rustc_layout(abi)] +type NPONever12 = Result<(), NPONeverI16>; +//~^ERROR: abi: Scalar(Initialized { value: Int(I16 + +#[rustc_layout(abi)] +enum NPONever13 { //~ERROR: abi: Scalar(Initialized { value: Pointer + A(!, &'static (), !), + B((), !, [u8; 0]), +} + +#[rustc_layout(abi)] +enum NPONever14 { //~ERROR: abi: Scalar(Initialized { value: Pointer + A(!, &'static (), !), + B((), (), [u8; 0]), +} + +#[rustc_layout(abi)] +enum NPONever15 { //~ERROR: abi: Scalar(Initialized { value: Pointer + A((), &'static (), ()), + B((), !, [u8; 0]), +} + + +// These are not guaranteed to be NPO-optimized +#[rustc_layout(abi)] +type NotNPONever1 = Result; +//~^ERROR: abi: Scalar(Initialized { value: Int + +#[rustc_layout(abi)] +type NotNPONever2 = Result; +//~^ERROR: abi: Memory + +#[rustc_layout(abi)] +type NotNPONever3 = Result; +//~^ERROR: abi: Scalar( + +#[rustc_layout(abi)] +type NotNPONever4 = Result<&'static (), AlignedNever>; +//~^ERROR: abi: Scalar( diff --git a/tests/ui/layout/enum.stderr b/tests/ui/layout/enum.stderr deleted file mode 100644 index f95b577bfc9df..0000000000000 --- a/tests/ui/layout/enum.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: align: AbiAlign { abi: Align(2 bytes) } - --> $DIR/enum.rs:9:1 - | -LL | enum UninhabitedVariantAlign { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: size: Size(16 bytes) - --> $DIR/enum.rs:15:1 - | -LL | enum UninhabitedVariantSpace { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=1 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }) - --> $DIR/enum.rs:21:1 - | -LL | enum ScalarPairDifferingSign { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors - diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr index d910456c0e6d1..22d6082d0c38e 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 2087fedeb19bc..bd8f379a4a274 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 6bcc5b4906b50..6bd931f78f754 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 9bd8ced0c02d6..8ccb145cf85f5 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 1707b8aff81cf..6d3e1121fbe69 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/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 64850e4782335..20335c0061610 100644 --- a/tests/ui/offset-of/offset-of-enum.rs +++ b/tests/ui/offset-of/offset-of-enum.rs @@ -2,9 +2,12 @@ use std::mem::offset_of; +enum Never {} + enum Alpha { One(u8), Two(u8), + Three(u8, u8, Never), } fn main() { @@ -15,4 +18,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 7e7ad41f5b6a9..4b345064a6a2a 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:11:16 + --> $DIR/offset-of-enum.rs:14: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[E0412]: cannot find type `Beta` in this scope - --> $DIR/offset-of-enum.rs:17:16 + --> $DIR/offset-of-enum.rs:20: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:12:23 + --> $DIR/offset-of-enum.rs:15:23 | LL | offset_of!(Alpha, One); | ^^^ enum variant error[E0609]: no field named `1` on enum variant `Alpha::Two` - --> $DIR/offset-of-enum.rs:14:23 + --> $DIR/offset-of-enum.rs:17: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:15:23 + --> $DIR/offset-of-enum.rs:18: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:16:23 + --> $DIR/offset-of-enum.rs:19: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:24:31 + | +LL | offset_of!(Alpha, Three.2.NonExistent); + | ^^^^^^^^^^^ variant not found + +error: aborting due to 7 previous errors Some errors have detailed explanations: E0412, E0573, E0599, E0609, E0795. For more information about an error, try `rustc --explain E0412`. 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 63d685951d981..8bf7a8872f089 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 555471be0271d..db42fa74a9678 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 63d685951d981..8bf7a8872f089 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 63d685951d981..8bf7a8872f089 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 d88a842f88482..8845a39f7f5e7 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/structs-enums/type-sizes.rs b/tests/ui/structs-enums/type-sizes.rs index a8fadcc1d1ec6..daa7a8b1cf6db 100644 --- a/tests/ui/structs-enums/type-sizes.rs +++ b/tests/ui/structs-enums/type-sizes.rs @@ -277,8 +277,16 @@ pub fn main() { assert_eq!(size_of::(), 1); assert_eq!(size_of::(), 1); - assert_eq!(size_of::>(), - size_of::>()); + assert_eq!(size_of::>(), 2 * size_of::<&'static ()>()); + assert_eq!(size_of::>(), size_of::<&'static ()>()); + assert_eq!( + size_of::>(), + 2 * size_of::<&'static ()>(), + ); + assert_eq!( + size_of::>(), + 2 * size_of::<&'static ()>(), + ); assert_eq!(size_of::(), size_of::<&'static ()>()); assert_eq!(size_of::(), 24); diff --git a/tests/ui/type/pattern_types/or_patterns.stderr b/tests/ui/type/pattern_types/or_patterns.stderr index a417e502e3562..dd4394f9b7ded 100644 --- a/tests/ui/type/pattern_types/or_patterns.stderr +++ b/tests/ui/type/pattern_types/or_patterns.stderr @@ -67,6 +67,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), @@ -105,6 +106,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 abd8b87fffc6f..83c5be45b22cb 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), @@ -71,6 +72,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), @@ -136,6 +138,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), @@ -176,6 +179,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), @@ -247,6 +251,7 @@ error: layout_of(Option>) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), @@ -287,6 +292,7 @@ error: layout_of(Option>) = Layout { uninhabited: false, variants: Single { index: 1, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -338,6 +344,7 @@ error: layout_of(NonZeroU32New) = Layout { uninhabited: false, variants: Single { index: 0, + variants: None, }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), @@ -404,6 +411,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), @@ -442,6 +450,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),