Currently the Box type has the methods Box::new_uninit_slice(len: usize) and Box::new_zeroed_slice(len: usize), which create Box<[MaybeUninit<T>]> with uninitialized and zeroed memory respectively.
I propose the creation of Box::new_uninit_array() and Box::new_zeroed_array(), which create Box<[MaybeUninit<T>; N]>, which create fixed-size arrays on the heap with a compile time size.
One example from my current use case (an I/O buffer):
To my knowledge, the only way to do this currently is:
Box::new_uninit_slice(N).into_array().unwrap()
...which is both unstable and somewhat unsightly in my opinion with an unwrap from an unnecessary runtime check.
I would love to take a shot at making a PR myself, but I thought I should post here first before I did anything, I'm not sure of the exact process as this would be my first contribution to Rust. If anyone here has any objections or pointers please let me know.
Because arrays are Sized, we can use the existing new_uninit/new_zeroed to get the right allocation for this…but I don't see a good way to then reinterpret the MaybeUninit to be elementwise. MaybeUninit::transpose does exist (unstably), but it doesn't apply to Boxed arrays. Still, I think that might be a better missing piece to add, rather than new top-level factory methods.
Another alternative is Box::new([MaybeUninit::zeroed(); N]), but then you're trusting the optimizer to eliminate the intermediate copy. So I see the motivation for something here.
Implementing transpose() on Box<MaybeUninit<[T; N]>> did also cross my mind, not sure why I dismissed the idea to be honest. Sounds perfectly reasonable to me.
On another note, someone in the Rust Discord pointed me to this, which works, but it's unsafe, which is clearly not ideal.
let data = unsafe { Box::new_uninit().assume_init() };
@pitaj
Using TryFrom adds a .unwrap() to the code, which shouldn't be needed (see original post). .unwrap() is also generally considered bad practice in general, and I feel like I shouldn't need one here.
unwrap is not considered bad practice in general, and is required for things like the recommended usize <-> uN conversion method as well. In cases where it can never fail, unwrap is totally fine and the check can be trivially optimized out.