Skip to content

Decrementing range behaviour is very confusing when used with unsigned integers #14020

Closed
@pimterry

Description

@pimterry

Range behaviour differs significantly and unexpectedly from expected behaviour if the range start is an unsigned integer.

use std::iter;

fn main() {
  let range_start: int = 10;
  for x in iter::range_step(range_start, -1, -1) {
    println!("{}", x);
  }
}

This prints 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0.

use std::iter;

fn main() {
  let range_start: uint = 10;
  for x in iter::range_step(range_start, -1, -1) {
    println!("{}", x);
  }
}

(range_start is a uint, not an int)

This prints '10', and stops. This is not expected.

This appears to be because the type signature for range_step uses the same generic parameter for all three argument. Thus, if the start is a uint then the others are all interpreted as uints, the negative numbers are interpreted as very large ints, the range increments by 2^64-1 up to a max of 2^64-1, rather than decrementing by -1, and the range immediately finishes.

This seems like a relatively common operation, and it'd be nice if the rust compiler could catch the incorrect types in this code, and/or the range_step method could properly handle mixing signed and unsigned parameters to the method.

(N.b. I am relatively new to rust, sorry if there's something obvious I'm missing that invalidates this entirely)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions