about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPointerbender <pointerbender@gmail.com>2022-09-14 10:10:18 +0200
committerPointerbender <pointerbender@gmail.com>2022-09-14 10:10:18 +0200
commit13bc0996ddb64919feefb256ad9468087333121d (patch)
treeeb4014b1620f93e08aebd506a3a800ea0aa2b305
parent302e33fde2785874c6b85aa9760e8e6be2e7dad4 (diff)
downloadrust-13bc0996ddb64919feefb256ad9468087333121d.tar.gz
rust-13bc0996ddb64919feefb256ad9468087333121d.zip
expand documentation on type conversion w.r.t. `UnsafeCell`
-rw-r--r--library/core/src/cell.rs31
1 files changed, 30 insertions, 1 deletions
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<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
 ///
 /// [`.get_mut()`]: `UnsafeCell::get_mut`
 ///
-/// `UnsafeCell<T>` has the same in-memory representation as its inner type `T`.
+/// `UnsafeCell<T>` 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<T>`.
+/// However, it is only valid to obtain a `*mut T` pointer or `&mut T` reference to the
+/// contents of an `UnsafeCell<T>` through [`.get()`], [`.raw_get()`] or [`.get_mut()`], e.g.:
+///
+/// ```rust
+/// use std::cell::UnsafeCell;
+///
+/// let mut x: UnsafeCell<u32> = UnsafeCell::new(5);
+/// let p1: &UnsafeCell<u32> = &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
 ///