3 ms·
I broadly agree with this, and am most frequently confused by the fact that a `Range<T>` isn't `Copy` even if `T: Copy`. I feel this was a small design mistake
by cmyr 6y ago
I broadly agree with this, and am most frequently confused by the fact that a `Range<T>` isn't `Copy` even if `T: Copy`. I feel this was a small design mistake (having `Range` itself be an interator instead of implementing the `IntoIterator` trait) but there is a proposal to fix this that looks like it wouldn't be breaking, and so should be possible:
https://github.com/rust-lang/rfcs/issues/2848 https://github.com/rust-lang/rfcs/issues/2848
- saghm 6y agoYeah, this sounds like it could be fixed with a one-liner without any breaking changes: `impl<T> Copy for Range<T> where T: Copy {}`. That being said, I can understand why this might not necessarily be desirable for some people; Copy is generally reserved for types that are "small enough" that implicitly copying the bytes will be cheap enough to ignore. It might seem obvious that a struct containing two types that are Copy should also be cheap enough to be Copy, the line has to be drawn _somewhere_, and for any number of bytes that is chosen to be the threshold where the cost is too high, it's pretty easy to pick a size that's below that threshold but a struct containing two instances of that size is above the threshold. Because of the unclear boundaries for that sort of thing, I generally tend only to derive Copy on things in my code that thin wrappers around existing types that are Copy, e.g. `struct Foo(i32)`.
- cmyr 6y agoThe reason this can't be done quite as you describe is outlined in the linked issue: if something implements both `Iterator` (as Range does) as well as `Copy`, then you can end up in situations where you accidentally end up copying an iterator you think you're mutating. A good example is provided here: https://github.com/rust-lang/rust/issues/48649#issuecomment-478350940 https://github.com/rust-lang/rust/issues/48649#issuecomment-...
- saghm 6y agoHmm, interesting. I honestly don't think I've ever really used an iterator like that, but I can understand why that would be considered undesirable. It does seem like having Range implement IntoIterator rather than Iterator would probably have been best, but that's tough to fix now.