src/unsafe-deep-dive/pinning/what-a-move-is.md
Always a bitwise copy, even for types that do not implement Copy:
# // Copyright 2026 Google LLC
# // SPDX-License-Identifier: Apache-2.0
#
#[derive(Debug, Default)]
pub struct DynamicBuffer {
data: Vec<u8>,
position: usize,
};
pub fn move_and_inspect(x: DynamicBuffer) { println!("{x:?}"); }
pub fn main() {
let a = DynamicBuffer::default();
let mut b = a;
b.data.push(b'R');
b.data.push(b'U');
b.data.push(b'S');
b.data.push(b'T');
move_and_inspect(b);
}
Generated LLVM IR for calling move_and_expect():
call void @llvm.memcpy.p0.p0.i64(ptr align 8 %_12, ptr align 8 %b, i64 32, i1 false)
invoke void @move_and_inspect(ptr align 8 %_12)
memcpy from variable %b to %_12move_and_inspect with %_12 (the copy)Note that DynamicBuffer does not implement Copy.
Implication: a value's memory address is not stable.
To show movement as a bitwise copy, either open the code in the playground and look at the or the Compiler Explorer.
Optional for those who prefer assembly output:
The Compiler Explorer is useful for discussing the generated assembly and focus
the cursor assembly output in the main function on lines 128-136 (should be
highlighted in pink).
Relevant code generated output move_and_inspect:
mov rax, qword ptr [rsp + 16]
mov qword ptr [rsp + 48], rax
mov rax, qword ptr [rsp + 24]
mov qword ptr [rsp + 56], rax
movups xmm0, xmmword ptr [rsp]
movaps xmmword ptr [rsp + 32], xmm0
lea rdi, [rsp + 32]
call qword ptr [rip + move_and_inspect@GOTPCREL]