I have a struct which owns a data structure and a strategy to manipulate that data. In code this looks like this:
trait MyStrategy<T> {
fn do_something(&mut self, data: &mut T);
}
struct Foo<T, B: MyStrategy<T>> {
data: T,
strat: B,
}
impl<T, B: MyStrategy<T>> Foo<T, B> {
fn get_data(&mut self) -> &mut T {
&mut self.data
}
fn do_something(&mut self) {
let data = self.get_data();
self.strat.do_something(data);
// error[E0499]: cannot borrow `self.strat` as mutable more than once at a time
}
}
Simply inlining get_data
makes everything work again.
fn do_something(&mut self) {
self.behavior.do_something(&mut self.data);
// no problem but only possible because this is a simplified example
}
What can I do to tell the borrow checker what's going on?
I'm pretty new to Rust (3-days-new) but I think the reason the inlined version works is because Rust is able to see that I'm using disjoint parts of the struct, so it can basically treat self.behavior
and self.data
as two distinct variables. Rust is totally ok with two distinct &mut
variables, so everything works. But when I use the getter, Rust only sees two uses of &mut self
and that's a big no-no.
I guess one possible solution is to wrap data: T
into its own struct and have my getter logic (and some more) there. However, this makes composition a lot more tedious to use. So is there some way to tell Rust: "Hey, I'm only using some (== not all) fields in this method"?