Latest Results
fix: overflowing_shl/overflowing_shr overflow-flag false negatives (#603)
* fix: overflowing_shl/overflowing_shr overflow-flag false negatives
The overflow flag returned by overflowing_shl and overflowing_shr only
accounted for bits shifted out of the tracked carry window, missing two
classes of discarded bits:
- overflowing_shl ignored source limbs that are wholly shifted out when
the shift amount is >= 64, and bits shifted above BITS but still inside
the top limb (any non-limb-aligned width, e.g. U65, U160).
- overflowing_shr ignored low limbs that are wholly discarded when the
shift amount is >= 64.
This propagated false negatives to checked_shl/checked_shr, strict_shl/
strict_shr, saturating_shl/saturating_shr, and caused to_base_be to loop
forever on no-alloc builds for non-limb-aligned widths (checked_shl
incorrectly returning Some(0) instead of None).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* fix: remove comment
* fix: shift-amount truncation in wrapping/overflowing shifts
The `wrapping_shl`/`wrapping_shr` primitive fast paths (LIMBS in {1, 2, 4})
cast the shift amount `rhs as u32`, reducing it mod 2^32, so shifts >= 2^32
wrapped instead of producing zero. Guard with an early `rhs > BITS` return.
`overflowing_shl_big`/`overflowing_shr_big` narrowed the shift amount to
`u64` and then cast `rhs as usize`, truncating u64 -> u32 on 32-bit targets
(e.g. wasm32) and wrapping shift amounts in [2^32, 2^64) mod 2^32. Guard with
`rhs >= BITS`, which shifts the whole value out and also keeps the surviving
`rhs < BITS <= usize::MAX` so the cast can no longer truncate on any target.
Add the `correctness_8_7_2026_overflowing_big` regression test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix: byte() panic contract on big-endian targets
The little-endian path indexes as_le_slice() (length BYTES) and panics
correctly for index >= BYTES. The big-endian path indexed
self.limbs[index / 8], which only panics for index >= LIMBS * 8, so for
BYTES <= index < LIMBS * 8 (sizes with BITS % 64 != 0) it silently
returned 0 instead of panicking as documented.
Add an explicit bounds check to the big-endian path so byte() upholds
its documented "Panics if index >= BYTES" contract on all targets.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* docs: add CHANGELOG entry (#603)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* perf: hoist shift-amount clamp into fast paths
The `if rhs > Self::BITS` guard in `wrapping_shl`/`wrapping_shr` was only
needed to stop the `rhs as u32` casts in the primitive fast paths
(`LIMBS in {1, 2, 4}`) from truncating shift amounts >= 2^32. Placed in the
prologue it also sat on the generic path, where `overflowing_shl` already
handles any `rhs` correctly -- an always-not-taken branch that blocked the
fall-through from being optimized (wrapping_shl/192 regressed ~2x).
Replace it with a branchless saturating usize->u32 cast (`shift_amount`,
built on `select_unpredictable_u32`) applied only inside the fast-path arms.
The generic path sheds the branch entirely, restoring wrapping_{shl,shr}/192
to main, with no measurable cost on the fast paths.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* lint: fmt
* review: collapse _big shift guards into usize::try_from, fix zero overflow flag
Per review: a shift amount that fails usize::try_from is necessarily
> usize::MAX >= BITS, so the separate u64 narrowing and rhs >= BITS
guard were redundant with overflowing_shl/shr's own handling. Also
return !self.const_is_zero() instead of true on that path — shifting
zero sheds no non-zero bits, so it must not report overflow.
Renames the correctness_8_7_2026_* tests to regression_*.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* chore: address review — comment shr shift loop, gate wasm-incompatible test
- copy the shift-loop comment from overflowing_shl into overflowing_shr
- gate regression_wrapping_shifts to 64-bit pointer width: `1usize << 32`
does not compile on wasm32, and the truncation it guards against cannot
occur when usize is 32 bits
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test: cover truncation-lands-in-range shift amounts at 256 bits
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Latest Branches
+11%
dependabot/github_actions/ci-weekly-f45aba672f N/A
dependabot/github_actions/ci-weekly-dd8776303d 0%
© 2026 CodSpeed Technology