-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Add slice::{split_,}{first,last}_chunk{,_mut} #95198
Conversation
r? @yaahc (rust-highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
I've definitely written a bunch of examples that did I don't know if this is how I'd expect it to look, though. For example, the indexing could be left to subslicing, like Of course, the other thing that comes to mind is wanting |
Hmm, you do have a point about subslicing; it might be more natural to have Essentially, we'd mimic the |
I don't know what the best approach would be here. Might be worth seeing if libs-api has any specific preferences. The whole "add const generic versions of most of the slice stuff" is a big project, but seems useful, so maybe they could have some generalized guidance of how they'd like to see it done? If that existed then I'd be happy to sign off on a bunch of individual PRs for adding the various pieces. |
That's incredibly fair. Since I was feeling particularly motivated, I decided to go ahead and implement the first/last chunk semantics that I mentioned and maybe that can help explain how this would work out. I personally find the result rather intuitive, although the chunk naming will probably need work before stabilisation. Hopefully seeing how this would work in code will help iron out that process. EDIT: And I finished modifying the PR description to properly summarise the new API and the use cases it allows. |
library/core/src/lib.rs
Outdated
@@ -151,6 +151,7 @@ | |||
#![feature(const_slice_from_ref)] | |||
#![feature(const_slice_index)] | |||
#![feature(const_is_char_boundary)] | |||
#![feature(slice_split_at_unchecked)] |
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.
I genuinely have no idea how this wasn't required before, since the existing implementation of split_at
requires split_at_unchecked
??
Anyway, I decided to reuse this code for these methods and needed this.
These look great to me, but apparently I was blind looking at the rustdoc, as I forgot about https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_array_mut from #90091 (comment) . I personally like these better, because they solve the |
Yeah, it's always a challenge to figure out what's there when there are so many methods and they're not really sorted in any logical way. But, I guess, that's a challenge for another day. Before merge, we can maybe decide which tracking issue this should go in, since, in hindsight, it makes the most sense for it to have its own tracking issue. |
I don't think |
☔ The latest upstream changes (presumably #95274) made this pull request unmergeable. Please resolve the merge conflicts. |
r? @rust-lang/libs-api |
Nominating for libs-api to try to unblock this. (Since it just came up on URLO.) Should we just merge to nightly as fine for unstable? Do you have strong feelings about the direction to take for "get arrays from slices" APIs? Does this need an ACP/RFC now? (Of course ACPs didn't exist when this PR was opened.) |
☔ The latest upstream changes (presumably #101017) made this pull request unmergeable. Please resolve the merge conflicts. |
With the APIs proposed, I don't see a nice way to extract a subslice at arbitrary offset (and fixed length) as an array and get an Option without panicking. impl [T] {
pub const fn get_array<const N: usize>(&self, start_idx: usize) -> Option<&[T; N]>;
pub const fn get_array_mut<const N: usize>(&mut self, start_idx: usize) -> Option<&mut [T; N]>;
} I think it's acceptable to have to specify a zero to get the first chunk:
The methods |
Looks like the ACP was accepted! 🎉 @clarfonthey Can you rebase and resolve conflicts and such please? |
2baf530
to
1974c7f
Compare
This comment has been minimized.
This comment has been minimized.
(Going to wait on final CI run to pass the torch, but things should be rebased now. The biggest change I had to make was using |
@rustbot ready |
#[unstable(feature = "slice_first_last_chunk", issue = "111774")] | ||
#[rustc_const_unstable(feature = "slice_first_last_chunk", issue = "111774")] | ||
#[inline] | ||
pub const fn split_last_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])> { |
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.
Hmm, I would have expected this to be -> Option<(&[T], &[T; N])>
, but this is consistent with split_last
, so I guess it's fine for now. I'll put a note in the tracking issue.
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.
Yeah, there are arguments for both but honestly, I don't feel too swayed either way. I think that the potential issues here are greater because of how the types are only nominally different and can both be coerced to be the same, although I don't think there's a whole much that can be done about that than encourage folks to pay more attention.
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.
Yeah, I'm worried that someone might try something that boils down to let (head, tail) = x.split_last_chunk(); frobble(tail[0])
and being confused when it compiles (as you said) but doesn't do what they expected.
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.
I think that should probably be mentioned on the tracking issue, because I would write something like that... 😅
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.
@WaffleLapkin Is the note in #111774 (comment) not sufficient?
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.
It is sufficient, thanks
Thanks! I'm excited to have these. @bors r+ rollup |
…iaskrgr Rollup of 4 pull requests Successful merges: - rust-lang#95198 (Add slice::{split_,}{first,last}_chunk{,_mut}) - rust-lang#109899 (Use apple-m1 as target CPU for aarch64-apple-darwin.) - rust-lang#111624 (Emit diagnostic for privately uninhabited uncovered witnesses.) - rust-lang#111875 (Don't leak the function that is called on drop) r? `@ghost` `@rustbot` modify labels: rollup
This adds to the existing tracking issue for
slice::array_chunks
(#74985) under a separate feature,slice_get_chunk
.Currently, we have the existing
first
/last
API for slices:This augments it with a
first_chunk
/last_chunk
API that allows retrieving multiple elements at once:The code is based off of a copy of the existing API, with the documentation and examples properly modified. Currently, the most common way to perform these kinds of lookups with the existing methods is via
slice.as_chunks::<N>().0[0]
or the worseslice.as_chunks::<N>().0[slice.len() - N]
, which is substantially less readable thanslice.first_chunk::<N>()
orslice.last_chunk::<N>()
.ACP: rust-lang/libs-team#69