Rollup merge of #122492 - GrigorenkoPV:ptr_as_ref_unchecked, r=workingjubilee
Implement ptr_as_ref_unchecked Implementation of #122034. Prefixed the feature name with `ptr_` for clarity. Linked const-unstability to #91822, so the post there should probably be updated to mentions the 3 new methods when/if this PR is merged.
This commit is contained in:
commit
a296693376
@ -358,6 +358,54 @@ pub const fn to_raw_parts(self) -> (*const (), <T as super::Pointee>::Metadata)
|
||||
if self.is_null() { None } else { unsafe { Some(&*self) } }
|
||||
}
|
||||
|
||||
/// Returns a shared reference to the value behind the pointer.
|
||||
/// If the pointer may be null or the value may be uninitialized, [`as_uninit_ref`] must be used instead.
|
||||
/// If the pointer may be null, but the value is known to have been initialized, [`as_ref`] must be used instead.
|
||||
///
|
||||
/// [`as_ref`]: #method.as_ref
|
||||
/// [`as_uninit_ref`]: #method.as_uninit_ref
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// When calling this method, you have to ensure that all of the following is true:
|
||||
///
|
||||
/// * The pointer must be properly aligned.
|
||||
///
|
||||
/// * It must be "dereferenceable" in the sense defined in [the module documentation].
|
||||
///
|
||||
/// * The pointer must point to an initialized instance of `T`.
|
||||
///
|
||||
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
|
||||
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
|
||||
/// In particular, while this reference exists, the memory the pointer points to must
|
||||
/// not get mutated (except inside `UnsafeCell`).
|
||||
///
|
||||
/// This applies even if the result of this method is unused!
|
||||
/// (The part about being initialized is not yet fully decided, but until
|
||||
/// it is, the only safe approach is to ensure that they are indeed initialized.)
|
||||
///
|
||||
/// [the module documentation]: crate::ptr#safety
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(ptr_as_ref_unchecked)]
|
||||
/// let ptr: *const u8 = &10u8 as *const u8;
|
||||
///
|
||||
/// unsafe {
|
||||
/// println!("We got back the value: {}!", ptr.as_ref_unchecked());
|
||||
/// }
|
||||
/// ```
|
||||
// FIXME: mention it in the docs for `as_ref` and `as_uninit_ref` once stabilized.
|
||||
#[unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub const unsafe fn as_ref_unchecked<'a>(self) -> &'a T {
|
||||
// SAFETY: the caller must guarantee that `self` is valid for a reference
|
||||
unsafe { &*self }
|
||||
}
|
||||
|
||||
/// Returns `None` if the pointer is null, or else returns a shared reference to
|
||||
/// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
|
||||
/// that the value has to be initialized.
|
||||
|
@ -367,6 +367,57 @@ pub const fn to_raw_parts(self) -> (*mut (), <T as super::Pointee>::Metadata) {
|
||||
if self.is_null() { None } else { unsafe { Some(&*self) } }
|
||||
}
|
||||
|
||||
/// Returns a shared reference to the value behind the pointer.
|
||||
/// If the pointer may be null or the value may be uninitialized, [`as_uninit_ref`] must be used instead.
|
||||
/// If the pointer may be null, but the value is known to have been initialized, [`as_ref`] must be used instead.
|
||||
///
|
||||
/// For the mutable counterpart see [`as_mut_unchecked`].
|
||||
///
|
||||
/// [`as_ref`]: #method.as_ref
|
||||
/// [`as_uninit_ref`]: #method.as_uninit_ref
|
||||
/// [`as_mut_unchecked`]: #method.as_mut_unchecked
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// When calling this method, you have to ensure that all of the following is true:
|
||||
///
|
||||
/// * The pointer must be properly aligned.
|
||||
///
|
||||
/// * It must be "dereferenceable" in the sense defined in [the module documentation].
|
||||
///
|
||||
/// * The pointer must point to an initialized instance of `T`.
|
||||
///
|
||||
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
|
||||
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
|
||||
/// In particular, while this reference exists, the memory the pointer points to must
|
||||
/// not get mutated (except inside `UnsafeCell`).
|
||||
///
|
||||
/// This applies even if the result of this method is unused!
|
||||
/// (The part about being initialized is not yet fully decided, but until
|
||||
/// it is, the only safe approach is to ensure that they are indeed initialized.)
|
||||
///
|
||||
/// [the module documentation]: crate::ptr#safety
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(ptr_as_ref_unchecked)]
|
||||
/// let ptr: *mut u8 = &mut 10u8 as *mut u8;
|
||||
///
|
||||
/// unsafe {
|
||||
/// println!("We got back the value: {}!", ptr.as_ref_unchecked());
|
||||
/// }
|
||||
/// ```
|
||||
// FIXME: mention it in the docs for `as_ref` and `as_uninit_ref` once stabilized.
|
||||
#[unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub const unsafe fn as_ref_unchecked<'a>(self) -> &'a T {
|
||||
// SAFETY: the caller must guarantee that `self` is valid for a reference
|
||||
unsafe { &*self }
|
||||
}
|
||||
|
||||
/// Returns `None` if the pointer is null, or else returns a shared reference to
|
||||
/// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
|
||||
/// that the value has to be initialized.
|
||||
@ -688,6 +739,58 @@ pub fn mask(self, mask: usize) -> *mut T {
|
||||
if self.is_null() { None } else { unsafe { Some(&mut *self) } }
|
||||
}
|
||||
|
||||
/// Returns a unique reference to the value behind the pointer.
|
||||
/// If the pointer may be null or the value may be uninitialized, [`as_uninit_mut`] must be used instead.
|
||||
/// If the pointer may be null, but the value is known to have been initialized, [`as_mut`] must be used instead.
|
||||
///
|
||||
/// For the shared counterpart see [`as_ref_unchecked`].
|
||||
///
|
||||
/// [`as_mut`]: #method.as_mut
|
||||
/// [`as_uninit_mut`]: #method.as_uninit_mut
|
||||
/// [`as_ref_unchecked`]: #method.as_mut_unchecked
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// When calling this method, you have to ensure that all of the following is true:
|
||||
///
|
||||
/// * The pointer must be properly aligned.
|
||||
///
|
||||
/// * It must be "dereferenceable" in the sense defined in [the module documentation].
|
||||
///
|
||||
/// * The pointer must point to an initialized instance of `T`.
|
||||
///
|
||||
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
|
||||
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
|
||||
/// In particular, while this reference exists, the memory the pointer points to must
|
||||
/// not get mutated (except inside `UnsafeCell`).
|
||||
///
|
||||
/// This applies even if the result of this method is unused!
|
||||
/// (The part about being initialized is not yet fully decided, but until
|
||||
/// it is, the only safe approach is to ensure that they are indeed initialized.)
|
||||
///
|
||||
/// [the module documentation]: crate::ptr#safety
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(ptr_as_ref_unchecked)]
|
||||
/// let mut s = [1, 2, 3];
|
||||
/// let ptr: *mut u32 = s.as_mut_ptr();
|
||||
/// let first_value = unsafe { ptr.as_mut_unchecked() };
|
||||
/// *first_value = 4;
|
||||
/// # assert_eq!(s, [4, 2, 3]);
|
||||
/// println!("{s:?}"); // It'll print: "[4, 2, 3]".
|
||||
/// ```
|
||||
// FIXME: mention it in the docs for `as_mut` and `as_uninit_mut` once stabilized.
|
||||
#[unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub const unsafe fn as_mut_unchecked<'a>(self) -> &'a mut T {
|
||||
// SAFETY: the caller must guarantee that `self` is valid for a reference
|
||||
unsafe { &mut *self }
|
||||
}
|
||||
|
||||
/// Returns `None` if the pointer is null, or else returns a unique reference to
|
||||
/// the value wrapped in `Some`. In contrast to [`as_mut`], this does not require
|
||||
/// that the value has to be initialized.
|
||||
|
Loading…
Reference in New Issue
Block a user