I'm not able to borrow where I thought I could. I reduced the problem down to this case:
struct A<'a> {
borrow: &'a mut u8,
}
fn does_nothing<'b, 'c>(a: &'b mut A<'c>) {
a.borrow = a.borrow;
}
error[E0623]: lifetime mismatch
--> src/lib.rs:6:16
|
5 | fn does_nothing<'b, 'c>(a: &'b mut A<'c>) {
| -------------
| |
| these two types are declared with different lifetimes...
6 | a.borrow = a.borrow;
| ^^^^^^^^ ...but data from `a` flows into `a` here
It seems that a.borrow
has the intersection of 'b
and 'c
and therefore cannot be guaranteed to still have the lifetime 'c
.
I don't have any real problem with this and can work around it by making both lifetimes the same, but why this does not borrow check?
It seems structs are unimportant to showing this issue and double borrows show it easily.
I have three functions which are pretty similar, but I would have trouble knowing which one compiles and which error the non-compiling ones would give.
The simple generic function:
fn only_borrow<T>(a: &mut T) {
*a = *a;
}
results in the error:
error[E0507]: cannot move out of `*a` which is behind a mutable reference
--> src/lib.rs:2:10
|
2 | *a = *a;
| ^^ move occurs because `*a` has type `T`, which does not implement the `Copy` trait
Including an extra level of indirection changes the error
fn only_borrow_double<T>(a: &mut &mut T) {
*a = *a;
}
error[E0623]: lifetime mismatch
--> src/lib.rs:2:10
|
1 | fn only_borrow_double<T>(a: &mut &mut T) {
| -----------
| |
| these two types are declared with different lifetimes...
2 | *a = *a;
| ^^ ...but data from `a` flows into `a` here
Changing away from the implied lifetimes can fix the error:
fn working_double<'b, T>(a: &'b mut &'b mut T) {
*a = *a;
}