Ah okay, sorry, I was confused for a short moment and now re-read your original code.
So if Bar
requires a mutable (i.e. exclusive) reference, but if you want to hold multiple references at the same time (e.g. because you want to store it in an Rc
or Arc
, or because you store it in a struct
where you have multiple shared references to), then you can use a RefCell
to obtain a mutable reference at runtime (even if you only have a shared reference to the RefCell
).
If you only require mutable references to Bar
when you also have a mutable reference to Foo
, then you wouldn't need a RefCell
at all.
But let's assume you need the RefCell
for now (I'm still not sure if you truly need it because I don't know the context of your application).
Now your original question was whether you should require the Foo::do_something
method require &mut self
. If it requires &mut self
, then the function will already have the assurance that nobody else holds a reference to self
(of type Foo
) and thus also self.inner
(of type Bar
). That means self.inner.borrow_mut()
could never panic, so it's okay to use self.inner.get_mut()
instead, which is slightly faster (but likely not noticeable) because it doesn't do the runtime check.
I believe it's semantically okay to offer such a function if the requirement of having to provide a mutable (i.e. an exclusive reference) isn't much trouble where this method is used. But I wouldn't see this as a "safety" measure, but more as an optimization which is likely not worth to do.
You might (hypothetically) even consider adding two functions doing the same, one taking &mut self
and one taking &self
, similar to what RefCell
does with borrow_mut
and get_mut
. Whenever you have a mutable reference, you can use the faster method (which doesn't do the runtime check), and when you only have a shared reference, you use the slower method.
But I feel like you either should remove the RefCell
completely, or to make do_something
(as well as most other methods on Foo
) work with &self
(because you will have multiple shared references to Foo
).
Note that if you use RefCell
, you might also want to consider using Mutex
instead, which would make Foo
be Send
and Sync
.
As I'm not really sure about your context, don't take these thoughts as definite advice.