Description
UPDATED
We have various safe wrappers that permit aliasable mutability (Cell
, RefCell
, etc). To be sound, all of them must use markers for invariance and non-freeze. We should factor out these markers and so on into a base type Unsafe<T>
that contains the most general (and unsafe) form of interior mutability, which is a function that yields a *mut T
:
struct Unsafe<T> {
priv value: T,
}
impl<T> Unsafe<T> {
unsafe fn get(&self) -> *mut T { transmute(&self.value) }
}
It will be undefined behavior to transmute an aliasable reference into something mutable through any other means.
Unsafe<T>
wlil be integrated into the compiler as follows:
- Its contents are invariant (variance analysis).
- If an immutable static item contains
Unsafe<T>
, you cannot take its address. - If a type contains
Unsafe<T>
(interior), the compiler will have to be careful about optimizing aliasing and so on. This may correspond to some existing LLVM compiler concept likevolatile
. - Remove the
Freeze
kind (seemingly orthogonal but...not).
This type replaces transmute_mut
as the building block for types like Cell
. What is better about this is that it ties together the transmute along with the marker types that are required for soundness, so that they cannot be forgotten.
cc @alexcrichton, with whom I was discussing this
cc @brson, because this relates to our discussion on laying out rules for unsafe code