Beginners can be confused when deref and deref_mut are called implicitely:
In this given code:
struct Foo {
a: Vec<i32>,
b: Vec<i32>,
}
fn add(foo: std::sync::Mutex<Foo>) {
let f = foo.lock().unwrap();
for i in &mut f.a {
for j in &f.b {
*i += *j;
}
}
}
The error message is not the clearest:
error[E0502]: cannot borrow `f` as immutable because it is also borrowed as mutable
--> src/lib.rs:10:19
|
9 | for i in &mut f.a {
| --------
| | |
| | mutable borrow occurs here
| mutable borrow used here, in later iteration of loop
10 | for j in &f.b {
| ^ immutable borrow occurs here
The users could not understand that the borrows are done by deref and deref_mut, since the calls are implicit. They could think that, for an unknown reason, the borrow checker does not understand that the fields are disjoint.
I think that it would be an improvement if the compiler added that the implicit call to deref/deref_mut is responsible of the borrowing:
error[E0502]: cannot borrow `f` as immutable because it is also borrowed as mutable
--> src/lib.rs:10:19
|
9 | for i in &mut f.a {
| --------
| | |
| | mutable borrow occurs here due to a call to `Deref::deref`
| mutable borrow used here, in later iteration of loop
10 | for j in &f.b {
| ^ immutable borrow occurs here due to a call to `DerefMut::deref_mut`
This could be even better if the compiler gave the solution:
You can call `DerefMut::deref_mut` before borrowing the fields:
--> src/lib.rs:8:1
7 | let mut f = foo.lock().unwrap();
| let f = DerefMut::deref_mut(&mut f);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Beginners can be confused when
derefandderef_mutare called implicitely:In this given code:
The error message is not the clearest:
The users could not understand that the borrows are done by
derefandderef_mut, since the calls are implicit. They could think that, for an unknown reason, the borrow checker does not understand that the fields are disjoint.I think that it would be an improvement if the compiler added that the implicit call to
deref/deref_mutis responsible of the borrowing:This could be even better if the compiler gave the solution: