I am match
ing on a struct and would like to use a match guard. However, the struct is mutable, and binding variables on the left side of the match arm seems to cause a separate borrow. This then triggers compilation errors, since you can't have a second borrow (mutable or immutable) while the mutable borrow is outstanding.
struct A(u8);
impl A {
fn is_awesome(&self) -> bool { true }
}
struct Container(A);
impl Container {
fn update(&mut self) {}
fn do_a_thing(&mut self) {
match *self {
Container(ref a) if a.is_awesome() => self.update(),
_ => {},
}
}
}
fn main() {}
error[E0502]: cannot borrow `*self` as mutable because `self.0` is also borrowed as immutable
--> src/main.rs:14:51
|
14 | Container(ref a) if a.is_awesome() => self.update(),
| ----- ^^^^ mutable borrow occurs here
| |
| immutable borrow occurs here
15 | _ => {},
16 | }
| - immutable borrow ends here
My current workaround is to duplicate the logic to compute the match guard before my match, then I can just use the boolean as my match guard. This is not satisfying for the obvious code duplication issues:
fn do_a_thing(&mut self) {
let awesome = match *self {
Container(ref a) => a.is_awesome(),
};
match *self {
Container(..) if awesome => self.update(),
_ => {},
}
}