-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Implement Vec::drain from RFC 574 #24781
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @brson (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. The way Github handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see CONTRIBUTING.md for more information. |
r? @aturon |
Range, | ||
RangeTo, | ||
RangeFrom | ||
}; |
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.
Stylistically the compiler doesn't tend to put an import-per-line like this but instead use multiple use
statements.
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.
One line with {RangeFull, Range, ..}
for all the ranges would be the usual style then?
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.
Indeed! The wrapping (to a new import) just happens if it runs over 80 chars
I've addressed all review comments, thank you @alexcrichton! Introducing this as unstable gives us leeway to fix it up later, what we could change:
|
use core::option::Option::{self, None, Some}; | ||
use core::ops::{RangeFull, Range, RangeTo, RangeFrom}; | ||
|
||
#[unstable(feature = "collections", reason = "was just added")] |
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.
On second though, could you apply just one of these stability attributes to the module itself? The instability should be inherited. Additionally, could you give this a name like collections_range
as well?
Looks great to me, thanks @bluss! After some minor refinements of the feature names here I think this is good to go! |
I'm excited. I'm working on checking that it compiles and then squashing it together. |
Thanks! Lemme know when it's ready to go and I'll r+ |
RangeArgument is introduced as unstable under the feature(collections_range)
There, it should be ready. I could have missed something, haven't added new feature flags before. |
⌛ Testing commit 447ef06 with merge dc19940... |
💔 Test failed - auto-mac-64-opt |
Old `.drain()` on vec is performed using `.drain(..)` now. `.drain(range)` is unstable and under feature(collections_drain) [breaking-change]
Fixed that test. |
Implement Vec::drain(\<range type\>) from rust-lang/rfcs#574, tracking issue #23055. This is a big step forward for vector usability. This is an introduction of an API for removing a range of *m* consecutive elements from a vector, as efficently as possible. New features: - Introduce trait `std::collections::range::RangeArgument` implemented by all four built-in range types. - Change `Vec::drain()` to use `Vec::drain<R: RangeArgument>(R)` Implementation notes: - Use @gankro's idea for memory safety: Use `set_len` on the source vector when creating the iterator, to make sure that the part of the vector that will be modified is unreachable. Fix up things in Drain's destructor — but even if it doesn't run, we don't expose any moved-out-from slots of the vector. - This `.drain<R>(R)` very close to how it is specified in the RFC. - Introduced as unstable - Drain reuses the slice iterator — copying and pasting the same iterator pointer arithmetic again felt very bad - The `usize` index as a range argument in the RFC is not included. The ranges trait would have to change to accomodate it. Please help me with: - Name and location of the new ranges trait. - Design of the ranges trait - Understanding Niko's comments about variance (Note: for a long time I was using a straight up &mut Vec in the iterator, but I changed this to permit reusing the slice iterator). Previous PR and discussion: #23071
So I know I'm starting to sound like a broken record but... use std::collections::Bound;
trait Bounds {
fn start(&self) -> Bound<&T>;
fn end(&self) -> Bound<&T>;
}
impl<T> Bounds for Range<T> {
fn start(&self) -> Bound<&T> { Bound::Included(&self.start) }
fn start(&self) -> Bound<&T> { Bound::Excluded(&self.end) }
}
// ... I suggest adding an |
I agree it's not ready for stabilization. Specifically the design of the trait over ranges, and then we should impl drain for more collections to see how the API holds up. |
|
Implement Vec::drain() from rust-lang/rfcs#574, tracking issue #23055.
This is a big step forward for vector usability. This is an introduction of an API for removing a range of m consecutive elements from a vector, as efficently as possible.
New features:
std::collections::range::RangeArgument
implemented by all four built-in range types.Vec::drain()
to useVec::drain<R: RangeArgument>(R)
Implementation notes:
set_len
on the source vector when creating the iterator, to make sure that the part of the vector that will be modified is unreachable. Fix up things in Drain's destructor — but even if it doesn't run, we don't expose any moved-out-from slots of the vector..drain<R>(R)
very close to how it is specified in the RFC.usize
index as a range argument in the RFC is not included. The ranges trait would have to change to accomodate it.Please help me with:
Previous PR and discussion: #23071