I'm having an issue resolving an borrow issue. I think I understand the problem, but don't know how to resolve it.
I have a data store where I keep Thing
s. If a Thing
is loaded, I want to return a reference to it. If a Thing
is not yet loaded, I want to load it, store it, and return a reference to the newly loaded Thing
. This is where I run into the borrow issues because to store the thing I need a mutable borrow, but to return a reference I need an immutable borrow. However, because I return if the thing exists already , it feels like the first immutable borrow of self.store
should not overlap with the mutable borrow of it.
I tried to scope the different chunks of the function but it didn't help.
What am I misunderstanding the problem? Is there a canonical way to solve this?
Here is a minimal code example to demonstrate the issue, but please let me know if more context is required.
fn load_thing(&mut self, path: &Path) -> &Thing {
// check if already loaded
if let Some(thing) = self.store.get_thing(&path) { // immutable borrow of `self.store`
return Ok(thing);
}
// load thing
let thing = Thing::load(&path)?;
let _old_thing = self.store.insert_thing(thing)?; // mutable borrow of `self.store`
// get newly inserted thing
if let Some(thing) = self.store.get_thing(&path) { // immutable borrow of `self.store`
return Ok(thing);
}
Err(Error("thing could not be loaded"))
}