Skip to content

It is unclear how UnsafeCell is special #34496

Closed
@diwic

Description

@diwic

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>.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions