-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Specialise count, last and nth for Cloned and Map iterators #28125
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
Thinking now, this might need an RFC since it breaks people’s assumptions with their side-effectful Please advise. |
My idea has been that these can only be specialized if there is no user-visible difference from the default Iterator-trait provided implementation of |
I believe these specializations aren't of very high importance. Better support for bidirectional or random access would be bigger. |
#[inline] | ||
fn last(self) -> Option<B> { | ||
let f = self.f; | ||
self.iter.last().map(f) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just nitpicking... is there a reason why last
does not use the same syntax as next
and nth
? (i.e. self.iter.last().map(|a| (self.f)(a))
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it doesn’t compile this way. self
is by value here and is therefore partially moved by self.iter
which does not allow capturing self
into the closure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, you're right, I did not realise that the signature was different... but then self.iter.last().map(self.f)
should work just fine, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it works.
I think they are important. If another method is added to |
I'm totally fine with this, pedantically this is a breaking change but practically I highly doubt that it will be. I'll tag this with T-libs so we can discuss but our conclusion may just be to clarify the documentation of the methods on the |
@alexcrichton It's not about breaking changes but about how we want iterators to behave |
@alexcrichton It breaks existing code. Examples: (1), (2), (3), (4)
|
I’m willing to limit the scope to While it is still theoretically breaking, I think the impact should be non-existent in the real world. |
Definitely not map. The |
If I am not mistaken, this would impact both side-effectful Has there been any investigation on what implementations of the |
The This would address the fair-to-common usecase where someone just wants to chain a method to run the iterator chain, instead of using the |
Just as an update, the libs team has had quite a full agenda the past few weeks (dealing with FCP both ending and starting anew), but we'll be sure to get around to this next week! |
@Kimundi I think an actual |
Ok, thanks for the patience here! The libs team talked about this and the conclusion was that these iterator adaptor methods should always preserve the same semantics as the current default implementations, specifically with respect to side effects that may be seen. In light of that I'm going to close this as "unfortunately we can't do this", and otherwise I've opened a tracking issue for auditing those changes we've already made in the standard library. |
Thank you, that sounds great for iterators. |
…).last() Iterator::last() consumes the entire iterator, even for DoubleEndedIterator, see rust-lang/rust#28125 (comment) Because of this, "at_line_start()" took 90% of fish_indent share/completions/git.fish making it take 1000ms instead of 30 ms. Fix that.
Map/Cloned does not call the mapping/cloning function unnecessarily anymore for
count
,last
andnth
, which has a serious benefit to performance, especially with expensive mapping functions.For example
runs in 25 ns/iter (+/- 9) compared to 238 ns/iter (+/- 21) with nightly.