Closed
Description
Please see the assembly from these functions (Rust 1.85.0 --release
):
use std::mem::MaybeUninit;
pub struct SmallVec<T> {
pub len: usize,
pub arr: [MaybeUninit<T>; 24],
}
#[unsafe(no_mangle)]
pub fn uninit_arr_via_const() -> SmallVec<String> {
SmallVec { len: 0, arr: [const { MaybeUninit::uninit() }; 24] }
}
#[unsafe(no_mangle)]
pub fn uninit_arr_via_assume_init() -> SmallVec<String> {
SmallVec { len: 0, arr: unsafe { MaybeUninit::uninit().assume_init() } }
}
uninit_arr_via_const:
pushq %rbx
movq %rdi, %rbx
movl $584, %edx
xorl %esi, %esi
callq *memset@GOTPCREL(%rip)
movq %rbx, %rax
popq %rbx
retq
uninit_arr_via_assume_init:
movq %rdi, %rax
movq $0, 576(%rdi)
retq
The const {}
variant compiles with code that seems to zero-out the arr
field. This should not be necessary and the other version (correctly) only initializes the len
field.
This is particularly troublesome because the documentation in multiple places expresses that const-blocks are the preferred way to create a [MaybeUnint; _]
.