简体   繁体   中英

mem::transmute error when bounded to const N

I do not understand why wouldn't the compiler let this example compile:


use std::mem::{self, MaybeUninit};


fn foo<const N: usize>() -> [u32; N] {
    let mut res: [MaybeUninit<u32>; N] = unsafe { MaybeUninit::uninit().assume_init() };

    for elem in &mut res[..] {
        unsafe { elem.as_mut_ptr().write(0) };
    }

    unsafe { mem::transmute::<[MaybeUninit<u32>; N], [u32; N]>(res) }
}
Compiling playground v0.0.1 (/playground)
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
  --> src/lib.rs:11:14
   |
11 |     unsafe { mem::transmute::<[MaybeUninit<u32>; N], [u32; N]>(res) }
   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: source type: `[MaybeUninit<u32>; N]` (this type does not have a fixed size)
   = note: target type: `[u32; N]` (this type does not have a fixed size)

error: aborting due to previous error

It is clearly that N is the same for both result and input array. Is there anyway of achieving this?

Playground

It's a compiler limitation. They're indeed the same size, but the compiler is not able to see that (yet?).

You can use raw pointer casts to achieve this, because the compiler doesn't check the sizes are equal:

use std::mem::{self, MaybeUninit};

fn foo<const N: usize>() -> [u32; N] {
    let mut res: [MaybeUninit<u32>; N] = unsafe { MaybeUninit::uninit().assume_init() };

    for elem in &mut res[..] {
        unsafe { elem.as_mut_ptr().write(0) };
    }

    unsafe { *(&res as *const [MaybeUninit<u32>; N] as *const [u32;N] ) }
}

Alternatively there's array_assume_init , still unstable so nightly-only though.

#![feature(maybe_uninit_array_assume_init)]

use std::mem::{self, MaybeUninit};

fn foo<const N: usize>() -> [u32; N] {
    let mut res: [MaybeUninit<u32>; N] = unsafe { MaybeUninit::uninit().assume_init() };

    for elem in &mut res[..] {
        unsafe { elem.as_mut_ptr().write(0) };
    }

    unsafe { MaybeUninit::array_assume_init(res) }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM