Skip to content

Fix no-panic link failure for non-constant u32/u64/u128 - #72

Open
patrick-immometrica wants to merge 1 commit into
dtolnay:masterfrom
patrick-immometrica:no-panic-runtime-values
Open

patrick-immometrica wants to merge 1 commit into
dtolnay:masterfrom
patrick-immometrica:no-panic-runtime-values

Conversation

@patrick-immometrica

Copy link
Copy Markdown

With the no-panic feature enabled, formatting a value that isn't a compile-time constant fails to link for u32, u64, u128, i32, i128 and usize:

// Cargo.toml: itoa = { version = "1", features = ["no-panic"] }
fn main() {
    let n: u64 = std::env::args().count() as u64;
    println!("{}", itoa::Buffer::new().format(n));
}
ERROR[no-panic]: detected panic in function `fmt`

It's the bounds checks on buf[offset] in the digit loops. LLVM can't prove offset stays in range, so panic_bounds_check stays in the binary. u8/u16/i8/i16/i64/isize happen to link fine.

CI didn't catch this because the tests only format literals, so in the release build every call folds away and there's nothing left to check. The test macro now passes the value through black_box. Without the fix, cargo build --tests --features no-panic --release fails; with it, it passes.

The fix uses get_unchecked_mut for those writes, as the table lookups next to them already do. I checked a downstream crate on aarch64 and x86_64 macOS: all 12 types link with no-panic now. There's no measurable difference in speed.

The tests only formatted constants, so the no-panic build in CI folded
every call away and never linked a real Unsigned::fmt. With a runtime
value, u32/u64/u128 (and i32/i128/usize) fail to link with no-panic
enabled because of the bounds checks on buf.
@patrick-immometrica
patrick-immometrica marked this pull request as ready for review November 5, 2026 10:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant