Their end_bound are different. Shouldn't they work the same way?
I guess it's something to do with iterators.
when T: Step, RangeInclusive<T> implements Iterator, that's why it needs the extra exhaustive boolean flag, because the range might be mutated ("shrinked"). that's also the reason ranges are not Copy: an Iterator that is Copy is very easy to be misused.
on the other hand, reference types (at least the built-in scalar types) never implement Step, so RangeInclusive<&T> cannot be "shrinked" via iteration, it is essentially immutable.
let mut r = 0..=0;
dbg!(r.start_bound());
dbg!(r.end_bound());
dbg!(r.contains(&0));
// calling `Iterator::next()` will "shrink" the range
let x = Iterator::next(&mut r);
assert_eq!(x, Some(0));
dbg!(r.start_bound());
dbg!(r.end_bound());
dbg!(r.contains(&0));
let mut rr = &0..=&0;
Iterator::next(&mut rr); // error: `&Integer: Step` not satisified
see also the "new" range type design in rfc3550:
4 Likes