Mark function as mutable when using interior mutability?

I have a struct which owns a Rc<RefCell>

Should methods of this struct take &mut self when they borrow_mut() its contents?

Technically it's not required, the compiler won't complain if it's &self, but I'm thinking it's good practice to mark it &mut self so that bugs of borrow_mut() can be caught at compile-time (even though they'll be really checked at runtime)...

You can do that, but it will restrict how users can call the method, because they can have several references of your struct, OR only one mutable one.

It's hard to tell without knowing more about the design. Why are you using interior mutability if you don't need to be able to operate on a &self?

1 Like

If they have several references, wouldn't calling this method in a way that &self allows (i.e. multiple times in the same block) break things since it's calling borrow_mut() internally?

The object that this struct owns is also owned by other structs - has to be that way since it's passed into JS/FFI closures which are 'static

If at runtime borrow_mut() is called and the return value is in scope at the same time as another borrow_mut or borrow, it will panic (note that there are try_ variants to handle this at runtime). If you're compiling this in wasm, there is only one thread, but it can happen if you write async code and your borrow stays in scope over an await point.

You might make it take &mut self to avoid that problem with this struct, however if there are also other structs and closures that borrow this value, that won't save you.

It's not always easy to know what the best design is. I'm working on an actor library, since actors solve this design problem rather conveniently, but it's not published yet. Otherwise you just want to be really clear on your book-keeping and keep the borrows as short as possible.

1 Like