Add vec::Drain{,Filter}::keep_rest#95376
Conversation
|
r? @kennytm (rust-highfive has picked a reviewer for you, use r? to override) |
|
I haven't looked at the code, but I think this is a better answer to 90% of what |
|
Truth be told, when I struggled with the default behavior of |
|
☔ The latest upstream changes (presumably #95798) made this pull request unmergeable. Please resolve the merge conflicts. |
|
Ping from triage: |
7fa7bac to
810a63e
Compare
|
I think this should be the default for
Perhaps adding a defaulted const generic |
|
r? rust-lang/libs-api |
|
☔ The latest upstream changes (presumably #97729) made this pull request unmergeable. Please resolve the merge conflicts. |
These methods allow to cancel draining of unyielded elements.
810a63e to
50c98a8
Compare
dtolnay
left a comment
There was a problem hiding this comment.
I am on board with this API. Next steps are:
- I think this is the kind of method that would benefit from a usage example in the rustdoc.
- Needs a tracking issue.
Some considerations to note in the tracking issue for discussion before we could stabilize:
- Just change the not-yet-stable
Drop for DrainFilterto keep rest?- Advantage: usually what you want (??)
- I don't have a good picture what the use cases involve drain_filter and not exhausting the iterator obtained from it.
- Disadvantage: inconsistent with stable
Drop for Drain - If you want to remove rest (matching the current unstable behavior of drain_filter) then you'd need to write
.foreach(drop)to explicitly drop all the rest of the range that matches the filter.
- Advantage: usually what you want (??)
&mut selfinstead ofself?- If you're holding a
Draininside a struct and are operating on it from a&mut selfmethod of the struct,keep_rest(self)is impossible to use. :(- You'd want something like
mem::replace(&mut self.drain_filter, Vec::new().drain(..)).keep_rest()but the borrow checker won't like that. - Failing that, you'd need to change your
Drainfield toOption<Drain>and useself.drain_filter.take().unwrap().keep_rest()along withunwrap()everywhere else that the drain is used. Not good.
- You'd want something like
- We'd need to define behavior of calling
.next()after.keep_rest(). Presumably one of:.next()returnsNone- this is considered incorrect usage and so
.next()panicks .keep_rest()sets a flag inside the Drain which Drop will use to decide its behavior, and you're free to continue accessing iterator elements in between.
- If you're holding a
|
I've updated docs and the tracking issue ✅ |
|
@bors r+ |
Rollup of 9 pull requests Successful merges: - rust-lang#95376 (Add `vec::Drain{,Filter}::keep_rest`) - rust-lang#100092 (Fall back when relating two opaques by substs in MIR typeck) - rust-lang#101019 (Suggest returning closure as `impl Fn`) - rust-lang#101022 (Erase late bound regions before comparing types in `suggest_dereferences`) - rust-lang#101101 (interpret: make read-pointer-as-bytes a CTFE-only error with extra information) - rust-lang#101123 (Remove `register_attr` feature) - rust-lang#101175 (Don't --bless in pre-push hook) - rust-lang#101176 (rustdoc: remove unused CSS selectors for `.table-display`) - rust-lang#101180 (Add another MaybeUninit array test with const) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This PR adds
keep_restmethods tovec::Drainandvec::DrainFilterunderdrain_keep_restfeature gate:Both these methods cancel draining of elements that were not yet yielded from the iterators. While this needs more testing & documentation, I want at least start the discussion. This may be a potential way out of the "should
DrainFilterexhaust itself on drop?" argument.