Skip to content
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

Replace manual iterator exhaust with for_each(drop) #48945

Merged
merged 1 commit into from Apr 16, 2018

Conversation

Projects
None yet
@clarfon
Copy link
Contributor

clarfon commented Mar 12, 2018

This originally added a dedicated method, Iterator::exhaust, and has since been replaced with for_each(drop), which is more idiomatic.

This is just shorthand for for _ in &mut self {} or while let Some(_) = self.next() {}. This states the intent a lot more clearly than the identical code: run the iterator to completion.

At least personally, my eyes tend to gloss over for _ in &mut self {} without fully paying attention to what it does; having a Drop implementation akin to:

for _ in &mut self {}; unsafe { free(self.ptr); }

Is not as clear as:

self.exhaust(); unsafe { free(self.ptr); }

Additionally, I've seen debate over whether while let Some(_) = self.next() {} or for _ in &mut self {} is more clear, whereas self.exhaust() is clearer than both.

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

rust-highfive commented Mar 12, 2018

r? @TimNN

(rust_highfive has picked a reviewer for you, use r? to override)

@clarfon clarfon force-pushed the clarfon:iter_exhaust branch 5 times, most recently from 049a71c to f109596 Mar 12, 2018

@kennytm kennytm added the T-libs label Mar 12, 2018

@ollie27

This comment has been minimized.

Copy link
Contributor

ollie27 commented Mar 12, 2018

As I suggested in #45168 I think this should take self by value like all the other methods which consume an iterator.

Also the implementation should probably be written in terms of fold like #45168.

@TimNN

This comment has been minimized.

Copy link
Contributor

TimNN commented Mar 12, 2018

Re-assigning to @rust-lang/libs:

r? @Kimundi


As I suggested in #45168 I think this should take self by value like all the other methods which consume an iterator.

I think that would kind of defeat the purpose of the method proposed here: Not dropping / consuming the iterator seems to be an explicit goal.

If consuming the iterator was the goal either mem::drop(iter) or iter.for_each(|_| ()) should work. In fact, .exhaust() would probably be equivalent to (&mut iter).for_each(|_| ()), I think.

@rust-highfive rust-highfive assigned Kimundi and unassigned TimNN Mar 12, 2018

@clarfon

This comment has been minimized.

Copy link
Contributor Author

clarfon commented Mar 12, 2018

Note that |_| () could be worded as drop also.

@ExpHP

This comment has been minimized.

Copy link
Contributor

ExpHP commented Mar 13, 2018

And putting it all together with by_ref():

iter.by_ref().for_each(drop);
unsafe { free(self.ptr); }

I rather like the looks of what we can already write.

@Centril

This comment has been minimized.

Copy link
Contributor

Centril commented Mar 14, 2018

Is this operation common enough to warrant a dedicated method in Iterator?

@sfackler

This comment has been minimized.

Copy link
Member

sfackler commented Mar 14, 2018

I think I agree that as_ref + for_each sufficiently covers this kind of thing.

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Mar 15, 2018

