= note: source type: `[MaybeUninit<T>; N]` (this type does not have a fixed size)
= note: target type: `[T; N]` (this type does not have a fixed size)
The example code is from the "init array element-by-element" example from MaybeUninit in std::mem - Rust but for some reason, I can not use the last line (transmute) w/ a generic T ?
DutchGhost:
Transmuting a MaybeUninit<T> to T is already rejected, and thus transmuting from any wrapper containing a MaybeUninit<T> to a Wrapper<T> is also rejected.
Yes, [MaybeUninit<T>; N] to [T; N]should be okey, but Option<MaybeUninit<T>> to Option<T> isnt in all cases.
The ManuallyDrop::new() technically does add a copy/move, but it will almost certainly be removed by the optimizer.
transmute_copy itself isn't any worse than transmute, though. It takes a reference as its argument and then copies from behind that reference whereas transmute requires the argument to be moved in the first place— The only real performance difference is whether the memcpy happens before or inside the transmute* call.
// Using &mut as an assertion of unique "ownership"
let ptr = &mut arr as *mut _ as *mut [T; N];
let res = unsafe { ptr.read() };
core::mem::forget(arr);
res
@2e71828 : Are you saying that all 3 solutions (transmute, transmute_copy, ptr manip) involve 1 copy/move. I.e. the pointer manip solution does the "copy" at the ptr.read() line ?
Yes, unless I'm missing one somewhere— A move operation is equivalent to copy+forget, so I'd be very surprised if these solutions didn't all end up compiling to the exact same machine code (especially with optimizations turned on).