Actually, I got curious and tried it out. Turns out Rust didn't optimize the heap case: it used the caller's stack, and only then copied the value to the heap.
Because it would change the semantics of the program. Where heap allocations happen is considered a side effect, and forcing a function to be inline(never) also makes it have unconstrained side effects (in some cases). Those side effects cannot be reordered.
https://play.rust-lang.org/?code=%23!%5Bfeature(core)%5D%0A%...