10

I'm looking for the document about copy/move semantics of reference and mutable reference types.

The following code snippet shows immutable references (& T) implement the Copy trait and mutable references (&mut T) do not.

struct T;
fn copyable<U>(_: U) where U: Copy {}

fn main() {
    let a = &T;
    copyable(a);  // OK

    let b = &mut T;
    copyable(b);
    // error: the trait `core::marker::Copy` is not implemented for the type `&mut T`
}

But I can't find the description of this behavior. Someone know some (un)official documents? (or am I wrong?)

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
yohjp
  • 2,985
  • 3
  • 30
  • 100
  • 2
    Being able to copy a mutable reference would infer that you can have multiple mutable references to the same object at the same time in Rust... when you can't. – Simon Whitehead May 23 '16 at 01:05
  • Thanks for your comment. Why they behave is understandable, and I'm looking for some documented resources. – yohjp May 23 '16 at 02:50
  • 2
    See this issue about rustdoc not showing `Copy` impls for builtin types: https://github.com/rust-lang/rust/issues/25893 – oli_obk May 23 '16 at 08:48
  • 5
    The [documentation for Copy](https://doc.rust-lang.org/std/marker/trait.Copy.html) mentions `&mut T` not being `Copy`. – Chris Emerson May 23 '16 at 11:03

2 Answers2

4

Rust's std::marker::Copy trait reference says (thanks to @Chris Emerson):

When can my type not be Copy?
Some types can't be copied safely. For example, copying &mut T would create an aliased mutable reference, and copying String would result in two attempts to free the same buffer.
[...]

Community
  • 1
  • 1
yohjp
  • 2,985
  • 3
  • 30
  • 100
  • 1
    This link became [When can't my type be Copy?](https://doc.rust-lang.org/std/marker/trait.Copy.html#when-cant-my-type-be-copy). – Ta Thanh Dinh Oct 08 '19 at 00:00
4

As an addition to your code, you can always ask the compiler to tell you if a type can be copied, even without being able to construct that type:

fn is_this_type_copy<T: Copy>() {}

fn main() {
    is_this_type_copy::<&u8>();
}

If a type does not implement Copy, the compiler will produce an error.

You can extend this to ask the question for every reference to a type. Your existing code only shows that an immutable reference to a specific type implements Copy:

fn is_every_reference_copy<T>() {
    is_this_copy::<&T>()
}

Doing the same thing for &mut T:

fn is_every_mut_reference_copy<T>() {
    is_this_copy::<&mut T>()
}

Produces the same error you saw:

error[E0277]: the trait bound `&mut T: std::marker::Copy` is not satisfied
 --> src/main.rs:8:5
  |
8 |     is_this_copy::<&mut T>()
  |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `&mut T`
  |
  = note: required by `is_this_copy`

We've already seen why &mut T cannot be copied, but why can &T be copied? In a way, that's kind of the entire point of a reference. A reference is a way of cheaply sharing data. Instead of needing to clone (potentially expensively) something to give to multiple things, we can simply give each thing a lightweight reference to the original thing. If references couldn't be copied, they wouldn't have nearly the same amount of value.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366