Assignment of references


#1

The Rust reference states:

When a local variable is used as an rvalue, the variable will be copied if its type implements Copy. All others are moved.

https://doc.rust-lang.org/reference.html#moved-and-copied-types

Therefore, the following code doesn’t compile:

fn main() {
    let mut a = 1;
    let x = &mut a;
    let y = x;
    x;
}

But why does the following code compile? Is the Clone trait implemented for shared references but not for mutable references? I cannot find any discussion of this in the Rust reference.

fn main() {
    let mut a = 1;
    let x = &a;
    let y = x;
    x;
}

#2

Sure, shared (immutable) references implement Copy and Clone, while unique (mutable) ones do not. See for yourself: https://is.gd/UxF3Vs


#3

Thanks. Is this implemented in the standard library (if so, where) or in the compiler?


#4

I believe it’s in the compiler, like most of the things that are related to primitive types.


#5

It would be nice to add this knowledge to the Book.:slight_smile:


#6

Also, the standard documentation doesn’t mention any primitive types in the list of Copy implementors.
Let’s cc @steveklabnik


#7

Every implementation of Clone is written out in the standard library. See https://doc.rust-lang.org/nightly/std/clone/trait.Clone.html for a complete list of those implementations. This is a link to the nightly documentation because the stable rustdoc apparently misses a bunch of implementations. See also https://github.com/rust-lang/rust/issues/24000 , where the lack of magic causes bugs.

Copy involves some compiler magic; https://github.com/rust-lang/rust/blob/12238b984abfacb2cccea176f862c94aa1231fb5/src/librustc/traits/select.rs#L1811 is where the magic happens. We could probably write out some of the implementations in the standard library so that rustdoc can see them. (We can’t write out all of them because there isn’t any way to write out “any array type where the element is Copy” or “any tuple type where the elements are Copy” or “any function definition type” or “any function pointer type”.)