Numeric loop without upper bound panics early

Is this a bug or expected behavior? And if it's expected, where is it documented?

fn main() {
    // This works:
    for i in 250u8..=255u8 {
        println!("{i}");
        if i == 255 {
            break;
        }
    }
    println!();
    // But this panics:
    for i in 250u8.. {
        println!("{i}");
        if i == 255 {
            break;
        }
    }
}

(Playground)

Output:

250
251
252
253
254
255

250
251
252
253
254

Errors:

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 0.63s
     Running `target/debug/playground`
thread 'main' panicked at 'attempt to add with overflow', /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/core/src/iter/range.rs:391:1
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

It's documented in RangeFrom:

Note: Overflow in the Iterator implementation (when the contained data type reaches its numerical limit) is allowed to panic, wrap, or saturate. This behavior is defined by the implementation of the Step trait. For primitive integers, this follows the normal rules, and respects the overflow checks profile (panic in debug, wrap in release). Note also that overflow happens earlier than you might assume: the overflow happens in the call to next that yields the maximum value, as the range must be set to a state to yield the next value.

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.