1
Fork 0

Rollup merge of #136985 - zachs18:backend-repr-remove-uninhabited, r=workingjubilee

Do not ignore uninhabited types for function-call ABI purposes. (Remove BackendRepr::Uninhabited)

Accepted MCP: https://github.com/rust-lang/compiler-team/issues/832

Fixes #135802

Do not consider the inhabitedness of a type for function call ABI purposes.

* Remove the [`rustc_abi::BackendRepr::Uninhabited`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_abi/enum.BackendRepr.html) variant
  * Instead calculate the `BackendRepr` of uninhabited types "normally" (as though they were not uninhabited "at the top level", but still considering inhabitedness of variants to determine enum layout, etc)
* Add an `uninhabited: bool` field to [`rustc_abi::LayoutData`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_abi/struct.LayoutData.html) so inhabitedness of a `LayoutData` can still be queried when necessary (e.g. when determining if an enum variant needs a tag value allocated to it).

This should not affect type layouts (size/align/field offset); this should only affect function call ABI, and only of uninhabited types.

cc ``@RalfJung``
This commit is contained in:
Jubilee 2025-02-20 14:58:18 -08:00 committed by GitHub
commit 8c9e3749a1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
49 changed files with 532 additions and 167 deletions

View file

@ -65,8 +65,6 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
Ty: TyAbiInterface<'a, C> + Copy,
{
match self.backend_repr {
BackendRepr::Uninhabited => Err(Heterogeneous),
// The primitive for this algorithm.
BackendRepr::Scalar(scalar) => {
let kind = match scalar.primitive() {

View file

@ -130,6 +130,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
},
backend_repr: BackendRepr::ScalarPair(a, b),
largest_niche,
uninhabited: false,
align,
size,
max_repr_align: None,
@ -221,8 +222,9 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
LayoutData {
variants: Variants::Empty,
fields: FieldsShape::Primitive,
backend_repr: BackendRepr::Uninhabited,
backend_repr: BackendRepr::Memory { sized: true },
largest_niche: None,
uninhabited: true,
align: dl.i8_align,
size: Size::ZERO,
max_repr_align: None,
@ -400,6 +402,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
fields: FieldsShape::Union(union_field_count),
backend_repr: abi,
largest_niche: None,
uninhabited: false,
align,
size: size.align_to(align.abi),
max_repr_align,
@ -447,7 +450,6 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
Scalar::Union { .. } => {}
};
match &mut st.backend_repr {
BackendRepr::Uninhabited => {}
BackendRepr::Scalar(scalar) => hide_niches(scalar),
BackendRepr::ScalarPair(a, b) => {
hide_niches(a);
@ -639,9 +641,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
let same_size = size == variant_layouts[largest_variant_index].size;
let same_align = align == variant_layouts[largest_variant_index].align;
let abi = if variant_layouts.iter().all(|v| v.is_uninhabited()) {
BackendRepr::Uninhabited
} else if same_size && same_align && others_zst {
let uninhabited = variant_layouts.iter().all(|v| v.is_uninhabited());
let abi = if same_size && same_align && others_zst {
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.
@ -683,6 +684,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
},
backend_repr: abi,
largest_niche,
uninhabited,
size,
align,
max_repr_align,
@ -853,9 +855,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
};
let mut abi = BackendRepr::Memory { sized: true };
if layout_variants.iter().all(|v| v.is_uninhabited()) {
abi = BackendRepr::Uninhabited;
} else if tag.size(dl) == size {
let uninhabited = layout_variants.iter().all(|v| v.is_uninhabited());
if tag.size(dl) == size {
// Make sure we only use scalar layout when the enum is entirely its
// own tag (i.e. it has no padding nor any non-ZST variant fields).
abi = BackendRepr::Scalar(tag);
@ -995,6 +996,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
memory_index: [0].into(),
},
largest_niche,
uninhabited,
backend_repr: abi,
align,
size,
@ -1355,9 +1357,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
_ => {}
}
}
if fields.iter().any(|f| f.is_uninhabited()) {
abi = BackendRepr::Uninhabited;
}
let uninhabited = fields.iter().any(|f| f.is_uninhabited());
let unadjusted_abi_align = if repr.transparent() {
match layout_of_single_non_zst_field {
@ -1378,6 +1378,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
fields: FieldsShape::Arbitrary { offsets, memory_index },
backend_repr: abi,
largest_niche,
uninhabited,
align,
size,
max_repr_align,

View file

@ -1404,7 +1404,6 @@ impl AddressSpace {
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
pub enum BackendRepr {
Uninhabited,
Scalar(Scalar),
ScalarPair(Scalar, Scalar),
Vector {
@ -1423,10 +1422,9 @@ impl BackendRepr {
#[inline]
pub fn is_unsized(&self) -> bool {
match *self {
BackendRepr::Uninhabited
| BackendRepr::Scalar(_)
| BackendRepr::ScalarPair(..)
| BackendRepr::Vector { .. } => false,
BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) | BackendRepr::Vector { .. } => {
false
}
BackendRepr::Memory { sized } => !sized,
}
}
@ -1445,12 +1443,6 @@ impl BackendRepr {
}
}
/// Returns `true` if this is an uninhabited type
#[inline]
pub fn is_uninhabited(&self) -> bool {
matches!(*self, BackendRepr::Uninhabited)
}
/// Returns `true` if this is a scalar type
#[inline]
pub fn is_scalar(&self) -> bool {
@ -1471,7 +1463,7 @@ impl BackendRepr {
BackendRepr::Vector { element, count } => {
cx.data_layout().vector_align(element.size(cx) * count)
}
BackendRepr::Uninhabited | BackendRepr::Memory { .. } => return None,
BackendRepr::Memory { .. } => return None,
})
}
@ -1492,7 +1484,7 @@ impl BackendRepr {
// to make the size a multiple of align (e.g. for vectors of size 3).
(element.size(cx) * count).align_to(self.inherent_align(cx)?.abi)
}
BackendRepr::Uninhabited | BackendRepr::Memory { .. } => return None,
BackendRepr::Memory { .. } => return None,
})
}
@ -1506,9 +1498,7 @@ impl BackendRepr {
BackendRepr::Vector { element, count } => {
BackendRepr::Vector { element: element.to_union(), count }
}
BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {
BackendRepr::Memory { sized: true }
}
BackendRepr::Memory { .. } => BackendRepr::Memory { sized: true },
}
}
@ -1704,6 +1694,11 @@ pub struct LayoutData<FieldIdx: Idx, VariantIdx: Idx> {
/// The leaf scalar with the largest number of invalid values
/// (i.e. outside of its `valid_range`), if it exists.
pub largest_niche: Option<Niche>,
/// Is this type known to be uninhabted?
///
/// This is separate from BackendRepr because uninhabited return types can affect ABI,
/// especially in the case of by-pointer struct returns, which allocate stack even when unused.
pub uninhabited: bool,
pub align: AbiAndPrefAlign,
pub size: Size,
@ -1735,14 +1730,14 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
/// Returns `true` if this is an aggregate type (including a ScalarPair!)
pub fn is_aggregate(&self) -> bool {
match self.backend_repr {
BackendRepr::Uninhabited | BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => false,
BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => false,
BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => true,
}
}
/// Returns `true` if this is an uninhabited type
pub fn is_uninhabited(&self) -> bool {
self.backend_repr.is_uninhabited()
self.uninhabited
}
pub fn scalar<C: HasDataLayout>(cx: &C, scalar: Scalar) -> Self {
@ -1778,6 +1773,7 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
fields: FieldsShape::Primitive,
backend_repr: BackendRepr::Scalar(scalar),
largest_niche,
uninhabited: false,
size,
align,
max_repr_align: None,
@ -1802,6 +1798,7 @@ where
backend_repr,
fields,
largest_niche,
uninhabited,
variants,
max_repr_align,
unadjusted_abi_align,
@ -1813,6 +1810,7 @@ where
.field("abi", backend_repr)
.field("fields", fields)
.field("largest_niche", largest_niche)
.field("uninhabited", uninhabited)
.field("variants", variants)
.field("max_repr_align", max_repr_align)
.field("unadjusted_abi_align", unadjusted_abi_align)
@ -1877,7 +1875,6 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) | BackendRepr::Vector { .. } => {
false
}
BackendRepr::Uninhabited => self.size.bytes() == 0,
BackendRepr::Memory { sized } => sized && self.size.bytes() == 0,
}
}

View file

@ -638,9 +638,7 @@ impl<'tcx> CPlace<'tcx> {
}
CPlaceInner::Addr(_, Some(_)) => bug!("Can't write value to unsized place {:?}", self),
CPlaceInner::Addr(to_ptr, None) => {
if dst_layout.size == Size::ZERO
|| dst_layout.backend_repr == BackendRepr::Uninhabited
{
if dst_layout.size == Size::ZERO {
return;
}

View file

@ -315,7 +315,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
let layout = self.layout_of(tp_ty).layout;
let _use_integer_compare = match layout.backend_repr() {
Scalar(_) | ScalarPair(_, _) => true,
Uninhabited | Vector { .. } => false,
Vector { .. } => false,
Memory { .. } => {
// For rusty ABIs, small aggregates are actually passed
// as `RegKind::Integer` (see `FnAbi::adjust_for_abi`),

View file

@ -84,7 +84,7 @@ fn uncached_gcc_type<'gcc, 'tcx>(
false,
);
}
BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {}
BackendRepr::Memory { .. } => {}
}
let name = match *layout.ty.kind() {
@ -179,19 +179,16 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
fn is_gcc_immediate(&self) -> bool {
match self.backend_repr {
BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => true,
BackendRepr::ScalarPair(..) | BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {
false
}
BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false,
}
}
fn is_gcc_scalar_pair(&self) -> bool {
match self.backend_repr {
BackendRepr::ScalarPair(..) => true,
BackendRepr::Uninhabited
| BackendRepr::Scalar(_)
| BackendRepr::Vector { .. }
| BackendRepr::Memory { .. } => false,
BackendRepr::Scalar(_) | BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => {
false
}
}
}

View file

@ -476,7 +476,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
let layout = self.layout_of(tp_ty).layout;
let use_integer_compare = match layout.backend_repr() {
Scalar(_) | ScalarPair(_, _) => true,
Uninhabited | Vector { .. } => false,
Vector { .. } => false,
Memory { .. } => {
// For rusty ABIs, small aggregates are actually passed
// as `RegKind::Integer` (see `FnAbi::adjust_for_abi`),

View file

@ -23,7 +23,7 @@ fn uncached_llvm_type<'a, 'tcx>(
let element = layout.scalar_llvm_type_at(cx, element);
return cx.type_vector(element, count);
}
BackendRepr::Uninhabited | BackendRepr::Memory { .. } | BackendRepr::ScalarPair(..) => {}
BackendRepr::Memory { .. } | BackendRepr::ScalarPair(..) => {}
}
let name = match layout.ty.kind() {
@ -172,19 +172,16 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
fn is_llvm_immediate(&self) -> bool {
match self.backend_repr {
BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => true,
BackendRepr::ScalarPair(..) | BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {
false
}
BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false,
}
}
fn is_llvm_scalar_pair(&self) -> bool {
match self.backend_repr {
BackendRepr::ScalarPair(..) => true,
BackendRepr::Uninhabited
| BackendRepr::Scalar(_)
| BackendRepr::Vector { .. }
| BackendRepr::Memory { .. } => false,
BackendRepr::Scalar(_) | BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => {
false
}
}
}

View file

@ -4,9 +4,7 @@ use rustc_abi::{BackendRepr, ExternAbi, HasDataLayout, Reg, WrappingRange};
use rustc_ast as ast;
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir::lang_items::LangItem;
use rustc_middle::mir::{
self, AssertKind, BasicBlock, InlineAsmMacro, SwitchTargets, UnwindTerminateReason,
};
use rustc_middle::mir::{self, AssertKind, InlineAsmMacro, SwitchTargets, UnwindTerminateReason};
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use rustc_middle::ty::{self, Instance, Ty};
@ -942,7 +940,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
&fn_abi.ret,
&mut llargs,
Some(intrinsic),
target,
);
let dest = match ret_dest {
_ if fn_abi.ret.is_indirect() => llargs[0],
@ -998,19 +995,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
};
let mut llargs = Vec::with_capacity(arg_count);
let destination = target.as_ref().map(|&target| {
(
self.make_return_dest(
bx,
destination,
&fn_abi.ret,
&mut llargs,
None,
Some(target),
),
target,
)
});
// We still need to call `make_return_dest` even if there's no `target`, since
// `fn_abi.ret` could be `PassMode::Indirect`, even if it is uninhabited,
// and `make_return_dest` adds the return-place indirect pointer to `llargs`.
let return_dest = self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs, None);
let destination = target.map(|target| (return_dest, target));
// Split the rust-call tupled arguments off.
let (first_args, untuple) = if abi == ExternAbi::RustCall && !args.is_empty() {
@ -1813,11 +1803,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
fn_ret: &ArgAbi<'tcx, Ty<'tcx>>,
llargs: &mut Vec<Bx::Value>,
intrinsic: Option<ty::IntrinsicDef>,
target: Option<BasicBlock>,
) -> ReturnDest<'tcx, Bx::Value> {
if target.is_none() {
return ReturnDest::Nothing;
}
// If the return is ignored, we can just return a do-nothing `ReturnDest`.
if fn_ret.is_ignore() {
return ReturnDest::Nothing;

View file

@ -422,9 +422,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
See <https://github.com/rust-lang/rust/issues/137108>",
);
}
BackendRepr::Uninhabited
| BackendRepr::ScalarPair(_, _)
| BackendRepr::Memory { sized: false } => bug!(),
BackendRepr::ScalarPair(_, _) | BackendRepr::Memory { sized: false } => bug!(),
})
};

View file

@ -385,7 +385,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
(Immediate::Uninit, _) => Immediate::Uninit,
// If the field is uninhabited, we can forget the data (can happen in ConstProp).
// `enum S { A(!), B, C }` is an example of an enum with Scalar layout that
// has an `Uninhabited` variant, which means this case is possible.
// has an uninhabited variant, which means this case is possible.
_ if layout.is_uninhabited() => Immediate::Uninit,
// the field contains no information, can be left uninit
// (Scalar/ScalarPair can contain even aligned ZST, not just 1-ZST)

View file

@ -1264,21 +1264,20 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
}
}
// *After* all of this, check the ABI. We need to check the ABI to handle
// types like `NonNull` where the `Scalar` info is more restrictive than what
// the fields say (`rustc_layout_scalar_valid_range_start`).
// But in most cases, this will just propagate what the fields say,
// and then we want the error to point at the field -- so, first recurse,
// then check ABI.
// *After* all of this, check further information stored in the layout. We need to check
// this to handle types like `NonNull` where the `Scalar` info is more restrictive than what
// the fields say (`rustc_layout_scalar_valid_range_start`). But in most cases, this will
// just propagate what the fields say, and then we want the error to point at the field --
// so, we first recurse, then we do this check.
//
// FIXME: We could avoid some redundant checks here. For newtypes wrapping
// scalars, we do the same check on every "level" (e.g., first we check
// MyNewtype and then the scalar in there).
match val.layout.backend_repr {
BackendRepr::Uninhabited => {
if val.layout.is_uninhabited() {
let ty = val.layout.ty;
throw_validation_failure!(self.path, UninhabitedVal { ty });
}
match val.layout.backend_repr {
BackendRepr::Scalar(scalar_layout) => {
if !scalar_layout.is_uninit_valid() {
// There is something to check here.

View file

@ -111,10 +111,12 @@ fn check_validity_requirement_lax<'tcx>(
};
// Check the ABI.
let valid = match this.backend_repr {
BackendRepr::Uninhabited => false, // definitely UB
let valid = !this.is_uninhabited() // definitely UB if uninhabited
&& match this.backend_repr {
BackendRepr::Scalar(s) => scalar_allows_raw_init(s),
BackendRepr::ScalarPair(s1, s2) => scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2),
BackendRepr::ScalarPair(s1, s2) => {
scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2)
}
BackendRepr::Vector { element: s, count } => count == 0 || scalar_allows_raw_init(s),
BackendRepr::Memory { .. } => true, // Fields are checked below.
};

View file

@ -794,8 +794,9 @@ where
Some(fields) => FieldsShape::Union(fields),
None => FieldsShape::Arbitrary { offsets: IndexVec::new(), memory_index: IndexVec::new() },
},
backend_repr: BackendRepr::Uninhabited,
backend_repr: BackendRepr::Memory { sized: true },
largest_niche: None,
uninhabited: true,
align: tcx.data_layout.i8_align,
size: Size::ZERO,
max_repr_align: None,

View file

@ -1558,8 +1558,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
return true;
};
if layout.uninhabited {
return true;
}
match layout.backend_repr {
BackendRepr::Uninhabited => true,
BackendRepr::Scalar(a) => !a.is_always_valid(&self.ecx),
BackendRepr::ScalarPair(a, b) => {
!a.is_always_valid(&self.ecx) || !b.is_always_valid(&self.ecx)

View file

@ -202,7 +202,6 @@ impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr {
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
match *self {
rustc_abi::BackendRepr::Uninhabited => ValueAbi::Uninhabited,
rustc_abi::BackendRepr::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables)),
rustc_abi::BackendRepr::ScalarPair(first, second) => {
ValueAbi::ScalarPair(first.stable(tables), second.stable(tables))

View file

@ -80,7 +80,7 @@ where
}
}
},
BackendRepr::Vector { .. } | BackendRepr::Uninhabited => return Err(CannotUseFpConv),
BackendRepr::Vector { .. } => return Err(CannotUseFpConv),
BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => match arg_layout.fields {
FieldsShape::Primitive => {
unreachable!("aggregates can't have `FieldsShape::Primitive`")

View file

@ -38,7 +38,7 @@ mod xtensa;
pub enum PassMode {
/// Ignore the argument.
///
/// The argument is either uninhabited or a ZST.
/// The argument is a ZST.
Ignore,
/// Pass the argument directly.
///
@ -350,7 +350,6 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
scalar_attrs: impl Fn(&TyAndLayout<'a, Ty>, Scalar, Size) -> ArgAttributes,
) -> Self {
let mode = match layout.backend_repr {
BackendRepr::Uninhabited => PassMode::Ignore,
BackendRepr::Scalar(scalar) => {
PassMode::Direct(scalar_attrs(&layout, scalar, Size::ZERO))
}

View file

@ -86,7 +86,7 @@ where
}
}
},
BackendRepr::Vector { .. } | BackendRepr::Uninhabited => return Err(CannotUseFpConv),
BackendRepr::Vector { .. } => return Err(CannotUseFpConv),
BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => match arg_layout.fields {
FieldsShape::Primitive => {
unreachable!("aggregates can't have `FieldsShape::Primitive`")

View file

@ -108,9 +108,7 @@ where
Ty: TyAbiInterface<'a, C> + Copy,
{
match layout.backend_repr {
BackendRepr::Uninhabited
| BackendRepr::Scalar(_)
| BackendRepr::ScalarPair(..) => false,
BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) => false,
BackendRepr::Vector { .. } => true,
BackendRepr::Memory { .. } => {
for i in 0..layout.fields.count() {

View file

@ -51,8 +51,6 @@ where
}
let mut c = match layout.backend_repr {
BackendRepr::Uninhabited => return Ok(()),
BackendRepr::Scalar(scalar) => match scalar.primitive() {
Primitive::Int(..) | Primitive::Pointer(_) => Class::Int,
Primitive::Float(_) => Class::Sse,

View file

@ -8,7 +8,7 @@ use crate::spec::{HasTargetSpec, RustcAbi};
pub(crate) fn compute_abi_info<Ty>(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {
let fixup = |a: &mut ArgAbi<'_, Ty>, is_ret: bool| {
match a.layout.backend_repr {
BackendRepr::Uninhabited | BackendRepr::Memory { sized: false } => {}
BackendRepr::Memory { sized: false } => {}
BackendRepr::ScalarPair(..) | BackendRepr::Memory { sized: true } => {
match a.layout.size.bits() {
8 => a.cast_to(Reg::i8()),

View file

@ -464,7 +464,7 @@ fn fn_abi_sanity_check<'tcx>(
match &arg.mode {
PassMode::Ignore => {
assert!(arg.layout.is_zst() || arg.layout.is_uninhabited());
assert!(arg.layout.is_zst());
}
PassMode::Direct(_) => {
// Here the Rust type is used to determine the actual ABI, so we have to be very
@ -472,9 +472,7 @@ fn fn_abi_sanity_check<'tcx>(
// `layout.backend_repr` and ignore everything else. We should just reject
//`Aggregate` entirely here, but some targets need to be fixed first.
match arg.layout.backend_repr {
BackendRepr::Uninhabited
| BackendRepr::Scalar(_)
| BackendRepr::Vector { .. } => {}
BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => {}
BackendRepr::ScalarPair(..) => {
panic!("`PassMode::Direct` used for ScalarPair type {}", arg.layout.ty)
}

View file

@ -348,19 +348,17 @@ fn layout_of_uncached<'tcx>(
.checked_mul(count, dl)
.ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?;
let abi = if count != 0 && ty.is_privately_uninhabited(tcx, cx.typing_env) {
BackendRepr::Uninhabited
} else {
BackendRepr::Memory { sized: true }
};
let abi = BackendRepr::Memory { sized: true };
let largest_niche = if count != 0 { element.largest_niche } else { None };
let uninhabited = if count != 0 { element.uninhabited } else { false };
tcx.mk_layout(LayoutData {
variants: Variants::Single { index: FIRST_VARIANT },
fields: FieldsShape::Array { stride: element.size, count },
backend_repr: abi,
largest_niche,
uninhabited,
align: element.align,
size,
max_repr_align: None,
@ -375,6 +373,7 @@ fn layout_of_uncached<'tcx>(
fields: FieldsShape::Array { stride: element.size, count: 0 },
backend_repr: BackendRepr::Memory { sized: false },
largest_niche: None,
uninhabited: false,
align: element.align,
size: Size::ZERO,
max_repr_align: None,
@ -390,6 +389,7 @@ fn layout_of_uncached<'tcx>(
fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
backend_repr: BackendRepr::Memory { sized: false },
largest_niche: None,
uninhabited: false,
align: dl.i8_align,
size: Size::ZERO,
max_repr_align: None,
@ -555,6 +555,7 @@ fn layout_of_uncached<'tcx>(
fields,
backend_repr: abi,
largest_niche: e_ly.largest_niche,
uninhabited: false,
size,
align,
max_repr_align: None,
@ -1014,13 +1015,8 @@ fn coroutine_layout<'tcx>(
size = size.align_to(align.abi);
let abi = if prefix.backend_repr.is_uninhabited()
|| variants.iter().all(|v| v.backend_repr.is_uninhabited())
{
BackendRepr::Uninhabited
} else {
BackendRepr::Memory { sized: true }
};
let uninhabited = prefix.uninhabited || variants.iter().all(|v| v.is_uninhabited());
let abi = BackendRepr::Memory { sized: true };
// this is similar to how ReprOptions populates its field_shuffle_seed
let def_hash = tcx.def_path_hash(def_id).0.to_smaller_hash();
@ -1041,6 +1037,7 @@ fn coroutine_layout<'tcx>(
// See <https://github.com/rust-lang/rust/issues/63818>, <https://github.com/rust-lang/miri/issues/3780>.
// FIXME: Remove when <https://github.com/rust-lang/rust/issues/125735> is implemented and aliased coroutine fields are wrapped in `UnsafePinned`.
largest_niche: None,
uninhabited,
size,
align,
max_repr_align: None,

View file

@ -10,7 +10,11 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou
// Type-level uninhabitedness should always imply ABI uninhabitedness.
if layout.ty.is_privately_uninhabited(tcx, cx.typing_env) {
assert!(layout.is_uninhabited());
assert!(
layout.is_uninhabited(),
"{:?} is type-level uninhabited but not ABI-uninhabited?",
layout.ty
);
}
if layout.size.bytes() % layout.align.abi.bytes() != 0 {
@ -71,7 +75,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou
let Some((align, size)) = align.zip(size) else {
assert_matches!(
layout.layout.backend_repr(),
BackendRepr::Uninhabited | BackendRepr::Memory { .. },
BackendRepr::Memory { .. },
"ABI unexpectedly missing alignment and/or size in {layout:#?}"
);
return;
@ -235,7 +239,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou
assert!(align >= element.align(cx).abi); // just sanity-checking `vector_align`.
// FIXME: Do some kind of check of the inner type, like for Scalar and ScalarPair.
}
BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {} // Nothing to check.
BackendRepr::Memory { .. } => {} // Nothing to check.
}
}
@ -291,8 +295,8 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou
|| variant.is_uninhabited()
{
// These are never actually accessed anyway, so we can skip the coherence check
// for them. They also fail that check, since they have
// `Aggregate`/`Uninhabited` ABI even when the main type is
// for them. They also fail that check, since they may have
// a different ABI even when the main type is
// `Scalar`/`ScalarPair`. (Note that sometimes, variants with fields have size
// 0, and sometimes, variants without fields have non-0 size.)
continue;
@ -306,7 +310,6 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou
(BackendRepr::ScalarPair(a1, b1), BackendRepr::ScalarPair(a2, b2)) => {
scalar_coherent(a1, a2) && scalar_coherent(b1, b2)
}
(BackendRepr::Uninhabited, _) => true,
(BackendRepr::Memory { .. }, _) => true,
_ => false,
};

View file

@ -227,7 +227,6 @@ pub enum TagEncoding {
/// in terms of categories of C types there are ABI rules for.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum ValueAbi {
Uninhabited,
Scalar(Scalar),
ScalarPair(Scalar, Scalar),
Vector {
@ -244,10 +243,7 @@ impl ValueAbi {
/// Returns `true` if the layout corresponds to an unsized type.
pub fn is_unsized(&self) -> bool {
match *self {
ValueAbi::Uninhabited
| ValueAbi::Scalar(_)
| ValueAbi::ScalarPair(..)
| ValueAbi::Vector { .. } => false,
ValueAbi::Scalar(_) | ValueAbi::ScalarPair(..) | ValueAbi::Vector { .. } => false,
ValueAbi::Aggregate { sized } => !sized,
}
}

View file

@ -194,6 +194,7 @@ fn layout_of_simd_ty(
fields,
backend_repr: BackendRepr::Vector { element: e_abi, count: e_len },
largest_niche: e_ly.largest_niche,
uninhabited: false,
size,
align,
max_repr_align: None,
@ -297,20 +298,17 @@ pub fn layout_of_ty_query(
.checked_mul(count, dl)
.ok_or(LayoutError::BadCalc(LayoutCalculatorError::SizeOverflow))?;
let backend_repr =
if count != 0 && matches!(element.backend_repr, BackendRepr::Uninhabited) {
BackendRepr::Uninhabited
} else {
BackendRepr::Memory { sized: true }
};
let backend_repr = BackendRepr::Memory { sized: true };
let largest_niche = if count != 0 { element.largest_niche } else { None };
let uninhabited = if count != 0 { element.uninhabited } else { false };
Layout {
variants: Variants::Single { index: struct_variant_idx() },
fields: FieldsShape::Array { stride: element.size, count },
backend_repr,
largest_niche,
uninhabited,
align: element.align,
size,
max_repr_align: None,
@ -325,6 +323,7 @@ pub fn layout_of_ty_query(
fields: FieldsShape::Array { stride: element.size, count: 0 },
backend_repr: BackendRepr::Memory { sized: false },
largest_niche: None,
uninhabited: false,
align: element.align,
size: Size::ZERO,
max_repr_align: None,
@ -337,6 +336,7 @@ pub fn layout_of_ty_query(
fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
backend_repr: BackendRepr::Memory { sized: false },
largest_niche: None,
uninhabited: false,
align: dl.i8_align,
size: Size::ZERO,
max_repr_align: None,

View file

@ -0,0 +1,44 @@
//@ compile-flags: -Copt-level=3
// See https://github.com/rust-lang/rust/issues/135802
#![crate_type = "lib"]
enum Void {}
// Should be ABI-compatible with T, but wasn't prior to the PR adding this test.
#[repr(transparent)]
struct NoReturn<T>(T, Void);
// Returned by invisible reference (in most ABIs)
#[allow(dead_code)]
struct Large(u64, u64, u64);
extern "Rust" {
fn opaque() -> NoReturn<Large>;
fn opaque_with_arg(rsi: u32) -> NoReturn<Large>;
}
// CHECK-LABEL: @test_uninhabited_ret_by_ref
#[no_mangle]
pub fn test_uninhabited_ret_by_ref() {
// CHECK: %_1 = alloca [24 x i8], align {{8|4}}
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %_1)
// CHECK-NEXT: call void @opaque(ptr noalias nocapture noundef nonnull sret([24 x i8]) align {{8|4}} dereferenceable(24) %_1) #2
// CHECK-NEXT: unreachable
unsafe {
opaque();
}
}
// CHECK-LABEL: @test_uninhabited_ret_by_ref_with_arg
#[no_mangle]
pub fn test_uninhabited_ret_by_ref_with_arg(rsi: u32) {
// CHECK: %_2 = alloca [24 x i8], align {{8|4}}
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %_2)
// CHECK-NEXT: call void @opaque_with_arg(ptr noalias nocapture noundef nonnull sret([24 x i8]) align {{8|4}} dereferenceable(24) %_2, i32 noundef %rsi) #2
// CHECK-NEXT: unreachable
unsafe {
opaque_with_arg(rsi);
}
}

View file

@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -45,6 +46,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},

View file

@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -56,6 +57,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},

View file

@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -56,6 +57,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},

View file

@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -56,6 +57,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},

View file

@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -45,6 +46,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},

View file

@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -56,6 +57,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},

View file

@ -20,6 +20,7 @@ error: fn_abi_of(test) = FnAbi {
),
fields: Primitive,
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -67,6 +68,7 @@ error: fn_abi_of(test) = FnAbi {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Single {
index: 0,
},
@ -125,6 +127,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Single {
index: 0,
},
@ -163,6 +166,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi {
),
fields: Primitive,
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -213,6 +217,7 @@ error: fn_abi_of(test_generic) = FnAbi {
),
fields: Primitive,
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -248,6 +253,7 @@ error: fn_abi_of(test_generic) = FnAbi {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -297,6 +303,7 @@ error: ABIs are not compatible
),
fields: Primitive,
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -332,6 +339,7 @@ error: ABIs are not compatible
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -369,6 +377,7 @@ error: ABIs are not compatible
),
fields: Primitive,
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -404,6 +413,7 @@ error: ABIs are not compatible
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -444,6 +454,7 @@ error: ABIs are not compatible
count: 32,
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -483,6 +494,7 @@ error: ABIs are not compatible
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -517,6 +529,7 @@ error: ABIs are not compatible
count: 32,
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -556,6 +569,7 @@ error: ABIs are not compatible
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -598,6 +612,7 @@ error: ABIs are not compatible
),
fields: Primitive,
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -633,6 +648,7 @@ error: ABIs are not compatible
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -670,6 +686,7 @@ error: ABIs are not compatible
),
fields: Primitive,
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -705,6 +722,7 @@ error: ABIs are not compatible
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -748,6 +766,7 @@ error: ABIs are not compatible
),
fields: Primitive,
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -783,6 +802,7 @@ error: ABIs are not compatible
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -820,6 +840,7 @@ error: ABIs are not compatible
),
fields: Primitive,
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -855,6 +876,7 @@ error: ABIs are not compatible
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -923,6 +945,7 @@ error: fn_abi_of(assoc_test) = FnAbi {
valid_range: $NON_NULL,
},
),
uninhabited: false,
variants: Single {
index: 0,
},
@ -960,6 +983,7 @@ error: fn_abi_of(assoc_test) = FnAbi {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},

View file

@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -45,6 +46,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},

View file

@ -31,6 +31,7 @@ error: layout_of(E) = Layout {
valid_range: 0..=0,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -56,6 +57,7 @@ error: layout_of(E) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -69,7 +71,9 @@ error: layout_of(E) = Layout {
abi: Align(4 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: Memory {
sized: true,
},
fields: Arbitrary {
offsets: [
Size(4 bytes),
@ -83,6 +87,7 @@ error: layout_of(E) = Layout {
],
},
largest_niche: None,
uninhabited: true,
variants: Single {
index: 1,
},
@ -136,6 +141,7 @@ error: layout_of(S) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -161,6 +167,7 @@ error: layout_of(U) = Layout {
2,
),
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -213,6 +220,7 @@ error: layout_of(Result<i32, i32>) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -255,6 +263,7 @@ error: layout_of(Result<i32, i32>) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -293,6 +302,7 @@ error: layout_of(Result<i32, i32>) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},
@ -328,6 +338,7 @@ error: layout_of(i32) = Layout {
),
fields: Primitive,
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -353,6 +364,7 @@ error: layout_of(V) = Layout {
2,
),
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -378,6 +390,7 @@ error: layout_of(W) = Layout {
2,
),
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -403,6 +416,7 @@ error: layout_of(Y) = Layout {
2,
),
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -428,6 +442,7 @@ error: layout_of(P1) = Layout {
1,
),
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -453,6 +468,7 @@ error: layout_of(P2) = Layout {
1,
),
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -478,6 +494,7 @@ error: layout_of(P3) = Layout {
1,
),
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -503,6 +520,7 @@ error: layout_of(P4) = Layout {
1,
),
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -533,6 +551,7 @@ error: layout_of(P5) = Layout {
2,
),
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -563,6 +582,7 @@ error: layout_of(MaybeUninit<u8>) = Layout {
2,
),
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},

View file

@ -31,6 +31,7 @@ error: layout_of(A) = Layout {
valid_range: 0..=0,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -56,6 +57,7 @@ error: layout_of(A) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -107,6 +109,7 @@ error: layout_of(B) = Layout {
valid_range: 255..=255,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -132,6 +135,7 @@ error: layout_of(B) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -183,6 +187,7 @@ error: layout_of(C) = Layout {
valid_range: 256..=256,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -208,6 +213,7 @@ error: layout_of(C) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -259,6 +265,7 @@ error: layout_of(P) = Layout {
valid_range: 268435456..=268435456,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -284,6 +291,7 @@ error: layout_of(P) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -335,6 +343,7 @@ error: layout_of(T) = Layout {
valid_range: 2164260864..=2164260864,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -360,6 +369,7 @@ error: layout_of(T) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},

View file

@ -37,6 +37,7 @@ error: layout_of(MissingPayloadField) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -78,6 +79,7 @@ error: layout_of(MissingPayloadField) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -99,6 +101,7 @@ error: layout_of(MissingPayloadField) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},
@ -157,6 +160,7 @@ error: layout_of(CommonPayloadField) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -199,6 +203,7 @@ error: layout_of(CommonPayloadField) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -237,6 +242,7 @@ error: layout_of(CommonPayloadField) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},
@ -294,6 +300,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -335,6 +342,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -372,6 +380,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},
@ -429,6 +438,7 @@ error: layout_of(NicheFirst) = Layout {
valid_range: 0..=4,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -486,6 +496,7 @@ error: layout_of(NicheFirst) = Layout {
valid_range: 0..=2,
},
),
uninhabited: false,
variants: Single {
index: 0,
},
@ -507,6 +518,7 @@ error: layout_of(NicheFirst) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},
@ -528,6 +540,7 @@ error: layout_of(NicheFirst) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 2,
},
@ -585,6 +598,7 @@ error: layout_of(NicheSecond) = Layout {
valid_range: 0..=4,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -642,6 +656,7 @@ error: layout_of(NicheSecond) = Layout {
valid_range: 0..=2,
},
),
uninhabited: false,
variants: Single {
index: 0,
},
@ -663,6 +678,7 @@ error: layout_of(NicheSecond) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},
@ -684,6 +700,7 @@ error: layout_of(NicheSecond) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 2,
},

View file

@ -25,6 +25,7 @@ error: layout_of(Aligned1) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -50,6 +51,7 @@ error: layout_of(Aligned1) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -73,6 +75,7 @@ error: layout_of(Aligned1) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},
@ -128,6 +131,7 @@ error: layout_of(Aligned2) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -153,6 +157,7 @@ error: layout_of(Aligned2) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -176,6 +181,7 @@ error: layout_of(Aligned2) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},

View file

@ -31,6 +31,7 @@ error: layout_of(A) = Layout {
valid_range: 0..=0,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -56,6 +57,7 @@ error: layout_of(A) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -107,6 +109,7 @@ error: layout_of(B) = Layout {
valid_range: 255..=255,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -132,6 +135,7 @@ error: layout_of(B) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -183,6 +187,7 @@ error: layout_of(C) = Layout {
valid_range: 256..=256,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -208,6 +213,7 @@ error: layout_of(C) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -259,6 +265,7 @@ error: layout_of(P) = Layout {
valid_range: 268435456..=268435456,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -284,6 +291,7 @@ error: layout_of(P) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -335,6 +343,7 @@ error: layout_of(T) = Layout {
valid_range: 2164260864..=2164260864,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -360,6 +369,7 @@ error: layout_of(T) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},

View file

@ -25,6 +25,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -54,6 +55,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -88,6 +90,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Single {
index: 1,
},
@ -133,6 +136,7 @@ error: layout_of(MultipleAlignments) = Layout {
valid_range: 0..=2,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -162,6 +166,7 @@ error: layout_of(MultipleAlignments) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -187,6 +192,7 @@ error: layout_of(MultipleAlignments) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},
@ -221,6 +227,7 @@ error: layout_of(MultipleAlignments) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Single {
index: 2,
},
@ -266,6 +273,7 @@ error: layout_of(Result<[u32; 0], Packed<NonZero<u16>>>) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -295,6 +303,7 @@ error: layout_of(Result<[u32; 0], Packed<NonZero<u16>>>) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -329,6 +338,7 @@ error: layout_of(Result<[u32; 0], Packed<NonZero<u16>>>) = Layout {
valid_range: 1..=65535,
},
),
uninhabited: false,
variants: Single {
index: 1,
},
@ -374,6 +384,7 @@ error: layout_of(Result<[u32; 0], Packed<U16IsZero>>) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -407,6 +418,7 @@ error: layout_of(Result<[u32; 0], Packed<U16IsZero>>) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -441,6 +453,7 @@ error: layout_of(Result<[u32; 0], Packed<U16IsZero>>) = Layout {
valid_range: 0..=0,
},
),
uninhabited: false,
variants: Single {
index: 1,
},

View file

@ -4,7 +4,15 @@ error: layout_of(Univariant) = Layout {
abi: Align(4 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: Scalar(
Initialized {
value: Int(
I32,
false,
),
valid_range: 0..=0,
},
),
fields: Arbitrary {
offsets: [
Size(0 bytes),
@ -23,6 +31,7 @@ error: layout_of(Univariant) = Layout {
valid_range: 0..=0,
},
),
uninhabited: true,
variants: Multiple {
tag: Initialized {
value: Int(
@ -40,7 +49,15 @@ error: layout_of(Univariant) = Layout {
abi: Align(4 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: Scalar(
Initialized {
value: Int(
I32,
false,
),
valid_range: 0..=0,
},
),
fields: Arbitrary {
offsets: [
Size(4 bytes),
@ -50,6 +67,7 @@ error: layout_of(Univariant) = Layout {
],
},
largest_niche: None,
uninhabited: true,
variants: Single {
index: 0,
},
@ -107,6 +125,7 @@ error: layout_of(TwoVariants) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -119,12 +138,26 @@ error: layout_of(TwoVariants) = Layout {
tag_field: 0,
variants: [
Layout {
size: Size(4 bytes),
size: Size(8 bytes),
align: AbiAndPrefAlign {
abi: Align(4 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: ScalarPair(
Initialized {
value: Int(
I32,
false,
),
valid_range: 0..=1,
},
Union {
value: Int(
I8,
false,
),
},
),
fields: Arbitrary {
offsets: [
Size(4 bytes),
@ -134,6 +167,7 @@ error: layout_of(TwoVariants) = Layout {
],
},
largest_niche: None,
uninhabited: true,
variants: Single {
index: 0,
},
@ -171,6 +205,7 @@ error: layout_of(TwoVariants) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},
@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
abi: Align(8 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: Memory {
sized: true,
},
fields: Arbitrary {
offsets: [
Size(8 bytes),
@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
],
},
largest_niche: None,
uninhabited: true,
variants: Single {
index: 0,
},
@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},

View file

@ -4,7 +4,15 @@ error: layout_of(Univariant) = Layout {
abi: Align(1 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: Scalar(
Initialized {
value: Int(
I8,
false,
),
valid_range: 0..=0,
},
),
fields: Arbitrary {
offsets: [
Size(0 bytes),
@ -23,6 +31,7 @@ error: layout_of(Univariant) = Layout {
valid_range: 0..=0,
},
),
uninhabited: true,
variants: Multiple {
tag: Initialized {
value: Int(
@ -40,7 +49,15 @@ error: layout_of(Univariant) = Layout {
abi: Align(1 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: Scalar(
Initialized {
value: Int(
I8,
false,
),
valid_range: 0..=0,
},
),
fields: Arbitrary {
offsets: [
Size(1 bytes),
@ -50,6 +67,7 @@ error: layout_of(Univariant) = Layout {
],
},
largest_niche: None,
uninhabited: true,
variants: Single {
index: 0,
},
@ -107,6 +125,7 @@ error: layout_of(TwoVariants) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -119,12 +138,26 @@ error: layout_of(TwoVariants) = Layout {
tag_field: 0,
variants: [
Layout {
size: Size(1 bytes),
size: Size(2 bytes),
align: AbiAndPrefAlign {
abi: Align(1 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: ScalarPair(
Initialized {
value: Int(
I8,
false,
),
valid_range: 0..=1,
},
Union {
value: Int(
I8,
false,
),
},
),
fields: Arbitrary {
offsets: [
Size(1 bytes),
@ -134,6 +167,7 @@ error: layout_of(TwoVariants) = Layout {
],
},
largest_niche: None,
uninhabited: true,
variants: Single {
index: 0,
},
@ -171,6 +205,7 @@ error: layout_of(TwoVariants) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},
@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
abi: Align(8 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: Memory {
sized: true,
},
fields: Arbitrary {
offsets: [
Size(8 bytes),
@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
],
},
largest_niche: None,
uninhabited: true,
variants: Single {
index: 0,
},
@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},

View file

@ -4,7 +4,15 @@ error: layout_of(Univariant) = Layout {
abi: Align(4 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: Scalar(
Initialized {
value: Int(
I32,
false,
),
valid_range: 0..=0,
},
),
fields: Arbitrary {
offsets: [
Size(0 bytes),
@ -23,6 +31,7 @@ error: layout_of(Univariant) = Layout {
valid_range: 0..=0,
},
),
uninhabited: true,
variants: Multiple {
tag: Initialized {
value: Int(
@ -40,7 +49,15 @@ error: layout_of(Univariant) = Layout {
abi: Align(4 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: Scalar(
Initialized {
value: Int(
I32,
false,
),
valid_range: 0..=0,
},
),
fields: Arbitrary {
offsets: [
Size(4 bytes),
@ -50,6 +67,7 @@ error: layout_of(Univariant) = Layout {
],
},
largest_niche: None,
uninhabited: true,
variants: Single {
index: 0,
},
@ -107,6 +125,7 @@ error: layout_of(TwoVariants) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -119,12 +138,26 @@ error: layout_of(TwoVariants) = Layout {
tag_field: 0,
variants: [
Layout {
size: Size(4 bytes),
size: Size(8 bytes),
align: AbiAndPrefAlign {
abi: Align(4 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: ScalarPair(
Initialized {
value: Int(
I32,
false,
),
valid_range: 0..=1,
},
Union {
value: Int(
I8,
false,
),
},
),
fields: Arbitrary {
offsets: [
Size(4 bytes),
@ -134,6 +167,7 @@ error: layout_of(TwoVariants) = Layout {
],
},
largest_niche: None,
uninhabited: true,
variants: Single {
index: 0,
},
@ -171,6 +205,7 @@ error: layout_of(TwoVariants) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},
@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
abi: Align(8 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: Memory {
sized: true,
},
fields: Arbitrary {
offsets: [
Size(8 bytes),
@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
],
},
largest_niche: None,
uninhabited: true,
variants: Single {
index: 0,
},
@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},

View file

@ -4,7 +4,15 @@ error: layout_of(Univariant) = Layout {
abi: Align(4 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: Scalar(
Initialized {
value: Int(
I32,
false,
),
valid_range: 0..=0,
},
),
fields: Arbitrary {
offsets: [
Size(0 bytes),
@ -23,6 +31,7 @@ error: layout_of(Univariant) = Layout {
valid_range: 0..=0,
},
),
uninhabited: true,
variants: Multiple {
tag: Initialized {
value: Int(
@ -40,7 +49,15 @@ error: layout_of(Univariant) = Layout {
abi: Align(4 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: Scalar(
Initialized {
value: Int(
I32,
false,
),
valid_range: 0..=0,
},
),
fields: Arbitrary {
offsets: [
Size(4 bytes),
@ -50,6 +67,7 @@ error: layout_of(Univariant) = Layout {
],
},
largest_niche: None,
uninhabited: true,
variants: Single {
index: 0,
},
@ -107,6 +125,7 @@ error: layout_of(TwoVariants) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -119,12 +138,26 @@ error: layout_of(TwoVariants) = Layout {
tag_field: 0,
variants: [
Layout {
size: Size(4 bytes),
size: Size(8 bytes),
align: AbiAndPrefAlign {
abi: Align(4 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: ScalarPair(
Initialized {
value: Int(
I32,
false,
),
valid_range: 0..=1,
},
Union {
value: Int(
I8,
false,
),
},
),
fields: Arbitrary {
offsets: [
Size(4 bytes),
@ -134,6 +167,7 @@ error: layout_of(TwoVariants) = Layout {
],
},
largest_niche: None,
uninhabited: true,
variants: Single {
index: 0,
},
@ -171,6 +205,7 @@ error: layout_of(TwoVariants) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},
@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
abi: Align(8 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: Memory {
sized: true,
},
fields: Arbitrary {
offsets: [
Size(8 bytes),
@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
],
},
largest_niche: None,
uninhabited: true,
variants: Single {
index: 0,
},
@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},

View file

@ -4,7 +4,15 @@ error: layout_of(UnivariantU8) = Layout {
abi: Align(1 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: Scalar(
Initialized {
value: Int(
I8,
false,
),
valid_range: 0..=0,
},
),
fields: Arbitrary {
offsets: [
Size(0 bytes),
@ -23,6 +31,7 @@ error: layout_of(UnivariantU8) = Layout {
valid_range: 0..=0,
},
),
uninhabited: true,
variants: Multiple {
tag: Initialized {
value: Int(
@ -40,7 +49,15 @@ error: layout_of(UnivariantU8) = Layout {
abi: Align(1 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: Scalar(
Initialized {
value: Int(
I8,
false,
),
valid_range: 0..=0,
},
),
fields: Arbitrary {
offsets: [
Size(1 bytes),
@ -50,6 +67,7 @@ error: layout_of(UnivariantU8) = Layout {
],
},
largest_niche: None,
uninhabited: true,
variants: Single {
index: 0,
},
@ -107,6 +125,7 @@ error: layout_of(TwoVariantsU8) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -119,12 +138,26 @@ error: layout_of(TwoVariantsU8) = Layout {
tag_field: 0,
variants: [
Layout {
size: Size(1 bytes),
size: Size(2 bytes),
align: AbiAndPrefAlign {
abi: Align(1 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: ScalarPair(
Initialized {
value: Int(
I8,
false,
),
valid_range: 0..=1,
},
Union {
value: Int(
I8,
false,
),
},
),
fields: Arbitrary {
offsets: [
Size(1 bytes),
@ -134,6 +167,7 @@ error: layout_of(TwoVariantsU8) = Layout {
],
},
largest_niche: None,
uninhabited: true,
variants: Single {
index: 0,
},
@ -171,6 +205,7 @@ error: layout_of(TwoVariantsU8) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},
@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
valid_range: 0..=1,
},
),
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
abi: Align(8 bytes),
pref: $SOME_ALIGN,
},
abi: Uninhabited,
abi: Memory {
sized: true,
},
fields: Arbitrary {
offsets: [
Size(8 bytes),
@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
],
},
largest_niche: None,
uninhabited: true,
variants: Single {
index: 0,
},
@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 1,
},

View file

@ -31,6 +31,7 @@ error: layout_of(NonZero<u32>) = Layout {
valid_range: 1..=4294967295,
},
),
uninhabited: false,
variants: Single {
index: 0,
},
@ -69,6 +70,7 @@ error: layout_of((u32) is 1..=) = Layout {
valid_range: 1..=4294967295,
},
),
uninhabited: false,
variants: Single {
index: 0,
},
@ -105,6 +107,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -134,6 +137,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -174,6 +178,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout {
valid_range: 1..=4294967295,
},
),
uninhabited: false,
variants: Single {
index: 1,
},
@ -216,6 +221,7 @@ error: layout_of(Option<NonZero<u32>>) = Layout {
],
},
largest_niche: None,
uninhabited: false,
variants: Multiple {
tag: Initialized {
value: Int(
@ -245,6 +251,7 @@ error: layout_of(Option<NonZero<u32>>) = Layout {
memory_index: [],
},
largest_niche: None,
uninhabited: false,
variants: Single {
index: 0,
},
@ -285,6 +292,7 @@ error: layout_of(Option<NonZero<u32>>) = Layout {
valid_range: 1..=4294967295,
},
),
uninhabited: false,
variants: Single {
index: 1,
},
@ -336,6 +344,7 @@ error: layout_of(NonZeroU32New) = Layout {
valid_range: 1..=4294967295,
},
),
uninhabited: false,
variants: Single {
index: 0,
},

View file

@ -0,0 +1,33 @@
//@ run-pass
//@ needs-unwind
// See https://github.com/rust-lang/rust/issues/135802
enum Void {}
// Should be ABI-compatible with T, but wasn't prior to the PR adding this test.
#[repr(transparent)]
struct NoReturn<T>(T, Void);
// Returned by invisible reference (in most ABIs)
#[allow(dead_code)]
struct Large(u64, u64, u64);
// Prior to the PR adding this test, this function had a different ABI than
// `fn() -> Large` (on `x86_64-unknown-linux-gnu` at least), so calling it as `fn() -> Large`
// would pass the return place pointer in rdi and `correct` in rsi, but the function
// would expect `correct` in rdi.
fn never(correct: &mut bool) -> NoReturn<Large> {
*correct = true;
panic!("catch this")
}
fn main() {
let mut correct = false;
let never: fn(&mut bool) -> NoReturn<Large> = never;
// Safety: `NoReturn<Large>` is a `repr(transparent)` wrapper around `Large`,
// so they should be ABI-compatible.
let never: fn(&mut bool) -> Large = unsafe { std::mem::transmute(never) };
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| never(&mut correct)));
assert!(result.is_err(), "function should have panicked");
assert!(correct, "function should have stored `true` into `correct`");
}