Skip to content

Commit ddd119b

Browse files
committed
expand documentation on type conversion w.r.t. UnsafeCell
1 parent 9c37c80 commit ddd119b

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

library/core/src/cell.rs

+13-8
Original file line numberDiff line numberDiff line change
@@ -1811,14 +1811,19 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
18111811
///
18121812
/// [`.get_mut()`]: `UnsafeCell::get_mut`
18131813
///
1814-
/// `UnsafeCell<T>` has the same in-memory representation as its inner type `T` if and only if
1815-
/// the type `T` does not contain a [niche] (e.g. the type `Option<NonNull<u8>>` is typically
1816-
/// 8 bytes large on 64-bit platforms, but the type `Option<UnsafeCell<NonNull<u8>>>` takes
1817-
/// up 16 bytes of space). A consequence of this guarantee is that it is possible to convert
1818-
/// between `T` and `UnsafeCell<T>` when `T` has no niches. However, it is only valid to obtain
1819-
/// a `*mut T` pointer to the contents of a _shared_ `UnsafeCell<T>` through [`.get()`] or
1820-
/// [`.raw_get()`]. A `&mut T` reference can be obtained by either dereferencing this pointer
1821-
/// or by calling [`.get_mut()`] on an _exclusive_ `UnsafeCell<T>`, e.g.:
1814+
/// `UnsafeCell<T>` has the same in-memory representation as its inner type `T`. A consequence
1815+
/// of this guarantee is that it is possible to convert between `T` and `UnsafeCell<T>`.
1816+
/// Special care has to be taken when converting a nested `T` inside of an `Outer<T>` type
1817+
/// to an `Outer<UnsafeCell<T>>` type: this is not sound when the `Outer<T>` type enables [niche]
1818+
/// optimizations. For example, the type `Option<NonNull<u8>>` is typically 8 bytes large on
1819+
/// 64-bit platforms, but the type `Option<UnsafeCell<NonNull<u8>>>` takes up 16 bytes of space.
1820+
/// Therefore this is not a valid conversion, despite `NonNull<u8>` and `UnsafeCell<NonNull<u8>>>`
1821+
/// having the same memory layout. This is because `UnsafeCell` disables niche optimizations in
1822+
/// order to avoid its interior mutability property from spreading from `T` into the `Outer` type,
1823+
/// thus this can cause distortions in the type size in these cases. Furthermore, it is only valid
1824+
/// to obtain a `*mut T` pointer to the contents of a _shared_ `UnsafeCell<T>` through [`.get()`]
1825+
/// or [`.raw_get()`]. A `&mut T` reference can be obtained by either dereferencing this pointer or
1826+
/// by calling [`.get_mut()`] on an _exclusive_ `UnsafeCell<T>`, e.g.:
18221827
///
18231828
/// ```rust
18241829
/// use std::cell::UnsafeCell;

0 commit comments

Comments
 (0)