summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2023-05-17 11:13:57 +0530
committerGitHub <noreply@github.com>2023-05-17 11:13:57 +0530
commit71fdb95272ba1155cb0eacd7053d0eec18f1dab1 (patch)
tree01605ebd761c6be436aa22b5944619ab17da392e
parentbc3b94a486cb2bea32f3d07bd6cab76fae95d35f (diff)
parentffacb8861a860e5797e2835668336e60147ef454 (diff)
downloadrust-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.rs1
-rw-r--r--library/core/src/cell.rs21
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.