-
-
Notifications
You must be signed in to change notification settings - Fork 15k
UnsafeCell: mention shared-ref-to-interior case, fix aliasing model inaccuracy #157658
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -2172,16 +2172,16 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> { | |||||
| /// - If you create a safe reference with lifetime `'a` (either a `&T` or `&mut T` reference), then | ||||||
| /// you must not access the data in any way that contradicts that reference for the remainder of | ||||||
| /// `'a`. For example, this means that if you take the `*mut T` from an `UnsafeCell<T>` and cast it | ||||||
| /// to an `&T`, then the data in `T` must remain immutable (modulo any `UnsafeCell` data found | ||||||
| /// to a `&T`, then the data in `T` must remain immutable (modulo any `UnsafeCell` data found | ||||||
| /// within `T`, of course) until that reference's lifetime expires. Similarly, if you create a | ||||||
| /// `&mut T` reference that is released to safe code, then you must not access the data within the | ||||||
| /// `&mut T` reference, then you must not access the data within the | ||||||
| /// `UnsafeCell` until that reference expires. | ||||||
| /// | ||||||
| /// - For both `&T` without `UnsafeCell<_>` and `&mut T`, you must also not deallocate the data | ||||||
| /// until the reference expires. As a special exception, given an `&T`, any part of it that is | ||||||
| /// until the reference expires. As a special exception, given a `&T`, any part of it that is | ||||||
| /// inside an `UnsafeCell<_>` may be deallocated during the lifetime of the reference, after the | ||||||
| /// last time the reference is used (dereferenced or reborrowed). Since you cannot deallocate a part | ||||||
| /// of what a reference points to, this means the memory an `&T` points to can be deallocated only if | ||||||
| /// of what a reference points to, this means the memory a `&T` points to can be deallocated only if | ||||||
| /// *every part of it* (including padding) is inside an `UnsafeCell`. | ||||||
| /// | ||||||
| /// However, whenever a `&UnsafeCell<T>` is constructed or dereferenced, it must still point to | ||||||
|
|
@@ -2197,7 +2197,7 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> { | |||||
| /// 2. A `&mut T` reference may be released to safe code provided neither other `&mut T` nor `&T` | ||||||
| /// co-exist with it. A `&mut T` must always be unique. | ||||||
| /// | ||||||
| /// Note that whilst mutating the contents of an `&UnsafeCell<T>` (even while other | ||||||
| /// Note that whilst mutating the contents of a `&UnsafeCell<T>` (even while other | ||||||
| /// `&UnsafeCell<T>` references alias the cell) is | ||||||
| /// ok (provided you enforce the above invariants some other way), it is still undefined behavior | ||||||
| /// to have multiple `&mut UnsafeCell<T>` aliases. That is, `UnsafeCell` is a wrapper | ||||||
|
|
@@ -2224,9 +2224,9 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> { | |||||
| /// thus this can cause distortions in the type size in these cases. | ||||||
| /// | ||||||
| /// Note that the only valid way to obtain a `*mut T` pointer to the contents of a | ||||||
| /// _shared_ `UnsafeCell<T>` is through [`.get()`] or [`.raw_get()`]. A `&mut T` reference | ||||||
| /// can be obtained by either dereferencing this pointer or by calling [`.get_mut()`] | ||||||
| /// on an _exclusive_ `UnsafeCell<T>`. Even though `T` and `UnsafeCell<T>` have the | ||||||
| /// _shared_ `UnsafeCell<T>` is through [`.get()`] or [`.raw_get()`]. A `&T` or `&mut T` reference | ||||||
| /// can then be obtained from that pointer, as long as the aliasing rules outlined above are obeyed. | ||||||
| /// Even though `T` and `UnsafeCell<T>` have the | ||||||
| /// same memory layout, the following is not allowed and undefined behavior: | ||||||
| /// | ||||||
| /// ```rust,compile_fail | ||||||
|
|
@@ -2421,9 +2421,9 @@ impl<T: ?Sized> UnsafeCell<T> { | |||||
|
|
||||||
| /// Gets a mutable pointer to the wrapped value. | ||||||
| /// | ||||||
| /// This can be cast to a pointer of any kind. When creating references, you must uphold the | ||||||
| /// aliasing rules; see [the type-level docs][UnsafeCell#aliasing-rules] for more discussion and | ||||||
| /// caveats. | ||||||
| /// This can be cast to a pointer of any kind. When creating (shared or mutable) references, you | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd remove the parentheses, for me they just add unnecessary nesting.
Suggested change
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was deliberate. We could arguably just say "when creating references" since the kind of reference does not matter -- the parenthetical just clarifies that yes we mean both kinds of references.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mmmh, fair enough... |
||||||
| /// must uphold the aliasing rules; see [the type-level docs][UnsafeCell#aliasing-rules] for | ||||||
| /// more discussion and caveats. | ||||||
| /// | ||||||
| /// # Examples | ||||||
| /// | ||||||
|
|
@@ -2473,9 +2473,9 @@ impl<T: ?Sized> UnsafeCell<T> { | |||||
| /// The difference from [`get`] is that this function accepts a raw pointer, | ||||||
| /// which is useful to avoid the creation of temporary references. | ||||||
| /// | ||||||
| /// This can be cast to a pointer of any kind. When creating references, you must uphold the | ||||||
| /// aliasing rules; see [the type-level docs][UnsafeCell#aliasing-rules] for more discussion and | ||||||
| /// caveats. | ||||||
| /// This can be cast to a pointer of any kind. When creating (shared or mutable) references, you | ||||||
|
joboet marked this conversation as resolved.
|
||||||
| /// must uphold the aliasing rules; see [the type-level docs][UnsafeCell#aliasing-rules] for | ||||||
| /// more discussion and caveats. | ||||||
| /// | ||||||
| /// [`get`]: UnsafeCell::get() | ||||||
| /// | ||||||
|
|
||||||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The existing docs seemed to imply that if you don't release the
&mutto safe code, the rules don't apply. That's incorrect, these rules always apply.View changes since the review