rust-lang/rust · critical
encountered a non-arbitrary layout during enum layout
Error message
encountered a non-arbitrary layout during enum layout
What it means
Fires in layout_of_enum during the niche/scalar-pair ABI optimization. The code calls LayoutData::scalar_pair and then destructures the resulting fields expecting FieldsShape::Arbitrary with in_memory_order [0,1]; the wildcard arm treats any other shape (Primitive/Array/Union) as unreachable. Hitting it means scalar_pair's documented output invariant was broken, an internal layout corruption.
Source
Thrown at compiler/rustc_abi/src/layout.rs:1007
}
}
if let Some((prim, offset)) = common_prim {
let prim_scalar = if common_prim_initialized_in_all_variants {
let size = prim.size(dl);
assert!(size.bits() <= 128);
Scalar::Initialized { value: prim, valid_range: WrappingRange::full(size) }
} else {
// Common prim might be uninit.
Scalar::Union { value: prim }
};
let pair =
LayoutData::<FieldIdx, VariantIdx>::scalar_pair(&self.cx, tag, prim_scalar);
let pair_offsets = match pair.fields {
FieldsShape::Arbitrary { ref offsets, ref in_memory_order } => {
assert_eq!(in_memory_order.raw, [FieldIdx::new(0), FieldIdx::new(1)]);
offsets
}
_ => panic!("encountered a non-arbitrary layout during enum layout"),
};
if pair_offsets[FieldIdx::new(0)] == Size::ZERO
&& pair_offsets[FieldIdx::new(1)] == *offset
&& align == pair.align.abi
&& size == pair.size
{
// We can use `ScalarPair` only when it matches our
// already computed layout (including `#[repr(C)]`).
abi = pair.backend_repr;
}
}
}
// If we pick a "clever" (by-value) ABI, we might have to adjust the ABI of the
// variants to ensure they are consistent. This is because a downcast is
// semantically a NOP, and thus should not affect layout.
if matches!(abi, BackendRepr::Scalar(..) | BackendRepr::ScalarPair { .. }) {
for variant in &mut layout_variants {View on GitHub (pinned to 22057b88b0)
Solutions
- Report as an ICE to the Rust repo with a reduced enum that triggers the niche optimization.
- As a compiler dev, audit LayoutData::scalar_pair to confirm it still emits FieldsShape::Arbitrary with in_memory_order [0,1].
- Bisect to locate the commit that altered scalar-pair field construction.
Defensive patterns
Strategy: try-catch
Try / catch
// 'non-arbitrary layout during enum layout' is an unreachable post-condition
// of LayoutData::scalar_pair; no input predicate can predict it. Catch it at the
// boundary where you compute enum ABI layouts.
let abi = match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
layout_for_enum(cx, ty)
})) {
Ok(Ok(layout)) => layout,
Ok(Err(recoverable)) => return Err(recoverable.into()),
Err(payload) => {
log::error!("rustc bug: scalar_pair did not yield Arbitrary FieldsShape: {payload:?}");
// fall back to the memory (non-ScalarPair) ABI you already computed
fallback_memory_abi(ty)
}
}; Prevention
- This fires only when LayoutData::scalar_pair produces a FieldsShape other than Arbitrary — an internal invariant violation, not something a caller's enum definition can be validated against.
- Wrap the enum-layout computation in catch_unwind and degrade gracefully to the already-computed BackendRepr::Memory layout when it triggers.
- Do not construct LayoutData fields by hand to feed the layout calculator; obtain them through the normal layout pipeline so scalar_pair's Arbitrary post-condition is preserved.
- If reproducible, report to rustc with the enum whose (tag, primitive-payload) niche-pair triggered the ScalarPair attempt.
When it happens
Trigger: Reached only if LayoutData::scalar_pair is modified to return a non-Arbitrary FieldsShape, or memory/logic corruption makes pair.fields not match the expected Arbitrary { offsets, in_memory_order: [0, 1] } during enum niche optimization.
Common situations: Pure internal compiler bug surfacing as an ICE during enum layout. Typically appears after edits to the rustc_abi scalar-pair constructors or a bad merge in the layout/codegen pipeline; ordinary user programs do not trigger it.
Related errors
- layout decided on a larger discriminant type ({min_ity:?}) t
- aggregates can't have `FieldsShape::Primitive`
- Expected multi-variant layout in `Layout::for_variant`
- a multi-variant layout should have `Arbitrary` fields
- obj_size_bound: unknown pointer bit size {bits}
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/ec2a3193ff4d9fd5.json.
Report an issue: GitHub.