I want to write the following function:
fn foo<'a, 'b, 'c>(rr1: &'a mut &'c mut u32, rr2: &'b mut &'c mut u32) {
*rr1 = *rr2;
}
But the compiler complains:
error[E0623]: lifetime mismatch
--> src/lib.rs:2:12
|
1 | fn foo<'a, 'b, 'c>(rr1: &'a mut &'c mut u32, rr2: &'b mut &'c mut u32) {
| ----------- ------------------- these two types are declared with different lifetimes...
2 | *rr1 = *rr2;
| ^^^^ ...but data from `rr2` flows into `rr1` here
My mental model of Rust's lifetimes does not agree that the code is wrong. I read the type of rr2 as "A reference with lifetime 'b to a reference with lifetime 'c to an u32". Thus when I dereference rr2, I get a reference with lifetime 'c to an u32. This should be safe to store in *rr1, which has the same type.
If I require that 'b outlives 'c, it works:
fn foo<'a, 'b: 'c, 'c>(rr1: &'a mut &'c mut u32, rr2: &'b mut &'c mut u32) {
*rr1 = *rr2;
}
This makes me think that the type &'b mut &'c mut u32 means the u32 at the end of the reference chain is only available during the intersection of 'b and 'c.
What is the right explanation for Rust's behavior here? And why do references of references behave this way instead of the way I thought they do?