Initialize array of arrays from iterator

Viewed 380

I'm trying to initialize an array of arrays from an iterator using const generics. The following code serves as an example:

pub fn foo<const R: usize, const C: usize>(iter: Iter<i32>) -> [[i32; C]; R] {
    let mut res: [[MaybeUninit<i32>; C]; R] = unsafe { MaybeUninit::uninit().assume_init() };
    let mut counter = 0;
    res.iter_mut().flatten().zip(iter).for_each(|(r, l)| {
        *r = MaybeUninit::new(*l);
        counter += 1;
    });
    assert_eq!(counter, R * C);
    unsafe { transmute::<_, [[i32; C]; R]>(res) }
}

However, I'm getting the error:

error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
  --> src\main.rs:14:14
   |
14 |     unsafe { transmute::<_, [[i32; C]; R]>(res) }
   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: source type: `[[MaybeUninit<i32>; C]; R]` (this type does not have a fixed size)
   = note: target type: `[[i32; C]; R]` (this type does not have a fixed size)

Both types clearly have a fixed size, so i'm not understanding this error...

If I use this code with specific values in the program it works:

    let iter = (0..4);

    let res = {
        let mut res: [[MaybeUninit<i32>; 2]; 2] = unsafe { MaybeUninit::uninit().assume_init() };
        res.iter_mut().flatten().zip(iter).for_each(|(r, l)| {
            *r = MaybeUninit::new(l);
        });
        unsafe { transmute::<_, [[i32; 2]; 2]>(res) }
    };

    println!("{:?}", res);   //[[0, 1], [2, 3]]

Is this some bug with const generics or am I doing something wrong??

0 Answers
Related