Hello there,
As far as I understand, borrow checker adds lifetimes to references to maintain the absence of multiple coexisting (im)mutable references. But I can't understand the following example:
struct A {
}
fn foo(a: &A, b: usize) {
}
fn bar(a: &mut A) -> usize {
0
}
fn main() {
let mut a = A{};
foo(&a, bar(&mut a))
}
There I get following compile time error:
error[E0502]: cannot borrow `a` as mutable because it is also borrowed as immutable
--> src/main.rs:16:17
|
16 | foo(&a, bar(&mut a))
| --- -- ^^^^^^ mutable borrow occurs here
| | |
| | immutable borrow occurs here
| immutable borrow later used by call
For more information about this error, try `rustc --explain E0502`.
warning: `playground` (bin "playground") generated 3 warnings
error: could not compile `playground` (bin "playground") due to 1 previous error; 3 warnings emitted
The lifetime of the inner mutable reference is bounded by bar(..) call expression and the lifetime of the immutable reference is bounded by foo(...) call expression.
If we assume that the evaluation order for call expressions is eager then we call bar(...), and then call foo(...), getting that the lifetimes of these references don't overlap in runtime.
So the following example compiles correctly:
struct A {
}
fn foo(a: &A, b: usize) {
}
fn bar(a: &mut A) -> usize {
0
}
fn main() {
let mut a = A{};
let c = bar(&mut a);
foo(&a, c)
}
Can you explain, why the first snippet is incorrect?