Description
Proposal
Problem statement
There should be a safe API that converts an &mut T
reference into an &mut UnsafeCell<T>
reference within a certain scope.
Motivation, use-cases
When dealing with exclusive references, sometimes you may wish to opt in to temporary shared mutable access. If your type implements Copy
, you can use Cell::from_mut
to convert a mutable reference to a Cell
, which allows interior mutability. For non-Copy
types, it is often required to use UnsafeCell
to allow interior mutability. Converting from &mut T
to &mut UnsafeCell<T>
is always sound, however there is currently no safe way to do this so the user is required to use std::mem::transmute
. Use of this function is potentially error-prone, as a simple mistake might result in the returned reference having an incorrect lifetime.
For an example of a situation where this would be useful, consider this code I wrote for the bevy game engine:
// SAFETY: Converting `&mut T` -> `&UnsafeCell<T>`
// is explicitly allowed in the docs for `UnsafeCell`.
let world: &'w UnsafeCell<World> = unsafe { std::mem::transmute(world) };
Func::combine(
input,
// SAFETY: Since these closures are `!Send + !Sync + !'static`, they can never
// be called in parallel. Since mutable access to `world` only exists within
// the scope of either closure, we can be sure they will never alias one another.
|input| self.a.run(input, unsafe { world.deref_mut() }),
|input| self.b.run(input, unsafe { world.deref_mut() }),
)
Solution sketches
We should add an associated fn to the UnsafeCell
type:
pub fn from_mut(value: &mut T) -> &mut UnsafeCell<T> {
// SAFETY: UnsafeCell is repr(transparent).
unsafe { &mut *(value as *mut T as *mut Self) }
}
This returns &mut UnsafeCell<T>
, unlike Cell::from_mut
which returns &Cell
. It was a mistake for Cell::from_mut
to work this way, since exclusive references are more useful due to the {Unsafe}Cell::get_mut
function.
Links and related work
What happens now?
This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals in its weekly meeting. You should receive feedback within a week or two.