According the Rustonomicon, &mut T
is invariant over T
. How can the following code compile when &mut (str, str)
is not a subtype of &mut (T, T)
?
fn swap<T: Copy>(pair: &mut (T, T)) {
let temp = pair.0;
pair.0 = pair.1;
pair.1 = temp;
}
fn main() {
let mut pair = ("left", "right");
swap(&mut pair);
println!("{:?}", pair);
}
The relevant chapter is here
The Rustonomicon implies that you can call f: (T) -> U
on f(V)
only if V
is a subtype of T
. (4th code block, the example is evil_feeder(pet: &mut Animal)
being called with &mut Cat
). How can the above example compile if it's not a subtype?
It can compile because you are not using a &mut (str, str)
. What you have is an &mut (&'static str, &'static str)
. This is because string literals are references to the read-only memory where the actual string was stored in the executable.
It can fulfill the requirement of the function because even though str
does not implement Copy
, all immutable references implement Copy
.