234. core::range::Range — A Range That's Copy, So You Can Store and Reuse It
The classic 0..3 isn’t Copy — it is the iterator, so it gets consumed and can’t live in a Copy struct. Rust 1.96 stabilises core::range::Range, which is Copy and iterates through IntoIterator instead.
Why the old Range fights you
std::ops::Range implements Iterator directly. That’s convenient in a for loop, but it means the range is mutable iterator state, so it can’t be Copy:
| |
It also can’t sit inside a Copy type, which is annoying when you want a lightweight span:
| |
The new core::range::Range is Copy
Stabilised in 1.96, core::range::Range implements IntoIterator rather than Iterator, which frees it to be Copy. Convert a literal range into it with .into():
| |
Now it fits in a Copy struct
Because it’s Copy, you can store a range as a cheap, copyable span and still index slices with it directly:
| |
No more splitting a range into separate start / end fields just to keep a struct Copy.
Heads up
0..3 syntax still produces the legacy std::ops::Range for now — the new types come in via .into() or by naming core::range::Range. A future edition will switch the syntax over. For public APIs that should accept either, take impl RangeBounds<usize>.
Stabilised in Rust 1.96 (May 2026).