-
Notifications
You must be signed in to change notification settings - Fork 13.3k
It is unclear how UnsafeCell is special #34496
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
UnsafeCell is not documented because we don't actually know what it does, not at an abstraction level that would be meaningful to programmers anyway. Operationally it causes rustc to suppress emitting llvm noalias attributes in certain situations, but part of the task of the ongoing Rust memory model effort will be to come up with clear rules for when UnsafeCell is needed. |
There's no contradiction. That said the docs should definitely be improved with the results of the memory model effort. |
I don't think they are actually contradictory here, just confusing. As you point out
Yes.
|
This is correct. However, you should not be transmuting an What you should be doing is converting that *mut T to an &mut T and using it. But you must ensure that at runtime that is the only &mut T in active use. You should never ever ever have two &mut Ts active pointing to the same T. However, when building abstractions like RefCell, Mutex, or Cell, you need the ability to turn off this restriction for a while. The compiler basically makes optimizations assuming that But it is fundamentally unsafe to have two &muts lying around; which is why the stdlib never gives those out without some form of checking. |
First, thanks for all explanations! About the contradiction; I think that if one doc says "In general, transmuting...", that implies that there are exceptions to the rule, and "No, no you're not special" implies that there are no exceptions. That's the core of the contradiction to me. I'm afraid your answers left me with more questions, but feel free to poke me in case you feel this is taking up too much of your time.
I'm not sure we require a lang_item for this part - wouldn't just the existing
Okay, so this makes some sense, maybe you can reason about function purity if a
Okay, so this is the part I don't get. Cell, e g, could just as well just have used A related question here is also about the typecast |
Since functions can always access
This is the main win. The compiler doesn't have to prove that intervening writes can't affect the
The exact rules for what's UB and what isn't are still being hammered out, but it's pretty clear that e.g. this shall be illegal:
And this shall be legal:
The latter also creates a |
We have still not decided on the semantics of Also, doing |
I believe you are correct, yes. |
The lang item part seems to be used in various corners of the compiler for On Tue, Jun 28, 2016 at 2:10 PM, Brian Anderson notifications@github.com
|
But you're not supposed to transmute it. That it internally does something similar to a transmute is irrelevant, don't transmute &UnsafeCell.
Cell is usually found behind an &, e.g. within an Rc. Mutating this is unsafe, unless unsafecell is involved. &mut is only half the story, there are rules about & too. |
I think things are a bit clearer now. I also found a third source of information, form the Language reference:
Yes. Let's just remove the "In general, transmuting an
Yes, that's what's becoming more obvious to me now after the explanations from you all. Thanks! |
But it is true. Remember that UB isn't completely defined in Rust, so weasel-word statements like this are necessary 😄 |
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 docsThe second from nomicon:
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
, butUnsafeCell
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
andRwLock
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 aT
rather than anUnsafeCell<T>
.The text was updated successfully, but these errors were encountered: