17

Do all primitive types in Rust implement the Copy trait?

It would be interesting to know, as surely such knowledge is part of a thorough learning of a new programming language.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
D. Ataro
  • 1,711
  • 17
  • 38

1 Answers1

37

We can use the compiler to prove if something implements Copy. Using the list of primitives from The Rust Programming Language:

fn is_copy<T: Copy>() {}

fn main() {
    is_copy::<bool>();
    is_copy::<char>();
    is_copy::<i8>();
    is_copy::<i16>();
    is_copy::<i32>();
    is_copy::<i64>();
    is_copy::<u8>();
    is_copy::<u16>();
    is_copy::<u32>();
    is_copy::<u64>();
    is_copy::<isize>();
    is_copy::<usize>();
    is_copy::<f32>();
    is_copy::<f64>();
    is_copy::<fn()>();
}

There are a few other types I'd consider "primitive":

  • Immutable references (&T)
  • Mutable references (&mut T)
  • Raw pointers (*const T / *mut T)

Immutable references always implement Copy, mutable references never implement Copy, and raw pointers always implement Copy:

// OK
is_copy::<&String>();
is_copy::<*const String>();
is_copy::<*mut String>();
// Not OK
is_copy::<&mut i32>();

There are a few other types from the book's list:

  • Tuples
  • Arrays

These types can contain many types; they are parameterized over a generic. They are only Copy if all the contained values are Copy:

// OK
is_copy::<[i32; 1]>();
is_copy::<(i32, i32)>();
// Not OK
is_copy::<[Vec<i32>; 1]>();
is_copy::<(Vec<i32>, Vec<i32>)>();
  • Slices

Slices are doubly special. The slice type itself ([T]) and string slices (str) are unsized types. It's very rare to see them without an indirection of some kind, often a reference (&[T] / &str). The unsized values cannot exist by themselves. The version behind a reference behaves like references do.

// OK
is_copy::<&str>();
is_copy::<&[i32]>();
// Not OK
is_copy::<str>();
is_copy::<[i32]>();

And as always, the documentation for a trait lists everything that implements that trait. (Except when there are bugs in the documentation).

E_net4
  • 27,810
  • 13
  • 101
  • 139
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • 2
    I don't see primitive types (e.g. https://doc.rust-lang.org/std/primitive.i64.html) listed in https://doc.rust-lang.org/std/marker/trait.Copy.html, am I missing something? – ArtemGr Jan 01 '17 at 13:16
  • 3
    @ArtemGr guh, I really thought that had been fixed by now. I linked to the issue for that. – Shepmaster Jan 01 '17 at 15:02
  • But slices (those of the form `&[T]`, not the plain unsized `[T]`), are just references, thus they are always `Copy`. I mean, your last example, once you add a type for the `Vec` generic) actually works: `is_copy(&[Vec::::new()][..]);`. – rodrigo Aug 21 '19 at 16:28
  • @rodrigo odd, wonder how I missed that. I've rectified that and added a section about references. – Shepmaster Aug 21 '19 at 16:52
  • @Shepmaster Typo here: "Immutable references always implement Copy, immutable references never implement Copy" :) – joe Aug 21 '19 at 16:59