Search code examples
rusttype-theory

Covariant Types


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?


Solution

  • 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.