My intuition must be wrong about moves and copies. I would expect the Rust compiler optimize away moves of an immutable value as a no-op. Since the value is immutable, we can safely reuse it after the move. But Rust 1.65.0 on Godbolt compiles to assembly that copies the value to a new position in memory. The Rust code that I am studying:
pub fn f_int() {
let x = 3;
let y = x;
println!("{}, {}", x, y);
}
The resulting assembly with -C opt-level=3
:
; pub fn f_int() {
sub rsp, 88
; let x = 3;
mov dword ptr [rsp], 3
; let y = x;
mov dword ptr [rsp + 4], 3
mov rax, rsp
...
Why does let y = x;
result in mov dword ptr [rsp + 4], 3
and mov rax, rsp
? Why doesn't the compiler treat y
as the same variable as x
in the assembly?
(This question looks similar but it is about strings which are not Copy. My question is about integers which are Copy. It looks like what I am describing is not a missed optimization opportunity but a fundamental mistake in my understanding.)