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?