Is this form of interior mutability safe?

I have a doubt about a case of implementing interior mutability and whether it is in fact safe. If a struct A provides closure-controlled access to the aliasing and mutability of a T value, is it safe? Follow the pseudo code.

struct A<T> {
    cell: UnsafeCell<T>,
}

impl A {
...

pub fn mutate<M: FnMut(&mut T)>(&self, mut mutator: M) {
    let inner = unsafe { &mut *self.cell.get() };
    mutator(inner);
}

pub fn access<A: Fn(&T)>(&self, accessor: A) {
    let inner = unsafe { &*self.cell.get() };
    accessor(inner);
}
}

this struct does not allow in any way to obtain a reference to the value beyond the described methods.

Any closures passed as mutator could itself call mutate, which would make two &muts alive at once.

1 Like

hmm... if reentrance were somehow prevented, would it still be unsafe otherwise?

Yes, assuming it is !Sync (if it was Sync you would have to treat concurrent access like reentrance).

Though the only way I can see that working is if you were to reimplement RefCell with a worse API surface.

1 Like

"references" can't really meaningfully be prevented here. Some important cases to consider include &'static A and Arc<A>, which you can't generally prevent users from creating if they have an A.

1 Like

Reading a bit of refcell's code I understood how they control aliasing and mutability through the guard. The way described by me would never work correctly.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.