{"id":"7df9e2e4c48ec921","repo":"rust-lang/rust","slug":"unsupported-integer-self","errorCode":null,"errorMessage":"unsupported integer: {self:?}","messagePattern":"unsupported integer: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_abi/src/callconv/reg.rs","lineNumber":63,"sourceCode":"    /// A vector of the given size with an unknown (and irrelevant) element type.\n    pub fn opaque_vector(size: Size) -> Reg {\n        // Default to an i8 vector of the given size.\n        Reg { kind: RegKind::Vector { hint_vector_elem: Primitive::Int(Integer::I8, true) }, size }\n    }\n}\n\nimpl Reg {\n    pub fn align<C: HasDataLayout>(&self, cx: &C) -> Align {\n        let dl = cx.data_layout();\n        match self.kind {\n            RegKind::Integer => match self.size.bits() {\n                1 => dl.i1_align,\n                2..=8 => dl.i8_align,\n                9..=16 => dl.i16_align,\n                17..=32 => dl.i32_align,\n                33..=64 => dl.i64_align,\n                65..=128 => dl.i128_align,\n                _ => panic!(\"unsupported integer: {self:?}\"),\n            },\n            RegKind::Float => match self.size.bits() {\n                16 => dl.f16_align,\n                32 => dl.f32_align,\n                64 => dl.f64_align,\n                128 => dl.f128_align,\n                _ => panic!(\"unsupported float: {self:?}\"),\n            },\n            RegKind::Vector { .. } => dl.rust_vector_align(self.size),\n        }\n    }\n}\n","sourceCodeStart":45,"sourceCodeEnd":76,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_abi/src/callconv/reg.rs#L45-L76","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nlet r = Reg { kind: RegKind::Integer, size: Size::from_bits(256) };\nlet a = r.align(&dl); // panic: unsupported integer\n\n// after — clamp to the largest supported integer register, or extend the layer\nlet r = Reg::i128();\nlet a = r.align(&dl);","handlingStrategy":"validation","validationCode":"// Reg::align panics on integer sizes outside {1, 2..=8, 9..=16, 17..=32, 33..=64, 65..=128} bits.\n// Validate before calling `reg.align(cx)`.\nuse rustc_abi::{Reg, RegKind};\nfn supported_integer_align(reg: &Reg) -> bool {\n    if !matches!(reg.kind, RegKind::Integer) { return true; }\n    let b = reg.size.bits();\n    b == 1\n        || (2..=8).contains(&b)\n        || (9..=16).contains(&b)\n        || (17..=32).contains(&b)\n        || (33..=64).contains(&b)\n        || (65..=128).contains(&b)\n}\n// caller: if supported_integer_align(&reg) { reg.align(cx) } else { /* skip / report */ }","typeGuard":"// Narrow a Reg to a known-supported integer register.\nfn is_supported_int_reg(reg: &Reg) -> bool {\n    matches!(reg.kind, RegKind::Integer) && supported_integer_align(reg)\n}","tryCatchPattern":"// Panics are not Result-returning; use catch_unwind as a last resort when validating\n// an externally-supplied Reg whose size you do not control.\nlet result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| reg.align(cx)));\nmatch result {\n    Ok(align) => { /* use align */ }\n    Err(payload) => { eprintln!(\"unsupported integer reg: {:?}\", &reg); /* recover */ }\n}","preventionTips":["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."],"tags":["rustc","abi","codegen","integer","ice"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}