{"id":"68cdb750c0da177e","repo":"rust-lang/rust","slug":"size-add-doesn-t-fit-in-u64","errorCode":null,"errorMessage":"Size::add: {} + {} doesn't fit in u64","messagePattern":"Size::add: (.+?) \\+ (.+?) doesn't fit in u64","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_abi/src/lib.rs","lineNumber":990,"sourceCode":"    pub fn signed_int_max(&self) -> i128 {\n        i128::MAX >> (128 - self.bits())\n    }\n\n    #[inline]\n    pub fn unsigned_int_max(&self) -> u128 {\n        u128::MAX >> (128 - self.bits())\n    }\n}\n\n// Panicking addition, subtraction and multiplication for convenience.\n// Avoid during layout computation, return `LayoutError` instead.\n\nimpl Add for Size {\n    type Output = Size;\n    #[inline]\n    fn add(self, other: Size) -> Size {\n        Size::from_bytes(self.bytes().checked_add(other.bytes()).unwrap_or_else(|| {\n            panic!(\"Size::add: {} + {} doesn't fit in u64\", self.bytes(), other.bytes())\n        }))\n    }\n}\n\nimpl Sub for Size {\n    type Output = Size;\n    #[inline]\n    fn sub(self, other: Size) -> Size {\n        Size::from_bytes(self.bytes().checked_sub(other.bytes()).unwrap_or_else(|| {\n            panic!(\"Size::sub: {} - {} would result in negative size\", self.bytes(), other.bytes())\n        }))\n    }\n}\n\nimpl Mul<Size> for u64 {\n    type Output = Size;\n    #[inline]\n    fn mul(self, size: Size) -> Size {","sourceCodeStart":972,"sourceCodeEnd":1008,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_abi/src/lib.rs#L972-L1008","documentation":"Thrown by the `Add` impl for `Size` (compiler/rustc_abi/src/lib.rs:990) when `self.bytes() + other.bytes()` overflows u64. The module comment at lib.rs:982-983 explicitly warns: these panicking operators are convenience helpers and must NOT be used during layout computation, where `LayoutError` should be returned instead.","triggerScenarios":"Using `size_a + size_b` (the `+` operator) on two `Size` values whose combined byte count exceeds u64::MAX. Common callers are codegen offset arithmetic, niche computation, and any code path that ignores `checked_add`.","commonSituations":"Hits when porting layout code that previously assumed bounded sizes, or when a backend/helper uses the bare `+` operator on sizes derived from very large array counts or unsized types. Also a regression marker if `obj_size_bound` enforcement was bypassed.","solutions":["Replace the `+` operator with `size.checked_add(other, cx)`, which clamps against `data_layout().obj_size_bound()` and returns `Option<Size>`; propagate the `None` as a `LayoutError`.","If the addition is genuinely provably bounded (e.g. two small fixed sizes), keep the operator but add a debug_assert or comment documenting the invariant.","Audit git history for the panic site to find which layout pass introduced the un-checked arithmetic."],"exampleFix":"// before\nlet total = offset + field_size;\n\n// after\nlet total = offset.checked_add(field_size, cx)\n    .ok_or(LayoutError::SizeOverflow)?;","handlingStrategy":"validation","validationCode":"// Size::add panics on overflow. Use checked_add (inherent) or check bytes first.\nfn safe_add(a: rustc_abi::Size, b: rustc_abi::Size) -> Option<rustc_abi::Size> {\n    a.bytes().checked_add(b.bytes()).map(rustc_abi::Size::from_bytes)\n}\n// Or, with a layout context, the library helper also bounds against obj_size_bound():\n// a.checked_add(b, &cx)","typeGuard":"// No narrower type; guard the arithmetic result instead.\nfn fits_add(a: rustc_abi::Size, b: rustc_abi::Size) -> bool {\n    a.bytes().checked_add(b.bytes()).is_some()\n}","tryCatchPattern":"// Panics here are logic bugs, not recoverable runtime conditions. Do not catch;\n// route through checked_add and propagate Option/Result upstream.","preventionTips":["Avoid the `+` operator on Size entirely during layout computation; the source comment explicitly says: 'Avoid during layout computation, return LayoutError instead.'","Use checked_add(offset, &cx) which additionally enforces the target obj_size_bound().","Keep offset accumulators in u64 and validate once before constructing the final Size."],"tags":["rustc-abi","size","overflow","panic","layout"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}