Currently vec![val; len]
uses from_elem
which by default places clones into the heap directly one by one (pre-optimization). And it's also specialized for a few cases to e.g. just allocate zeroed memory or use memset
.
The box_new
intrinsic is what is also used by Box::new
. Though vec!
is more amenable to optimization on unoptimized builds, apparently.
More implementation details, but here's what box_new
eventually becomes currently, before being turned into some sort of LLVM IR. exchange_malloc
is just an allocation now I guess. So it allocates some memory and does a move into the allocation. The data being moved can still end up on the stack before the move (especially with no optimizations).
There is a lack of magic -- no guarantee that the stack isn't used -- even when optimizations are enabled. box
syntax was supposed to do that, but it wasn't actually guaranteed, so it was scrapped. box_new
is what remains of that attempt. Another attempt at emplacement has yet to emerge. So when you don't get the stack usage, it's due to optimizations, not guaranteed magic.
You could use vec![CONST; LEN].into()
instead of Box::new([CONST; LEN])
specifically. There's no guarantee that will continue to act like it does today AFAIK, but it seems unlikely that it would be changed to start using lots of stack.