From 13bc0996ddb64919feefb256ad9468087333121d Mon Sep 17 00:00:00 2001 From: Pointerbender Date: Wed, 14 Sep 2022 10:10:18 +0200 Subject: [PATCH] expand documentation on type conversion w.r.t. `UnsafeCell` --- library/core/src/cell.rs | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index cce4e5a5946..b730e13dcb8 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -1811,7 +1811,36 @@ impl fmt::Display for RefMut<'_, T> { /// /// [`.get_mut()`]: `UnsafeCell::get_mut` /// -/// `UnsafeCell` has the same in-memory representation as its inner type `T`. +/// `UnsafeCell` has the same in-memory representation as its inner type `T`. A consequence +/// of this guarantee is that it is possible to convert between `T` and `UnsafeCell`. +/// However, it is only valid to obtain a `*mut T` pointer or `&mut T` reference to the +/// contents of an `UnsafeCell` through [`.get()`], [`.raw_get()`] or [`.get_mut()`], e.g.: +/// +/// ```rust +/// use std::cell::UnsafeCell; +/// +/// let mut x: UnsafeCell = UnsafeCell::new(5); +/// let p1: &UnsafeCell = &x; +/// // using `.get()` is okay: +/// unsafe { +/// // SAFETY: there exist no other references to the contents of `x` +/// let p2: &mut u32 = &mut *p1.get(); +/// }; +/// // using `.raw_get()` is also okay: +/// unsafe { +/// // SAFETY: there exist no other references to the contents of `x` in this scope +/// let p2: &mut u32 = &mut *UnsafeCell::raw_get(p1 as *const _); +/// }; +/// // using `.get_mut()` is always safe: +/// let p2: &mut u32 = x.get_mut(); +/// // but the following is not allowed! +/// // let p2: &mut u32 = unsafe { +/// // let t: *mut u32 = &x as *const _ as *mut u32; +/// // &mut *t +/// // }; +/// ``` +/// +/// [`.raw_get()`]: `UnsafeCell::raw_get` /// /// # Examples ///