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

clarfonthey
Copy link
Contributor

@clarfonthey clarfonthey 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
Copy link
Collaborator

r? @TimNN

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

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 12, 2018
@clarfonthey clarfonthey force-pushed the iter_exhaust branch 5 times, most recently from 049a71c to f109596 Compare March 12, 2018 02:03
@kennytm kennytm added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Mar 12, 2018
@ollie27
Copy link
Member

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
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
@clarfonthey
Copy link
Contributor Author

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

@ExpHP
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
Copy link
Contributor

Centril commented Mar 14, 2018

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

@sfackler
Copy link
Member

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

@bors
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
Copy link
Member

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

@sfackler so, should this PR be closed?

@clarfonthey
Copy link
Contributor Author

(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
Copy link
Member

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

@Kimundi
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
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
Copy link
Member

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
Copy link
Contributor

Centril commented Mar 26, 2018

cc @steveklabnik ^

@clarfonthey clarfonthey changed the title Add Iterator::exhaust. Replace manual iterator exhaust with for_each(drop) Apr 4, 2018
@clarfonthey
Copy link
Contributor Author

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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Member

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

@sfackler sfackler mentioned this pull request Apr 16, 2018
@pietroalbini
Copy link
Member

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

@Kimundi
Copy link
Member

Kimundi commented Apr 16, 2018

@bors r+

@bors
Copy link
Contributor

bors commented Apr 16, 2018

📌 Commit 5c58eec has been approved by Kimundi

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 16, 2018
@bors
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
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 mentioned this pull request Apr 16, 2018
@bors
Copy link
Contributor

bors commented Apr 16, 2018

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.