Copy
The Copy trait is a marker trait indicating that values of a type can be duplicated solely by copying bits in memory (memcpy), so assignment and passing by value copy the value instead of moving ownership.
Trait Definition
pub trait Copy: Clone {
// Empty marker trait — no methods
}
Because Copy has Clone as a supertrait (Copy: Clone), every type that implements Copy must also implement Clone.
Move Semantics vs. Copy Semantics
When a type does not implement Copy, assigning it to another variable moves ownership and invalidates the source binding. When a type implements Copy, assignment performs an implicit bitwise copy and both bindings remain valid:
#[derive(Debug, Clone, Copy)]
struct Point {
x: i32,
y: i32,
}
fn main() {
let p1 = Point { x: 10, y: 20 };
let p2 = p1; // Implicit bitwise copy; p1 remains valid
println!("p1 = {p1:?}, p2 = {p2:?}");
}
p1 = Point { x: 10, y: 20 }, p2 = Point { x: 10, y: 20 }
Which Types Can and Cannot Be Copy
A type can implement Copy only if every component of it implements Copy and the type does not implement Drop.
| Category | Implements Copy? |
Reason |
|---|---|---|
Integers, floats, bool, char |
Yes | Fixed-size stack scalars with no owned resources |
Shared references (&T) |
Yes (even if T is not Copy) |
Multiple shared references to the same target are allowed |
Mutable references (&mut T) |
No | Duplicating &mut T would violate the aliasing rule (two active mutable references) |
Arrays [T; N] and tuples (A, B) |
Yes, if all elements are Copy |
Contiguous bitwise-copyable values |
String, Vec<T>, Box<T> |
No | Own heap buffers; bitwise copying would cause a double free on drop |
Mutual Exclusion of Copy and Drop (E0184)
The compiler forbids implementing both Copy and Drop on the same type. If a type requires custom cleanup logic when it goes out of scope, duplicating it via a silent bitwise copy would cause both copies to run Drop::drop on the same underlying resource:
// ❌ does not compile
#[derive(Clone, Copy)]
struct FileDescriptor(i32);
impl Drop for FileDescriptor {
fn drop(&mut self) {}
}
fn main() {}
error[E0184]: the trait `Copy` cannot be implemented for this type; the type has a destructor
--> src/main.rs:2:17
|
2 | #[derive(Clone, Copy)]
| ^^^^ `Copy` not allowed on types with destructors
API Design Consideration
Implementing Copy on a public type is a stability commitment: removing Copy in a future version is a SemVer-breaking change because caller code relying on implicit copies will begin failing with use-after-move errors (E0382). Only implement Copy for small, plain-data value types that will never own heap allocations or handles.