diff options
author | Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> | 2023-05-17 11:13:57 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-17 11:13:57 +0530 |
commit | 71fdb95272ba1155cb0eacd7053d0eec18f1dab1 (patch) | |
tree | 01605ebd761c6be436aa22b5944619ab17da392e | |
parent | bc3b94a486cb2bea32f3d07bd6cab76fae95d35f (diff) | |
parent | ffacb8861a860e5797e2835668336e60147ef454 (diff) | |
download | rust-71fdb95272ba1155cb0eacd7053d0eec18f1dab1.tar.gz |
Rollup merge of #111654 - JoJoJet:unsafe-cell-from-mut-lib, r=joshtriplett
Add a conversion from `&mut T` to `&mut UnsafeCell<T>`
Provides a safe way of downgrading an exclusive reference into an alias-able `&UnsafeCell<T>` reference.
ACP: https://github.com/rust-lang/libs-team/issues/198.
-rw-r--r-- | compiler/rustc_span/src/symbol.rs | 1 | ||||
-rw-r--r-- | library/core/src/cell.rs | 21 |
2 files changed, 22 insertions, 0 deletions
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index e43eddd8e6b..874d578fe1d 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1584,6 +1584,7 @@ symbols! { unrestricted_attribute_tokens, unsafe_block_in_unsafe_fn, unsafe_cell, + unsafe_cell_from_mut, unsafe_no_drop_flag, unsafe_pin_internals, unsize, diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 2c3c14853a4..744767aae44 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -2030,6 +2030,27 @@ impl<T> UnsafeCell<T> { } impl<T: ?Sized> UnsafeCell<T> { + /// Converts from `&mut T` to `&mut UnsafeCell<T>`. + /// + /// # Examples + /// + /// ``` + /// # #![feature(unsafe_cell_from_mut)] + /// use std::cell::UnsafeCell; + /// + /// let mut val = 42; + /// let uc = UnsafeCell::from_mut(&mut val); + /// + /// *uc.get_mut() -= 1; + /// assert_eq!(*uc.get_mut(), 41); + /// ``` + #[inline(always)] + #[unstable(feature = "unsafe_cell_from_mut", issue = "111645")] + pub const fn from_mut(value: &mut T) -> &mut UnsafeCell<T> { + // SAFETY: `UnsafeCell<T>` has the same memory layout as `T` due to #[repr(transparent)]. + unsafe { &mut *(value as *mut T as *mut UnsafeCell<T>) } + } + /// Gets a mutable pointer to the wrapped value. /// /// This can be cast to a pointer of any kind. |