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

Provide TryFrom<&[T]> implementation for &[[T; N]] #105316

Closed
wants to merge 1 commit into from

Conversation

mina86
Copy link
Contributor

@mina86 mina86 commented Dec 5, 2022

The TryFrom<&[T]> implementation for &[[T; N]] allows converting
a slice into a slice of N-element chunks while asserting that the
slice is evenly divided into those chunks. This is [T]::as_chunks
but makes it more concise to check that check that there's no
reminder. For example, something like:

let (chunks, remainder) = slice.as_chunks::<N>();
if !remainder.is_empty() {
    return Err(SomeError);
}

becomes:

let chunks = <&[[T; N]]>::try_from(slice).map_err(|_| SomeError)?;

ACP: rust-lang/libs-team#201

The `TryFrom<&[T]>` implementation for `<&[[T; N]]>` allows converting
a slice into a slice of N-element chunks while asserting that the
slice is evenly divided into those chunks.  This is `[T]::as_chunks`
but makes it more concise to check that check that there's no
reminder.  For example, something like:

    let (chunks, remainder) = slice.as_chunks::<N>();
    if !remainder.is_empty() {
        return Err(SomeError);
    }

becomes:

    let chunks = <&[[T; N]]>::try_from(slice).map_err(|_| SomeError)?;
@mina86
Copy link
Contributor Author

mina86 commented Dec 5, 2022

@rustbot label -T-libs +T-libs-api

#74985 is related.

I’m not sure how stability is supposed to work here. I was intending to propose this as addition to slice_as_chunks unstable feature but traits cannot be marked unstable. To make this compile added this as stable. Will this need an RFC?

@rustbot rustbot added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Dec 5, 2022
@rust-log-analyzer
Copy link
Collaborator

The job mingw-check failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
configure: rust.debug-assertions := True
configure: rust.overflow-checks := True
configure: llvm.assertions      := True
configure: dist.missing-tools   := True
configure: build.configure-args := ['--enable-sccache', '--disable-manage-submodu ...
configure: writing `config.toml` in current directory
configure: 
configure: run `python /checkout/x.py --help`
Attempting with retry: make prepare
---
* highest error code: E0790
Found 506 error codes
Found 0 error(s) in error codes
Done!
tidy error: /checkout/library/core/src/array/mod.rs:316: XXX is deprecated; use FIXME
tidy error: /checkout/library/core/src/array/mod.rs:345: XXX is deprecated; use FIXME
tidy error: The stabilization version 1.666.0 of lib feature `slice_try_as_chunks` is newer than the current 1.67.0
some tidy checks failed

@mejrs
Copy link
Contributor

mejrs commented Dec 6, 2022

I’m not sure how stability is supposed to work here. I was intending to propose this as addition to slice_as_chunks unstable feature but traits cannot be marked unstable. To make this compile added this as stable. Will this need an RFC?

A trait implementation such as this will be insta-stable, and needs a fcp.

@mina86
Copy link
Contributor Author

mina86 commented Dec 6, 2022

By FCP I’m assuming you mean final comment period. How would I trigger that for this change? Or do you mean this needs to wait for the slice_as_chunks’s FCP to be considered?

@scottmcm scottmcm added the needs-fcp This change is insta-stable, so needs a completed FCP to proceed. label Dec 17, 2022
@scottmcm
Copy link
Member

You make this its own feature name that this PR would make stable, and it's up to someone from T-libs-api to decide whether to kick off an FCP to add this.
r? rust-lang/libs-api

@scottmcm
Copy link
Member

Alternatively, this is the inverse of [T]::flatten (#95629), so you could add it as a named method instead of a trait impl, as those can be unstable.

(Sadly, the obvious antonym, fold, already has another meaning. So it'd need to be unflatten or crumple or something.)

@mina86
Copy link
Contributor Author

mina86 commented Dec 17, 2022

Either works for me so I’m happy to wait for reviewer to decide which path (TryFrom or method) is preferred.

Copy link
Member

@dtolnay dtolnay left a comment

Choose a reason for hiding this comment

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

The motivation mentions:

let chunks = <&[[T; N]]>::try_from(slice).map_err(|_| SomeError)?;

I think that use case is covered well enough already by:

let (chunks, []) = slice.as_chunks::<N>() else {return Err(SomeError)};

@mina86
Copy link
Contributor Author

mina86 commented Dec 18, 2022

TryFrom is still more compact and works better with method call
chaining especially since there’s also TryInto that can be used:

fn u64_chunks(bytes: &[u8]) -> Result<&[[u8; u64]]> {
    bytes.try_into().map_err(|_| SomeError)
}
// vs
fn u64_chunks(bytes: &[u8]) -> Result<&[[u8; u64]]> {
    let (chunks, []) = bytes.as_chunks() else { return Err(SomeError) };
    chunks
}
let u64s = get_bytes_in_a_vector()
    .as_slice()
    .try_into::<&[[u8; 8]]>(bytes)
    .map_err(|_| SomeError)?
    .into_iter()
    .map(|chunk| u64::from_le_bytes(*bytes))
    .collect::<Vec<_>>();
// vs
let bytes = get_bytes_in_a_vector();
let (chunks, []) = bytes.as_chunks() else { return Err(SomeError.into()); };
let u64s = chunks
    .into_iter()
    .map(|chunk| u64::from_le_bytes(*bytes))
    .collect::<Vec<_>>()
let chunks = <&[[_; N]]>::try_from(slice).unwrap();
// or
let chunks = slice.try_into::<&[[_; N]]>().unwrap();
// vs
let (chunks, []) = slice.as_chunks::<N>() else { unreachable!() };

so I’d still love to have it even with let-else alternative.

matthiaskrgr pushed a commit to matthiaskrgr/rust that referenced this pull request Dec 18, 2022
I really liked this structure that dtolney brought up in rust-lang#105316, so wanted to put it in the docs to help others use it.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Dec 18, 2022
…r=the8472

Another `as_chunks` example

I really liked this structure that dtolney brought up in rust-lang#105316, so wanted to put it in the docs to help others use it.
@dtolnay
Copy link
Member

dtolnay commented Feb 28, 2023

Looking at this again, I'm still not sold that this API carries its weight. I think the best chance for you to get this moving would be follow https://std-dev-guide.rust-lang.org/feature-lifecycle/api-change-proposals.html and open a convincing API change proposal in https://github.com/rust-lang/libs-team, to give someone else on the team (not me) a chance to second it if they like the idea.

@dtolnay dtolnay marked this pull request as draft February 28, 2023 05:44
@scottmcm scottmcm added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Feb 28, 2023
@mina86 mina86 changed the title Provide TryFrom<&[T]> implementation for <&[[T; N]]> Provide TryFrom<&[T]> implementation for &[[T; N]] Apr 1, 2023
@mina86
Copy link
Contributor Author

mina86 commented Apr 1, 2023

@rustbot label -S-waiting-on-author +S-waiting-on-ACP

@rustbot rustbot added S-waiting-on-ACP Status: PR has an ACP and is waiting for the ACP to complete. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 1, 2023
@scottmcm
Copy link
Member

scottmcm commented Apr 6, 2023

Since this is insta-stable, it probably needs a resolution to the "what to do for N == 0?" problem from #74985 before it can land.

@dtolnay dtolnay closed this Jul 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-fcp This change is insta-stable, so needs a completed FCP to proceed. S-waiting-on-ACP Status: PR has an ACP and is waiting for the ACP to complete. 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.

6 participants