From ffacb8861a860e5797e2835668336e60147ef454 Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Tue, 16 May 2023 15:36:05 -0400 Subject: [PATCH] add `UnsafeCell::from_mut` --- compiler/rustc_span/src/symbol.rs | 1 + library/core/src/cell.rs | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9951d8f4fc153..02505457efa4d 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1583,6 +1583,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 2c3c14853a44b..744767aae44ca 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -2030,6 +2030,27 @@ impl UnsafeCell { } impl UnsafeCell { + /// Converts from `&mut T` to `&mut UnsafeCell`. + /// + /// # 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 { + // SAFETY: `UnsafeCell` has the same memory layout as `T` due to #[repr(transparent)]. + unsafe { &mut *(value as *mut T as *mut UnsafeCell) } + } + /// Gets a mutable pointer to the wrapped value. /// /// This can be cast to a pointer of any kind.