rust-lang/rust · critical
unsupported integer: {self:?}
Error message
unsupported integer: {self:?} What it means
This panic fires inside `Reg::align` when a register of `RegKind::Integer` has a bit width outside the 1..=128 range the data layout knows alignments for. The compiler's calling-convention layer only models integer registers up to 128 bits, so any other size is an internal invariant violation rather than a normal user error. It almost always indicates a malformed target data layout or a codegen bug producing a bogus register width.
Source
Thrown at compiler/rustc_abi/src/callconv/reg.rs:63
/// A vector of the given size with an unknown (and irrelevant) element type.
pub fn opaque_vector(size: Size) -> Reg {
// Default to an i8 vector of the given size.
Reg { kind: RegKind::Vector { hint_vector_elem: Primitive::Int(Integer::I8, true) }, size }
}
}
impl Reg {
pub fn align<C: HasDataLayout>(&self, cx: &C) -> Align {
let dl = cx.data_layout();
match self.kind {
RegKind::Integer => match self.size.bits() {
1 => dl.i1_align,
2..=8 => dl.i8_align,
9..=16 => dl.i16_align,
17..=32 => dl.i32_align,
33..=64 => dl.i64_align,
65..=128 => dl.i128_align,
_ => panic!("unsupported integer: {self:?}"),
},
RegKind::Float => match self.size.bits() {
16 => dl.f16_align,
32 => dl.f32_align,
64 => dl.f64_align,
128 => dl.f128_align,
_ => panic!("unsupported float: {self:?}"),
},
RegKind::Vector { .. } => dl.rust_vector_align(self.size),
}
}
}
View on GitHub (pinned to 22057b88b0)
Solutions
- Verify the target's `data_layout` in `rustc_abi`/target spec is one of the supported LLVM-style layouts and that integer alignment entries cover 1..128 bits.
- Find where the oversized/zero-sized integer `Reg` was constructed (search for `Reg { kind: RegKind::Integer` and `Reg::i*` callers) and fix the size at the source.
- If you genuinely need a >128-bit integer register, extend `align`'s match arms and the data layout alignment fields first; do not paper over the panic.
- File an ICE report against rustc with the `-Ztreat-err-as-bug` backtrace if this fires on upstream `rustc` with no custom target.
Example fix
// before
let r = Reg { kind: RegKind::Integer, size: Size::from_bits(256) };
let a = r.align(&dl); // panic: unsupported integer
// after — clamp to the largest supported integer register, or extend the layer
let r = Reg::i128();
let a = r.align(&dl); Defensive patterns
Strategy: validation
Validate before calling
// Reg::align panics on integer sizes outside {1, 2..=8, 9..=16, 17..=32, 33..=64, 65..=128} bits.
// Validate before calling `reg.align(cx)`.
use rustc_abi::{Reg, RegKind};
fn supported_integer_align(reg: &Reg) -> bool {
if !matches!(reg.kind, RegKind::Integer) { return true; }
let b = reg.size.bits();
b == 1
|| (2..=8).contains(&b)
|| (9..=16).contains(&b)
|| (17..=32).contains(&b)
|| (33..=64).contains(&b)
|| (65..=128).contains(&b)
}
// caller: if supported_integer_align(®) { reg.align(cx) } else { /* skip / report */ } Type guard
// Narrow a Reg to a known-supported integer register.
fn is_supported_int_reg(reg: &Reg) -> bool {
matches!(reg.kind, RegKind::Integer) && supported_integer_align(reg)
} Try / catch
// Panics are not Result-returning; use catch_unwind as a last resort when validating
// an externally-supplied Reg whose size you do not control.
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| reg.align(cx)));
match result {
Ok(align) => { /* use align */ }
Err(payload) => { eprintln!("unsupported integer reg: {:?}", ®); /* recover */ }
} Prevention
- Construct Reg values only through the provided constructors (Reg::i8..Reg::i128) rather than building Reg structs with arbitrary Size values.
- Treat any Reg whose size is not a power of two in [1,128] bits as untrusted input; reject it before touching layout/calling-convention code.
- If you accept Reg/Size from serialized or foreign sources, run a whitelist size check at the trust boundary, not deep inside layout computation.
When it happens
Trigger: Calling `Reg { kind: RegKind::Integer, size }.align(cx)` where `size.bits()` is 0 or >128; i.e. constructing an integer `Reg` whose size is not one of the i8..i128 widths the `reg_ctor!` helpers define, then querying its ABI alignment via a `HasDataLayout` target.
Common situations: A target spec with a broken `data_layout` string, a custom codegen backend that hands an off-size integer register to the ABI layer, or an internal compiler change that introduces 256-bit (or wider) integer primitives before the data layout / callconv layer was updated to know their alignment.
Related errors
- unsupported float: {self:?}
- `homogeneous_aggregate` should not be called for scalable ve
- aggregates can't have `FieldsShape::Primitive`
- unreachable: invalid ExternAbi variant
- ptr_sized_integer: unknown pointer bit size {bits}
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/7df9e2e4c48ec921.json.
Report an issue: GitHub.