Closed
Description
I tried this code: [playground]
#![feature(iter_advance_by)]
fn main() {
_ = (-128i8..127).advance_by(200);
}
I expected to see this happen: No UB.
Instead, this happened: UB, confirmed by Miri. Step::forward_unchecked(-128i8, 200usize)
is called, which does (-128i8).unchecked_add(200usize as i8)
, or (-128i8).unchecked_add(-56i8)
.
The implementation of advance_by
is correct here, and Step::forward_unchecked(-128i8, 200usize)
should be safe to call. The implementation that does a wrapping as
cast from usize
to iN
before doing the unchecked math is the incorrect code here. Signed integers should switch to just using wrapping or unsigned math, whichever gets better codegen out of LLVM. We do have wrapping_add_unsigned
and checked_add_unsigned
methods now, but no unchecked_add_unsigned
.
Meta
rustc --version
:
rustc 1.78.0-nightly (2024-03-12 a165f1f65015b1bd4afd)