-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Revert "remove Copy impls from remaining iterators" #21846
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