rust-lang/rust · critical

Size::bits: {bytes} bytes in bits doesn't fit in u64

Error message

Size::bits: {bytes} bytes in bits doesn't fit in u64

What it means

Thrown by `Size::bits()` (compiler/rustc_abi/src/lib.rs:897) when multiplying the stored byte count by 8 overflows u64. `Size` holds a raw byte count as `u64`; converting to bits via `bytes * 8` is only valid for sizes below ~2^61 bytes. This panic signals an absurd/corrupted `Size` value rather than a normal runtime condition, since no real object approaches that magnitude.

Source

Thrown at compiler/rustc_abi/src/lib.rs:897

        let bytes: u64 = bytes.try_into().ok().unwrap();
        Size { raw: bytes }
    }

    #[inline]
    pub fn bytes(self) -> u64 {
        self.raw
    }

    #[inline]
    pub fn bytes_usize(self) -> usize {
        self.bytes().try_into().unwrap()
    }

    #[inline]
    pub fn bits(self) -> u64 {
        #[cold]
        fn overflow(bytes: u64) -> ! {
            panic!("Size::bits: {bytes} bytes in bits doesn't fit in u64")
        }

        self.bytes().checked_mul(8).unwrap_or_else(|| overflow(self.bytes()))
    }

    #[inline]
    pub fn bits_usize(self) -> usize {
        self.bits().try_into().unwrap()
    }

    #[inline]
    pub fn align_to(self, align: Align) -> Size {
        let mask = align.bytes() - 1;
        Size::from_bytes((self.bytes() + mask) & !mask)
    }

    #[inline]
    pub fn is_aligned(self, align: Align) -> bool {

View on GitHub (pinned to 22057b88b0)

Solutions

  1. Trace where the oversized `Size` originated — it is almost certainly produced by an earlier unchecked arithmetic op; switch that producer to the checked variants (`checked_add`/`checked_mul` with a `HasDataLayout`) which return `Option<Size>` and propagate `LayoutError` instead of panicking.
  2. Guard at construction: validate the input to `Size::from_bytes` / `from_bits` against `cx.data_layout().obj_size_bound()` before creating the `Size`.
  3. If you control the caller of `bits()`, prefer operating in bytes (the stored representation) and only convert to bits once you have established the size is bounded.

Example fix

// before
let bit_size = layout.size.bits();

// after - use the checked path during layout
let Some(size) = layout.checked_add(other, cx) else {
    return Err(LayoutError::SizeOverflow);
};
let bit_size = size.bits();
Defensive patterns

Strategy: validation

Validate before calling

// Size::bits() panics when bytes * 8 overflows u64, i.e. bytes > u64::MAX/8.
// Validate before calling .bits():
fn safe_bits(size: rustc_abi::Size) -> Option<u64> {
    const BITS_CAP: u64 = u64::MAX / 8;
    (size.bytes() <= BITS_CAP).then(|| size.bits())
}

Type guard

// Size is a single struct; no narrower type exists. Guard the value, not the type.
// Equivalent: prefer checked helpers when a HasDataLayout context is available
// (checked_add/checked_mul bound against cx.data_layout().obj_size_bound()).
fn size_is_bit_representable(size: rustc_abi::Size) -> bool {
    size.bytes().checked_mul(8).is_some()
}

Try / catch

// Rust panics are not catchable without catch_unwind; prefer pre-validation.
// Last-resort pattern:
use std::panic::Assertion;
let bits = Assertion::catch_unwind(Assertion::always_enabled(), || size.bits())
    .ok_or_else(|| LayoutError::SizeOverflow)?;

Prevention

When it happens

Trigger: Calling `size.bits()` on a `Size` constructed from an astronomically large byte value (e.g. `Size::from_bytes(u64::MAX)` or a value derived from overflowing unsized-type metadata arithmetic). It is reached through `sign_extend`, `truncate`, `signed_int_min/max`, and `unsigned_int_max`, all of which call `bits()` internally.

Common situations: Corrupted or uninitialized `Size` from a malformed layout computation, a bug in custom codegen backends that hand-build `Size` values, or arithmetic on `usize`-typed unsized sizes that has already overflowed upstream. Almost never seen in front-end compiles; surfaces in fuzzing or when a backend constructs sizes from untrusted metadata.

Related errors


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