{"id":"687fcf2551aa7386","repo":"rust-lang/rust","slug":"size-sub-would-result-in-negative-size","errorCode":null,"errorMessage":"Size::sub: {} - {} would result in negative size","messagePattern":"Size::sub: (.+?) - (.+?) would result in negative size","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_abi/src/lib.rs","lineNumber":1000,"sourceCode":"// 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 {\n        size * self\n    }\n}\n\nimpl Mul<u64> for Size {\n    type Output = Size;\n    #[inline]\n    fn mul(self, count: u64) -> Size {\n        match self.bytes().checked_mul(count) {\n            Some(bytes) => Size::from_bytes(bytes),","sourceCodeStart":982,"sourceCodeEnd":1018,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_abi/src/lib.rs#L982-L1018","documentation":"Thrown by the `Sub` impl for `Size` (compiler/rustc_abi/src/lib.rs:1000) when the right operand is larger than the left, i.e. `self.bytes() - other.bytes()` would underflow. `Size` is an unsigned byte count with no notion of negative values, so subtraction that goes below zero is a programmer error.","triggerScenarios":"Computing `a - b` via the `-` operator where `b.bytes() > a.bytes()`. Typical in offset arithmetic — e.g. subtracting a field offset from a base offset that was assumed larger but is actually smaller, or subtracting a stride from `Size::ZERO`.","commonSituations":"Wrong ordering assumption in struct/enum layout (e.g. computing padding as `field_end - next_offset` when fields are reordered), or a downstream tool computing relative offsets from an uninitialized/zero base. Surfaces in codegen and in consumers like miri and rust-analyzer that replay layouts.","solutions":["Establish the precondition with `debug_assert!(a.bytes() >= b.bytes())` and fix the caller if it ever fires, since a negative size is always a logic error.","If underflow is legitimately possible, switch to `a.bytes().checked_sub(b.bytes()).map(Size::from_bytes)` and handle the `None` case explicitly.","Verify the operands are not swapped (the most common cause is `small - large` instead of `large - small`)."],"exampleFix":"// before\nlet padding = next_offset - prev_end;\n\n// after\nlet padding = next_offset\n    .bytes()\n    .checked_sub(prev_end.bytes())\n    .map(Size::from_bytes)\n    .expect(\"fields ordered: next_offset >= prev_end\");","handlingStrategy":"validation","validationCode":"// Size::sub panics when result would be negative (a < b).\nfn safe_sub(a: rustc_abi::Size, b: rustc_abi::Size) -> Option<rustc_abi::Size> {\n    a.bytes().checked_sub(b.bytes()).map(rustc_abi::Size::from_bytes)\n}","typeGuard":"// Ordering guard, not a type guard.\nfn is_subtractable(a: rustc_abi::Size, b: rustc_abi::Size) -> bool {\n    a.bytes() >= b.bytes()\n}","tryCatchPattern":"// Do not catch; subtraction underflow indicates wrong offset ordering upstream.\n// Return a Result/Option from the calling code via checked_sub.","preventionTips":["Never subtract a larger Size from a smaller one; assert/document the ordering invariant at the call site.","Compute offsets via align_to_round_up style helpers that guarantee monotonic increase.","When iterating field offsets, sort ascending before differencing."],"tags":["rustc-abi","size","underflow","panic","layout"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}