mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Rollup merge of #136398 - pitaj:unsafecell_access, r=dtolnay
add UnsafeCell direct access APIs - Implementation for ACP: https://github.com/rust-lang/libs-team/issues/521 - Tracking issue #136327
This commit is contained in:
commit
d89e98dcbf
@ -2118,6 +2118,35 @@ impl<T> UnsafeCell<T> {
|
||||
pub const fn into_inner(self) -> T {
|
||||
self.value
|
||||
}
|
||||
|
||||
/// Replace the value in this `UnsafeCell` and return the old value.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must take care to avoid aliasing and data races.
|
||||
///
|
||||
/// - It is Undefined Behavior to allow calls to race with
|
||||
/// any other access to the wrapped value.
|
||||
/// - It is Undefined Behavior to call this while any other
|
||||
/// reference(s) to the wrapped value are alive.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(unsafe_cell_access)]
|
||||
/// use std::cell::UnsafeCell;
|
||||
///
|
||||
/// let uc = UnsafeCell::new(5);
|
||||
///
|
||||
/// let old = unsafe { uc.replace(10) };
|
||||
/// assert_eq!(old, 5);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "unsafe_cell_access", issue = "136327")]
|
||||
pub const unsafe fn replace(&self, value: T) -> T {
|
||||
// SAFETY: pointer comes from `&self` so naturally satisfies invariants.
|
||||
unsafe { ptr::replace(self.get(), value) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> UnsafeCell<T> {
|
||||
@ -2230,6 +2259,61 @@ impl<T: ?Sized> UnsafeCell<T> {
|
||||
// no guarantee for user code that this will work in future versions of the compiler!
|
||||
this as *const T as *mut T
|
||||
}
|
||||
|
||||
/// Get a shared reference to the value within the `UnsafeCell`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// - It is Undefined Behavior to call this while any mutable
|
||||
/// reference to the wrapped value is alive.
|
||||
/// - Mutating the wrapped value while the returned
|
||||
/// reference is alive is Undefined Behavior.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(unsafe_cell_access)]
|
||||
/// use std::cell::UnsafeCell;
|
||||
///
|
||||
/// let uc = UnsafeCell::new(5);
|
||||
///
|
||||
/// let val = unsafe { uc.as_ref_unchecked() };
|
||||
/// assert_eq!(val, &5);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "unsafe_cell_access", issue = "136327")]
|
||||
pub const unsafe fn as_ref_unchecked(&self) -> &T {
|
||||
// SAFETY: pointer comes from `&self` so naturally satisfies ptr-to-ref invariants.
|
||||
unsafe { self.get().as_ref_unchecked() }
|
||||
}
|
||||
|
||||
/// Get an exclusive reference to the value within the `UnsafeCell`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// - It is Undefined Behavior to call this while any other
|
||||
/// reference(s) to the wrapped value are alive.
|
||||
/// - Mutating the wrapped value through other means while the
|
||||
/// returned reference is alive is Undefined Behavior.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(unsafe_cell_access)]
|
||||
/// use std::cell::UnsafeCell;
|
||||
///
|
||||
/// let uc = UnsafeCell::new(5);
|
||||
///
|
||||
/// unsafe { *uc.as_mut_unchecked() += 1; }
|
||||
/// assert_eq!(uc.into_inner(), 6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "unsafe_cell_access", issue = "136327")]
|
||||
#[allow(clippy::mut_from_ref)]
|
||||
pub const unsafe fn as_mut_unchecked(&self) -> &mut T {
|
||||
// SAFETY: pointer comes from `&self` so naturally satisfies ptr-to-ref invariants.
|
||||
unsafe { self.get().as_mut_unchecked() }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "unsafe_cell_default", since = "1.10.0")]
|
||||
|
Loading…
Reference in New Issue
Block a user