Skip to content

Commit 13bc099

Browse files
committed
expand documentation on type conversion w.r.t. UnsafeCell
1 parent 302e33f commit 13bc099

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

library/core/src/cell.rs

+30-1
Original file line numberDiff line numberDiff line change
@@ -1811,7 +1811,36 @@ 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`.
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+
/// However, it is only valid to obtain a `*mut T` pointer or `&mut T` reference to the
1817+
/// contents of an `UnsafeCell<T>` through [`.get()`], [`.raw_get()`] or [`.get_mut()`], e.g.:
1818+
///
1819+
/// ```rust
1820+
/// use std::cell::UnsafeCell;
1821+
///
1822+
/// let mut x: UnsafeCell<u32> = UnsafeCell::new(5);
1823+
/// let p1: &UnsafeCell<u32> = &x;
1824+
/// // using `.get()` is okay:
1825+
/// unsafe {
1826+
/// // SAFETY: there exist no other references to the contents of `x`
1827+
/// let p2: &mut u32 = &mut *p1.get();
1828+
/// };
1829+
/// // using `.raw_get()` is also okay:
1830+
/// unsafe {
1831+
/// // SAFETY: there exist no other references to the contents of `x` in this scope
1832+
/// let p2: &mut u32 = &mut *UnsafeCell::raw_get(p1 as *const _);
1833+
/// };
1834+
/// // using `.get_mut()` is always safe:
1835+
/// let p2: &mut u32 = x.get_mut();
1836+
/// // but the following is not allowed!
1837+
/// // let p2: &mut u32 = unsafe {
1838+
/// // let t: *mut u32 = &x as *const _ as *mut u32;
1839+
/// // &mut *t
1840+
/// // };
1841+
/// ```
1842+
///
1843+
/// [`.raw_get()`]: `UnsafeCell::raw_get`
18151844
///
18161845
/// # Examples
18171846
///

0 commit comments

Comments
 (0)