I'm using Rust to build a POC for some optimizer. At some point, I'd like to cache data for performance reason. However, I ran into some puzzle with layers of references. Any suggestions will be greatly appreciated. I tried to clean up code as much as possible as follow. Rust playground "share" just spins forever, so no link yet. Link to playground Rust Playground
use core::cell::RefCell;
use std::rc::Rc;
use std::collections::HashSet;
struct Dao {
d1: usize,
}
impl Dao {
fn capabilities(&self) -> Capabilities {
Capabilities{ d1: &self.d1 }
}
}
#[derive(PartialEq, Eq, Hash)]
struct Capabilities<'a> {
d1: &'a usize
}
struct CompositeDao<'a> {
dao: Dao,
cache: RefCell<HashSet<Rc<Capabilities<'a>>>>
}
impl<'a> CompositeDao<'a> {
fn new(dao: Dao) -> Self {
Self { dao, cache: RefCell::new(Default::default()) }
}
fn capabilities<'s: 'a>(&'s self) -> Rc<Capabilities<'a>> {
self.cache.borrow_mut().insert(Rc::new(self.flow_capabilities()));
self.cache.borrow().iter().next().unwrap().clone()
}
fn flow_capabilities(&self) -> Capabilities {
self.dao.capabilities()
}
}
struct Solver<'d, 'df: 'd> {
dao: &'df mut CompositeDao<'d>,
}
struct Goal<'d, 'df: 'd> {
dao: &'df CompositeDao<'d>,
}
impl<'d, 'df: 'd> Goal<'d, 'df> {
fn new(dao: &'df CompositeDao<'d>) -> Self {
Self { dao }
}
fn solve(&self) {
let caps = self.dao.capabilities();
unimplemented!()
}
}
impl<'d, 'df: 'd> Solver<'d, 'df> {
fn solve<'s: 'df>(&'s mut self) {
{
let mut goal = Goal::new(self.dao);
goal.solve();
}
self.persist();
}
fn persist(&mut self) {
unimplemented!()
}
}
The following is error message:
--> src/lib.rs:61:11
|
61 | let mut goal = Goal::new(self.dao);
| ----^^^^
| |
| help: remove this `mut`
|
= note: `#[warn(unused_mut)]` on by default
error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable
--> src/lib.rs:65:9
|
61 | let mut goal = Goal::new(self.dao);
| -------- immutable borrow occurs here
...
65 | self.persist();
| ^^^^^-------^^
| | |
| | immutable borrow later used by call
| mutable borrow occurs here
error: aborting due to previous error
Another version of this is without lifetime bound 's: 'df for solve method. However, that led to another error like "conflict lifetime". I don't feel bound 's: 'df is appropriate given that feels self-conflicting.