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 like volatile.
- 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
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 typeUnsafe<T>that contains the most general (and unsafe) form of interior mutability, which is a function that yields a*mut T: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:Unsafe<T>, you cannot take its address.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.Freezekind (seemingly orthogonal but...not).This type replaces
transmute_mutas the building block for types likeCell. 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