The key thing to understand is that in Rust, references are considered unique types. This means that &T
is a separate type from T
.
So, for #1, it is not saying that T
implements Copy
, it is saying that regardless of what T
is, &T
implements Copy
. This is because, by definition, it is always valid to copy a shared reference, even if T
itself is not Copy
.
Part of the reason this is confusing is that traits often include references in their function signatures; and in particular, Clone::clone
has the signature fn clone(&self) -> Self
. So when T
implements clone
, it has a method that takes &T
and returns T
. But even though the signature takes &T
, the type that implements Clone
is T
itself. (&T
always implements Clone
as well, just as it always implements Copy
, but as with Copy
, this is independent from whether T
itself implements Clone
. See for example the error message you get when explicitly cloning a shared reference: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=a1b80cc83570321868c4ad55ee3353dc)
Since Copy
is a marker trait, it doesn't have any associated methods making it explicit that Copy
affects how &T
can be used. However, Copy
requires the type to implement Clone
(even though you can implement Clone
in terms of Copy
) and implies that T
can always be automatically created from &T
without an explicit call to T::clone
, so you can think of the "signature" for Copy
as matching that of Clone
, even though there's no actual copy
method.
For #2, I recommend thinking in terms of explicit types. Adding annotations, you get:
let mut x: Box = Box::new(42); *x = 84_i32;
The type of x
is Box
. You cannot assign an i32
to a Box
; they're different types! But the type of *x
is i32
, and thus you can assign 84
to it.
The trait used to make Box
behave this way is DerefMut
, which explicitly makes *x
assignable: https://doc.rust-lang.org/std/ops/trait.DerefMut.html