Why the following code compiles:
struct U2 { index: usize }
struct U { ulist: Vec<U2> }
struct V2 { value: u8 }
struct V { vlist: Vec<V2> }
struct UV { u: U, v: V }
impl V2 {
fn bar(&mut self) {
self.value = 42;
}
}
impl UV {
fn foo(&mut self) {
for u2 in &self.u.ulist {
let v2 = &mut self.v.vlist[u2.index];
v2.bar();
}
}
}
Whereas the following one, exactly the same as the previous code except for the line self.v.vlist[u2.index]
which has been extracted to a function, does not:
struct A2 { index: usize }
struct A { alist: Vec<A2> }
struct B2 { value: u8 }
struct B { blist: Vec<B2> }
struct AB { a: A, b: B }
impl B2 {
fn bar(&mut self) {
self.value = 42;
}
}
impl AB {
// New function
fn get_b(&mut self, a2: &A2) -> &mut B2 {
&mut self.b.blist[a2.index]
}
fn foo(&mut self) {
for a2 in &self.a.alist {
let b2 = self.get_b(a2);
// error[E0502]: cannot borrow `*self` as mutable
// because it is also borrowed as immutable
b2.bar();
}
}
}
I'm new to Rust, so excuse me in advance for my bliss ignorance, but this difference makes me mad, and I cannot see how to code this cleanly.
Edit
I've solved my issue on borrowing only part of self (self.b
), by using the following function:
// ... (snip) ...
impl AB {
fn get_b<'a, 'b>(b: &'b mut B, a2: &'a A2) -> &'b mut B2 {
&mut b.blist[a2.index]
}
fn foo(&mut self) {
for a2 in &self.a.alist {
let b2 = AB::get_b(&mut self.b, a2);
b2.bar();
}
}
}
Is this proper rust?