Description
I'm raising this as an issue, even if it might look more like a question; I think the docs need to be clarified.
I'm trying to figure out if and how UnsafeCell
is special. Let's start with two statements, the first from std API docs
The UnsafeCell type is the only legal way to obtain aliasable data that is considered mutable. In general, transmuting an &T type into an &mut T is considered undefined behavior.
The second from nomicon:
Transmuting an & to &mut is UB
Transmuting an & to &mut is always UB
No you can't do it
No you're not special
So, this seems contradictory, and the first theory is that UnsafeCell
is indeed special and that the Nomicon just forgot to mention it. The fact that unsafecell is a lang_item points in that direction too. But it seems there is more to it than that. The API docs mention &mut T
, but UnsafeCell
never hands out a &mut T
, only a *mut T
. And for *mut T
, the compiler cannot assume that two pointers are never the same; that is only true for &mut T
. (Is this correct?)
And AFAIK, none of the std wrappers allow for two &mut T
- Cell
never gives out a &mut T
, it just copies values in and out, RefCell
, Mutex
and RwLock
uses runtime checks to make sure there is only one &mut T
at a time. And atomics never deal with &mut
either.
So, that seems to point to the nomicon being correct, but then I don't see why we would need an UnsafeCell
in the first place - Cell
and friends could just implement their functionality on top of a T
rather than an UnsafeCell<T>
.