box $expr
is special because it has different semantics from Box::new($expr)
. Roughly,
// box $expr
let p = alloc(Layout::new::<typeof!($expr)>());
p.write($expr);
p
// Box::new($expr)
let tmp = $expr;
let p = alloc(Layout::new::<typeof!(tmp)>());
p.write(tmp);
p
This matters because of the order of the alloc
and evaluating $expr
; it's significantly easier for LLVM to convert the former to do move elision of tmp
from the latter.
But perhaps more relevant to that PR is compiler performance (rather than performance of the built binary). Introducing #[rustc_box]
requires an extra step from the compiler to recognize the attribute (potentially going through name resolution). The more the compiler needs to do the longer it'll take to do it.
Plus, compile perf is fundamentally opaque due to a lot of factors, with a big one being that small source changes can result in LLVM making drastically different optimization choices, and the impact of this is magnified for fundamental generic types due to them being monomorphized into and recompiled as part of every crate.