☔️ The latest upstream changes (presumably #47813) made this pull request unmergeable. Please resolve the merge conflicts.

@pietroalbini

This comment has been minimized.

Copy link
Member

pietroalbini commented Mar 20, 2018

Ping from triage @Kimundi! This PR (probably) needs a review.

@sfackler so, should this PR be closed?

@clarfon

This comment has been minimized.

Copy link
Contributor Author

clarfon commented Mar 20, 2018

(If there is a motion to close I'll open a new PR to replace the instances that I changed to exhaust to by_ref().for_each(drop))

@pietroalbini

This comment has been minimized.

Copy link
Member

pietroalbini commented Mar 26, 2018

Ping from triage @rust-lang/libs! Can we get a review/decision on this PR?

@Kimundi

This comment has been minimized.

Copy link
Member

Kimundi commented Mar 26, 2018

Sorry, seems to have slipped under my radar. I think that I agree with @ExpHP that .by_ref().for_each(drop) is probably the better solution, as it just uses existing functionality.

I personally don't have any strong feelings about wether to add the new method or not, but I know that something like exhaust() method has been proposed multiple times in the past already, and not been added even before we had .for_each(), so I'd tentatively counts that as a argument against it.

@Centril

This comment has been minimized.

Copy link
Contributor

Centril commented Mar 26, 2018

@Kimundi Can we make this a matter of documentation then and include text about .by_ref().for_each(drop) somewhere on Iterator?

@scottmcm

This comment has been minimized.

Copy link
Member

scottmcm commented Mar 26, 2018

somewhere on Iterator

It feels mure like a "common patterns" document more than the doc comment. Is there a good place for that in one of the books? RBE is on doc.RLO now; maybe there?

@Centril

This comment has been minimized.

Copy link
Contributor

Centril commented Mar 26, 2018

@clarfon clarfon force-pushed the clarfon:iter_exhaust branch from f109596 to 5c58eec Apr 4, 2018

@clarfon clarfon changed the title Add Iterator::exhaust. Replace manual iterator exhaust with for_each(drop) Apr 4, 2018

@clarfon

This comment has been minimized.

Copy link
Contributor Author

clarfon commented Apr 4, 2018

I've replaced instances of the method with for_each(drop) as preferred by everyone here.

@@ -1129,7 +1129,7 @@ impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {

impl<'a, K: 'a, V: 'a> Drop for Drain<'a, K, V> {
fn drop(&mut self) {
for _ in self {}
self.for_each(drop);

This comment has been minimized.

@scottmcm

scottmcm Apr 4, 2018

Member

Ooh, nice that this just works without needing .by_ref() 🙂

This comment has been minimized.

@clarfon

clarfon Apr 5, 2018

Author Contributor

When I saw this comment my immediate thought was to hope that the CI actually passed, because I was pretty sure it would work but not 100%. :p

@pietroalbini

This comment has been minimized.

Copy link
Member

pietroalbini commented Apr 9, 2018

Ping from triage @Kimundi! If I understood correctly this PR still needs your review.

@sfackler sfackler referenced this pull request Apr 16, 2018

Closed

Add Iterator::exhaust #49990

@pietroalbini

This comment has been minimized.

Copy link
Member

pietroalbini commented Apr 16, 2018

Ping from triage! Can @Kimundi (or someone else from @rust-lang/libs) review this?

@Kimundi

This comment has been minimized.

Copy link
Member

Kimundi commented Apr 16, 2018

@bors r+

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Apr 16, 2018

📌 Commit 5c58eec has been approved by Kimundi

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Apr 16, 2018

⌛️ Testing commit 5c58eec with merge 1ef1563...

bors added a commit that referenced this pull request Apr 16, 2018

Auto merge of #48945 - clarcharr:iter_exhaust, r=Kimundi
Replace manual iterator exhaust with for_each(drop)

This originally added a dedicated method, `Iterator::exhaust`, and has since been replaced with `for_each(drop)`, which is more idiomatic.

<del>This is just shorthand for `for _ in &mut self {}` or `while let Some(_) = self.next() {}`. This states the intent a lot more clearly than the identical code: run the iterator to completion.

<del>At least personally, my eyes tend to gloss over `for _ in &mut self {}` without fully paying attention to what it does; having a `Drop` implementation akin to:

<del>`for _ in &mut self {}; unsafe { free(self.ptr); }`</del>

<del>Is not as clear as:

<del>`self.exhaust(); unsafe { free(self.ptr); }`

<del>Additionally, I've seen debate over whether `while let Some(_) = self.next() {}` or `for _ in &mut self {}` is more clear, whereas `self.exhaust()` is clearer than both.

@bors bors referenced this pull request Apr 16, 2018

Merged

Stabilize x86/x86_64 SIMD #49664

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Apr 16, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: Kimundi
Pushing 1ef1563 to master...

@bors bors merged commit 5c58eec into rust-lang:master Apr 16, 2018

2 checks passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details

@clarfon clarfon deleted the clarfon:iter_exhaust branch Apr 16, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.