diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index e9eeb3153307f..73bb256518d89 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -358,6 +358,54 @@ impl *const T { 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. diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index c5a188dc7d4f2..b67930503e015 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -367,6 +367,57 @@ impl *mut T { 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 @@ impl *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.