Rollup merge of #88551 - inquisitivecrystal:unsafe_cell_raw_get, r=m-ou-se

Stabilize `UnsafeCell::raw_get()`

This PR stabilizes the associated function `UnsafeCell::raw_get()`. The FCP has [already completed](https://github.com/rust-lang/rust/issues/66358#issuecomment-899095068). While there was some discussion about the naming after the close of the FCP, it looks like people have agreed on this name. Still, it would probably be best if a `libs-api` member had a look at this and stated whether more discussion is needed.

While I was at it, I added some tests for `UnsafeCell`, because there were barely any.

Closes #66358.
This commit is contained in:
Mara Bos 2021-09-01 09:23:31 +02:00 committed by GitHub
commit d31352961c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 4 deletions

View file

@ -1921,7 +1921,7 @@ impl<T: ?Sized> UnsafeCell<T> {
}
/// Gets a mutable pointer to the wrapped value.
/// The difference to [`get`] is that this function accepts a raw pointer,
/// The difference from [`get`] is that this function accepts a raw pointer,
/// which is useful to avoid the creation of temporary references.
///
/// The result can be cast to a pointer of any kind.
@ -1937,7 +1937,6 @@ impl<T: ?Sized> UnsafeCell<T> {
/// calling `get` would require creating a reference to uninitialized data:
///
/// ```
/// #![feature(unsafe_cell_raw_get)]
/// use std::cell::UnsafeCell;
/// use std::mem::MaybeUninit;
///
@ -1948,7 +1947,7 @@ impl<T: ?Sized> UnsafeCell<T> {
/// assert_eq!(uc.into_inner(), 5);
/// ```
#[inline(always)]
#[unstable(feature = "unsafe_cell_raw_get", issue = "66358")]
#[stable(feature = "unsafe_cell_raw_get", since = "1.56.0")]
pub const fn raw_get(this: *const Self) -> *mut T {
// We can just cast the pointer from `UnsafeCell<T>` to `T` because of
// #[repr(transparent)]. This exploits libstd's special status, there is

View file

@ -2,6 +2,38 @@ use core::cell::*;
use core::default::Default;
use std::mem::drop;
#[test]
fn smoketest_unsafe_cell() {
let mut x = UnsafeCell::new(10);
let ref_mut = &mut x;
unsafe {
// The asserts are repeated in order to ensure that `get()`
// is non-mutating.
assert_eq!(*ref_mut.get(), 10);
assert_eq!(*ref_mut.get(), 10);
*ref_mut.get_mut() += 5;
assert_eq!(*ref_mut.get(), 15);
assert_eq!(*ref_mut.get(), 15);
assert_eq!(x.into_inner(), 15);
}
}
#[test]
fn unsafe_cell_raw_get() {
let x = UnsafeCell::new(10);
let ptr = &x as *const UnsafeCell<i32>;
unsafe {
// The asserts are repeated in order to ensure that `raw_get()`
// is non-mutating.
assert_eq!(*UnsafeCell::raw_get(ptr), 10);
assert_eq!(*UnsafeCell::raw_get(ptr), 10);
*UnsafeCell::raw_get(ptr) += 5;
assert_eq!(*UnsafeCell::raw_get(ptr), 15);
assert_eq!(*UnsafeCell::raw_get(ptr), 15);
assert_eq!(x.into_inner(), 15);
}
}
#[test]
fn smoketest_cell() {
let x = Cell::new(10);

View file

@ -331,7 +331,6 @@
#![feature(try_reserve)]
#![feature(try_reserve_kind)]
#![feature(unboxed_closures)]
#![feature(unsafe_cell_raw_get)]
#![feature(unwrap_infallible)]
#![feature(vec_into_raw_parts)]
#![feature(vec_spare_capacity)]