[MaybeUninit<T>] and clone_from_slice not compiling

Hi everyone,

I've encountered this issue in which I can't call clone_from_slice on a slice of MaybeUninit<T>s, on account of:

the trait Copy is not implemented for TestStruct, which is required by `MaybeUninit: Clone

I've created a sample playground that reproduces my issue here.

I'm hesitating to require a Copy bound for TestStruct or any T because I don't want to make assumptions about the library usage.

I'm clearly misunderstanding something, and would love your feedback and insight!

Thanks in advance!

MaybeUninit<T> is only Clone if T is Copy, because the only possible implementation of Clone for MaybeUninit is to just copy all the bytes. It cannot call clone() on T because it might be uninitialized.

In your example, TestStruct contains a Box: cloning a MaybeUninit<TestStruct> safely is impossible, because if the box is initialized then just doing a bytewise copy means you have two boxes pointing at the same allocation (so it's not possible to just copy it), and if the box isn't initialized then trying to clone it will access uninitialized memory (so it's not possible to call clone either).

3 Likes

Your example doesn't need MaybeUninit.

let mut buffer: Vec<TestStruct> = Vec::with_capacity(16);

let mut src: Vec<TestStruct> = Vec::with_capacity(4);
for i in 0..4 {
    src.push(TestStruct {
        data: i,
        key: i,
        value: vec![i + 1; i + 1].into_boxed_slice(),
    });
}

buffer.extend_from_slice(&src);

for i in 0..4 {
    println!("{:?}", buffer[i]);
}

This is the same except it compiles, and it'll actually drop the first 4 items so you don't leak memory.

3 Likes
- buffer[0..4].clone_from_slice(&src);
+ for (dst, src) in buffer[0..4].iter_mut().zip(&src) {
+     unsafe {
+         dst.write(src.assume_init_ref().clone());
+     }
+ }

That said, I agree with above suggestion to simply avoid using unsafe and MaybeUninit in the first place here.

1 Like

Thank you all!

I understand we generally avoid unsafe when we can, but this is a personal experiment with it.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.