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

&[T] can be converted into [T; N] but &mut [T] can't #91085

Closed
rhysd opened this issue Nov 20, 2021 · 1 comment · Fixed by #91086
Closed

&[T] can be converted into [T; N] but &mut [T] can't #91085

rhysd opened this issue Nov 20, 2021 · 1 comment · Fixed by #91086
Labels
A-array Area: `[T; N]` C-bug Category: This is a bug. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@rhysd
Copy link
Contributor

rhysd commented Nov 20, 2021

I tried this code:

fn main() {
    use std::convert::TryFrom;

    let s: &[i32] = &[1, 2, 3, 4, 5];
    let _: [i32; 5] = TryFrom::try_from(s).unwrap();

    let s: &mut [i32] = &mut [1, 2, 3, 4, 5];
    let _: [i32; 5] = TryFrom::try_from(s).unwrap();
}

I expected to see this happen: The source is compiled without any error.

Instead, this happened: Compile error as follows.

error[E0277]: the trait bound `[i32; 5]: From<&mut [i32]>` is not satisfied
   --> foo.rs:8:23
    |
8   |     let _: [i32; 5] = TryFrom::try_from(s).unwrap();
    |                       ^^^^^^^^^^^^^^^^^ the trait `From<&mut [i32]>` is not implemented for `[i32; 5]`
    |
    = note: required because of the requirements on the impl of `Into<[i32; 5]>` for `&mut [i32]`
    = note: required because of the requirements on the impl of `TryFrom<&mut [i32]>` for `[i32; 5]`
note: required by `try_from`
   --> /Users/rhysd/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/convert/mod.rs:477:5
    |
477 |     fn try_from(value: T) -> Result<Self, Self::Error>;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0277]: the trait bound `[i32; 5]: From<&mut [i32]>` is not satisfied
 --> foo.rs:8:23
  |
8 |     let _: [i32; 5] = TryFrom::try_from(s).unwrap();
  |                       ^^^^^^^^^^^^^^^^^^^^ the trait `From<&mut [i32]>` is not implemented for `[i32; 5]`
  |
  = note: required because of the requirements on the impl of `Into<[i32; 5]>` for `&mut [i32]`
  = note: required because of the requirements on the impl of `TryFrom<&mut [i32]>` for `[i32; 5]`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.

Is there any reason TryFrom<&mut '_ [T]> for [T; N] is not implemented though TryFrom<&'_ [T]> for [T; N] is implemented?

Since the implementation is lack, I needed to convert the mutable slice into immutable slice like below.

let s: &mut [T] = ...;
let a: [T; N] = (&*s).try_into().unwrap();

Meta

rustc --version --verbose:

rustc 1.56.1 (59eed8a2a 2021-11-01)
binary: rustc
commit-hash: 59eed8a2aac0230a8b53e89d4e99d55912ba6b35
commit-date: 2021-11-01
host: x86_64-apple-darwin
release: 1.56.1
LLVM version: 13.0.0
@rhysd rhysd added the C-bug Category: This is a bug. label Nov 20, 2021
@camelid camelid added A-array Area: `[T; N]` T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Nov 20, 2021
@scottmcm
Copy link
Member

To answer the historical reason: these implementations previously had to be generated with macros. See how ugly that made https://doc.rust-lang.org/1.14.0/std/primitive.array.html, for example. And all those impls actually slowed down compilation, so the easily-worked-around ones were omitted.

// NOTE: some less important impls are omitted to reduce code bloat
// __impl_slice_eq2! { [A; $N], &'b [B; $N] }
// __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }

Now that const generics exist, though, that problem has pretty much gone away, so filling out the matrix of conversions is more reasonable.

@bors bors closed this as completed in 42f8d48 Dec 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-array Area: `[T; N]` C-bug Category: This is a bug. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants