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

  1. 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.
  2. 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.
  3. 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.
  4. 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) { 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: {:?}", &reg); /* recover */ }
}

Prevention

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


AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03). Data as JSON: /data/errors/7df9e2e4c48ec921.json. Report an issue: GitHub.