Description
Problem statement
The primary use case for MaybeUninit
is to initialize arrays of stuff (typically u8s). This is currently poorly supported, requiring the user to enable unstable features (e.g. uninit_array
) or immediately mark an array as assume_init
which is very confusing to beginners.
Motivation, use-cases
let data = [MaybeUninit::<u8>::uninit(); 2048]; // This could instead be MaybeUninit::<[u8; 2048]>::uninit(), but now you need to use raw pointers to write the data
for ... {
data.write(...);
}
let data: [u8; 2048] = UH_OH;
UH_OH can be replaced with a transmute
(Requires unsafe. Also is that actually safe? It is, but no one wants to spend hours digging around to figure that out.) or with array_assume_init
(Requires nightly).
Having a From
implementation between [MaybeUninit<T>; N]
and MaybeUninit<[T; N]>
makes it easy to move between filling an uninitialized array and then marking it as initialized.
Solution sketches
Links and related work
Other proposals have suggested implementing Index{,Mut}
. While I think that's probably a slightly nicer API in its limited scope, users are very quickly going to be sad when they see that their favorite MaybeUninit
method isn't available on [MaybeUninit<T>; N]
. Eventually that will lead to API duplication as [MaybeUninit<T>; N]
methods are added to mirror the MaybeUninit
ones. [MaybeUninit<T>; N]
<-> MaybeUninit<[T; N]>
conversion avoids this entirely.