Thanks to visit codestin.com
Credit goes to github.com

Skip to content

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
Contributor

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
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
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
Collaborator

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
Contributor

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.

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
Contributor

Kimundi commented Apr 16, 2018

@bors r+

@bors
Copy link
Collaborator

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
Collaborator

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
Collaborator

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.