-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
remove Copy impls from remaining iterators #21809
Conversation
Removes `Copy` from `ops::Range` (`a..b`) and `ops::RangeFrom` (`a..`) [breaking-change] --- I forgot about these two in #20790, this PR also adds `Clone` to the `Peekable` adapter which used to be `Copy`able. r? @nikomatsakis or anyone
@japaric |
This hurts the use of range in other APIs, as planned by std::rand (where it ends up) and collections. |
Right now |
Yes, they are heavily used for slicing in the whole rust repo, and as evidenced by this PR, it wasn't necessary to explictly clone any range at all, which means that the implicitly copyable property of ranges wasn't used in the whole repository. (Of course, we can't extrapolate this to all the other existing libraries, but it's worth noting)
That would hurt the ergonomics of the // from
let v = (a..b).map(f).collect::<Vec<_>>();
// to
use std::iter::IntoIterator;
let v = (a..b).into_iter().map(f).collect::<Vec<_>>();
Could you show me an example on how non implictly copyable ranges would hurt the ergonomics of these planned APIs? I'd like to better understand the situation. I don't know the exact API that will be added, but IIRC one of them was using range with // with implicit copy
let range = a..b;
v1.remove(range);
v2.remove(range);
// without implict copy (today)
let range = a..b;
v1.remove(range.clone());
v2.remove(range);
// however, I think it would be clearer to do
v1.remove(a..b);
v2.remove(a..b);
// which doesn't require an implicit copy
Yes, structs that implement To give some background. When I was implementing the new for-loops which take the iterator by value. The implictly copyability of iterators was causing several collections tests to SIGILL and broke some The new for-loops changed the semantics of the following pattern: // original code
for x in it { // a *copy* of the iterator is used here
// ..
}
match it.next() { // the original iterator is used here
// ..
} When the intended behaviour was: for x in it.by_ref() { // advance the iterator
// ..
}
match it.next() { // reuse the mutated iterator
// ..
} But I didn't know where the problems were. The fastest way to find the bugs was to make the iterators non-implictly copyable, that way the original code would error at compile time with My original plan was to fix the bugs, then make the iterators implicitly copyable again and defer the decision of whether iterators should be implictly copyable to a later date. But after discussing with the core devs, they told me that they wanted to make iterators non-implictly copyable anyways, so I went ahead with that. |
This reverts commit c3841b9. The commit made it impossible to copy the pretty fundamental data type `Range` and `RangeFrom`, which e.g. means that they can't be used in otherwise copyable structures anymore (or `Cell`s for that matter), where the reason for removal was that it can *also be used as an iterator*. CC @japaric rust-lang#21809
Removes
Copy
fromops::Range
(a..b
) andops::RangeFrom
(a..
)[breaking-change]
I forgot about these two in #20790, this PR also adds
Clone
to thePeekable
adapter which used to beCopy
able.r? @nikomatsakis or anyone