Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions library/core/src/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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

@RalfJung RalfJung Jun 9, 2026

Copy link
Copy Markdown
Member Author

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 &mut to safe code, the rules don't apply. That's incorrect, these rules always apply.

View changes since the review

/// `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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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
/// This can be cast to a pointer of any kind. When creating (shared or mutable) references, you
/// This can be cast to a pointer of any kind. When creating shared or mutable references, you

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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
///
Expand Down Expand Up @@ -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
Comment thread
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()
///
Expand Down
Loading