Skip to content

Commit 7958166

Browse files
authored
Rollup merge of rust-lang#82372 - RalfJung:unsafe-cell, r=KodrAus
improve UnsafeCell docs Sometimes [questions like this come up](https://rust-lang.zulipchat.com/#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/UnsafeCells.20as.20raw.20pointers) because the UnsafeCell docs say "it's the only legal way to obtain aliasable data that is considered mutable". That is not entirely correct, since raw pointers also provide that option. So I propose we focus the docs on the interaction of `UnsafeCell` and *shared references* specifically, which is really where they are needed.
2 parents 1870b3b + 1260883 commit 7958166

File tree

1 file changed

+11
-10
lines changed

1 file changed

+11
-10
lines changed

library/core/src/cell.rs

+11-10
Original file line numberDiff line numberDiff line change
@@ -1619,17 +1619,18 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
16191619

16201620
/// The core primitive for interior mutability in Rust.
16211621
///
1622-
/// `UnsafeCell<T>` is a type that wraps some `T` and indicates unsafe interior operations on the
1623-
/// wrapped type. Types with an `UnsafeCell<T>` field are considered to have an 'unsafe interior'.
1624-
/// The `UnsafeCell<T>` type is the only legal way to obtain aliasable data that is considered
1625-
/// mutable. In general, transmuting a `&T` type into a `&mut T` is considered undefined behavior.
1622+
/// If you have a reference `&T`, then normally in Rust the compiler performs optimizations based on
1623+
/// the knowledge that `&T` points to immutable data. Mutating that data, for example through an
1624+
/// alias or by transmuting an `&T` into an `&mut T`, is considered undefined behavior.
1625+
/// `UnsafeCell<T>` opts-out of the immutability guarantee for `&T`: a shared reference
1626+
/// `&UnsafeCell<T>` may point to data that is being mutated. This is called "interior mutability".
16261627
///
1627-
/// If you have a reference `&SomeStruct`, then normally in Rust all fields of `SomeStruct` are
1628-
/// immutable. The compiler makes optimizations based on the knowledge that `&T` is not mutably
1629-
/// aliased or mutated, and that `&mut T` is unique. `UnsafeCell<T>` is the only core language
1630-
/// feature to work around the restriction that `&T` may not be mutated. All other types that
1631-
/// allow internal mutability, such as `Cell<T>` and `RefCell<T>`, use `UnsafeCell` to wrap their
1632-
/// internal data. There is *no* legal way to obtain aliasing `&mut`, not even with `UnsafeCell<T>`.
1628+
/// All other types that allow internal mutability, such as `Cell<T>` and `RefCell<T>`, internally
1629+
/// use `UnsafeCell` to wrap their data.
1630+
///
1631+
/// Note that only the immutability guarantee for shared references is affected by `UnsafeCell`. The
1632+
/// uniqueness guarantee for mutable references is unaffected. There is *no* legal way to obtain
1633+
/// aliasing `&mut`, not even with `UnsafeCell<T>`.
16331634
///
16341635
/// The `UnsafeCell` API itself is technically very simple: [`.get()`] gives you a raw pointer
16351636
/// `*mut T` to its contents. It is up to _you_ as the abstraction designer to use that raw pointer

0 commit comments

Comments
 (0)