An ordinary mutable reference must have exclusive access to the value it points at, but this is violated in your code as the read_callback also has access. To obtain mutable shared access, you must use what is known as interior mutability. One way to do it is the following:
use std::cell::RefCell;
struct CPU<'a, 'b> {
reg: Vec<u8>,
read_callback: Box<dyn 'a + Fn(u8) -> u8>,
write_callback: Box<dyn 'b + FnMut(u8, u8)>
}
struct Memory {
ram: RefCell<Vec<u8>>,
}
impl Memory {
pub fn get(&self, i: usize) -> u8 {
self.ram.borrow()[i]
}
pub fn set(&self, i: usize, val: u8) {
self.ram.borrow_mut()[i] = val;
}
}
fn main() {
let mem = Memory {ram: RefCell::new(vec![0; 256])};
let mut cpu = CPU {
reg: vec![0; 4],
read_callback: Box::new(|address| mem.get(address as usize)),
write_callback: Box::new(|address, data| {mem.set(address as usize, data);})
};
cpu.read_callback.as_ref()(1);
cpu.write_callback.as_mut()(1,1);
}
This uses a shared reference instead of an unique reference, but RefCell guarantees that Memory is not accessed from multiple threads at the same time, which makes shared mutation safe.