-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Revert "remove Copy impls from remaining iterators" #21846
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Conversation
This reverts commit c3841b9.
(rust_highfive has picked a reviewer for you, use r? to override) |
IMO ranges should implement "IntoIterator" rather than being iterators themselves, it doesn't make too much sense and it's caused a few other conflicts as well as this. For example, currently "RangeTo" is not iterable at all, because there's currently no such thing as a "ReverseIterator" trait, and it only makes sense to iterate a "RangeTo" in reverse. If ranges are not themselves iterators, then "RangeTo" can just have a method to return a reverse iterator over that range, without breaking the symmetry with "RangeFrom" which has a similar method as part of its implementation of "IntoIterator", but for a forward iterator. |
CC @aturon |
@aturon I can do this, but it will break much code like |
@aturon Any news on this? |
Is that an insurmountable problem? #[derive(Copy)] struct Struct { .. }
fn constructor(r: Range<i32>) -> Struct {
Struct { start: r.start, end: r.end, .. }
} Then you can reconstruct the iterable range from the copies: @tbu- Could you elaborate on what functionality can't be achieved because |
@japaric I can't use them as public fields in my structs, constructors means you cna't construct a struct at compile-time, setters mean that I can't have per-field mutable borrows anymore. Things that are "a little unergonomic" have really bad impact. |
@japaric There's no reason |
Of course, you don't have to, you can keep the fields private.
Yes, but you just said above that you can't make the range public, so you need a constructor. (?)
Sorry, I don't quite understand this statement, you mean a getter that freezes the struct?
The original problem was #18045, which perhaps could have been prevented using a lint that triggers when an iterator is implicitly copied, but the core-devs opted for making iterators not implement
(I think impossible is an overstatement)
Range is a trivial memcpy (which is what clone does), yes, but that doesn't mean that it should be implicitly copyable. The current @tbu- I'd still like to see what use case you have problems with. |
@japaric It may indeed be the problem that the two things are conflated – not implementing Copy locks out compound data types from implementing Copy themselves. The core-devs might have missed that they were making I'm not sure if you're mocking me with your line-by-line reply, but what I wanted to say with the different options is that none of them are suitable: If I make the fields public, the sugar isn't there, if I use a constructor it can't be constructed statically, if I use setters and getters I always need complete ownership of the struct before I can set a single member. |
@japaric To see why sugar is important, let me suggest to remove the |
Sorry for the delay. Let me respond to your earlier comment.
There have been a lot of requests to reintroduce |
I've talked about this with @nikomatsakis and I think we definitely want to do it at some point, but I believe it can be done backwards-compatibly. |
Being able to treat (a..b) as an iterator is a really nice pattern outside of from_elem. |
A nice benefit of making ranges only IntoIter is that it resolves the need for a hypothetical RangeInclusive to include a has_yielded_inclusive boolean. |
Can you give some examples to clarify this? Any code that currently takes an |
Ah, hm, I bet you mean things like |
To be clear, the non- |
Yeah (a..b).mess().of().adaptors() is pretty pleasant in my opinion. |
Certainly no. I apologize if it seem that way. I was trying to understand your use case but failed to do so.
Sugar is important, but there is trade off between ergonomics and a potential source of bugs. Removing Iterator from Range will generate way more fallout (not just the
I was mocking a design, and it was backward incompatible, but if you have explored the space and think it can implement in bakcward compatible way, then I trust your decision of postponing it for after 1.0.
I'd be in favor of implementing
|
This example makes me feel especially strongly that ranges should be IntoIterator rather than Iterator. If I iterate through a range using a for loop, it's extremely counterintuitive to me that the range is modified in the process. While it's slightly more work to type ".iter()" to use it as an iterator:
|
The conflict between "leaving out One possible way to resolve that particular conflict could be the route suggested by @huonw here: Though as @huonw said at the time, the complexity of that solution may not pay for itself. |
@pnkfelix I think in the long run we will definitely want to go in this direction, but @nikomatsakis and I believe that we can do so backwards-compatibly. |
@aturon oh sorry, I see you wrote the same thing up above; sorry to make you repeat yourself! |
@aturon So I made an
fails with the error message "expected |
@aturon Now the decision in the RFC was to add a lint some day – so could we merge this |
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
☔ The latest upstream changes (presumably #25262) made this pull request unmergeable. Please resolve the merge conflicts. |
@tbu- Sorry, this one got buried and I missed it. In the Pod/Copy decision we determined that a lint was better than adding a further split to the marker traits, but I don't think there was an explicit decision about cases like this prior to the lint landing. I personally don't have a strong opinion here, though. I will ask the library subteam! |
As per discussion within the libs team on IRC (https://botbot.me/mozilla/rust-libs/2015-05-19/?msg=39609682&page=1), we're not going to take this at the moment. If in the future we develop a lint to make it more feasible to make this |
The link to IRC log above seems to have been broken now. If anyone still has the log, could you paste the whole log here (maybe hidden inside |
Here is a copy of the log on archive.org: https://web.archive.org/web/20181012140432/https://botbot.me/mozilla/rust-libs/2015-05-19/ I hope archive.org doesn't go the way of botbot.me, but just in case, since this was such a big decision that people still ask about:
|
This reverts commit c3841b9.
The commit made it impossible to copy the pretty fundamental data type
Range
andRangeFrom
, which e.g. means that they can't be used in otherwise copyable structures anymore (orCell
s for that matter), where the reason for removal was that it can also be used as an iterator.CC @japaric
#21809