Skip to content

Q019. How does Copy change assignment and move semantics?

Short Answer

When a type implements Copy, using its value in a move context implicitly creates another value instead of invalidating the source. Both places remain initialized and usable. The copy does not call Clone or other user code. It may still require machine instructions, although optimization can keep the value in registers or remove the copy entirely.

Deep Dive

Assignment, argument passing, returns, and pattern binding are normally move contexts. For a non-Copy type, reading a place by value moves from it. For a Copy type, the same expression copies the value and leaves the source initialized.

Copy is appropriate when implicit duplication has simple value semantics and requires no custom cleanup. Scalar values such as integers are independent after copying. Copying a shared reference or raw pointer duplicates the pointer value, however, so both copies can still refer to the same underlying data.

Copy changes language semantics, not storage guarantees. Rust does not promise that source and destination occupy distinct memory locations after optimization.

Internal Model

In rustc's intermediate representation, an operand can conceptually be a Move or a Copy from a place. Type information determines which operation is legal. A Copy operand does not mark the source place as moved from.

Code generation may lower the copy to loads and stores, register operations, or no instructions. There is no runtime call to the Copy trait because Copy is a marker trait with no methods.

Example

rust
#[derive(Clone, Copy)]
struct Point {
    x: i32,
    y: i32,
}

fn inspect(point: Point) {
    println!("{}, {}", point.x, point.y);
}

fn main() {
    let first = Point { x: 10, y: 20 };
    let second = first;

    inspect(first);
    inspect(second);
}

Common Mistakes

  • Saying a Copy use first moves the value and then restores the source.
  • Assuming Copy calls Clone::clone implicitly.
  • Assuming every copy creates a separate heap allocation or physical stack slot.

Follow-ups

  • What makes a type eligible to implement Copy?
  • Why is &T Copy while &mut T is not?
  • Can copying a large inline type be expensive?

References

  • The Rust Programming Language
  • Rust Reference
  • Rust Standard Library