Description
Location
https://doc.rust-lang.org/std/sync/struct.Mutex.html#method.get_mut
https://doc.rust-lang.org/std/sync/struct.RwLock.html#method.get_mut
https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.get_mut
Summary
The documentation of Mutex
says this (and similar wording exists in RefCell
and RwLock
):
Since this call borrows the
Mutex
mutably, no actual locking needs to take place – the mutable borrow statically guarantees no locks exist.
However, the last part is not quite accurate. A mutex guard may be forgotten, in which case get_mut()
still succeeds, but the Mutex
is in fact still locked. think it’s worth addressing this point because:
-
One may wonder if this function is sound, given its documentation seeming to believe forgetting doesn’t exist.
-
The implementation of
get_mut()
could, in addition to returning a reference, reset the mutex to be unlocked so it can be accessed in the normal fashion in the future. That doesn’t happen in at least one current implementation,let mut m = std::sync::Mutex::new(1); std::mem::forget(m.lock().unwrap()); *m.get_mut().unwrap() = 2; *m.lock().unwrap() // deadlocks
and I doubt it ever would, but it’s an observable choice of behavior that it doesn’t. (
RefCell
hasRefCell::undo_leak()
which actually does this, but neitherMutex
norRwLock
has an analogous function.)
A more accurate but cryptic wording would be to replace “guarantees no locks exist” would be “guarantees no usable MutexGuard
s exist”; or, an entire paragraph/section about forgetting could be added. A decision needs to be made about whether the documentation promises that the mutex will always still be locked, or whether that is an implementation detail subject to change.