From 2a91eeac1a2d27dd3de1bf55515d765da20fd86f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Wed, 13 Apr 2022 15:50:23 +0200 Subject: [PATCH] Implement `core::ptr::Unique` on top of `NonNull` Removes the use `rustc_layout_scalar_valid_range_start` and some `unsafe` blocks. --- library/core/src/lib.rs | 2 ++ library/core/src/ptr/unique.rs | 41 ++++++++++++++++++---------------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 6546a5244fd0..813f6ed58e7f 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -119,12 +119,14 @@ #![feature(const_likely)] #![feature(const_maybe_uninit_as_mut_ptr)] #![feature(const_maybe_uninit_assume_init)] +#![feature(const_nonnull_new)] #![feature(const_num_from_num)] #![feature(const_ops)] #![feature(const_option)] #![feature(const_option_ext)] #![feature(const_pin)] #![feature(const_replace)] +#![feature(const_ptr_as_ref)] #![feature(const_ptr_is_null)] #![feature(const_ptr_offset_from)] #![feature(const_ptr_read)] diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index 29398cbeb238..64616142b418 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs @@ -1,8 +1,8 @@ use crate::convert::From; use crate::fmt; use crate::marker::{PhantomData, Unsize}; -use crate::mem; use crate::ops::{CoerceUnsized, DispatchFromDyn}; +use crate::ptr::NonNull; /// A wrapper around a raw non-null `*mut T` that indicates that the possessor /// of this wrapper owns the referent. Useful for building abstractions like @@ -32,9 +32,8 @@ use crate::ops::{CoerceUnsized, DispatchFromDyn}; )] #[doc(hidden)] #[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(1)] pub struct Unique { - pointer: *const T, + pointer: NonNull, // NOTE: this marker has no consequences for variance, but is necessary // for dropck to understand that we logically own a `T`. // @@ -71,9 +70,7 @@ impl Unique { #[must_use] #[inline] pub const fn dangling() -> Self { - // SAFETY: mem::align_of() returns a valid, non-null pointer. The - // conditions to call new_unchecked() are thus respected. - unsafe { Unique::new_unchecked(crate::ptr::invalid_mut::(mem::align_of::())) } + Self::from(NonNull::dangling()) } } @@ -87,15 +84,14 @@ impl Unique { #[inline] pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { // SAFETY: the caller must guarantee that `ptr` is non-null. - unsafe { Unique { pointer: ptr as _, _marker: PhantomData } } + unsafe { Unique { pointer: NonNull::new_unchecked(ptr), _marker: PhantomData } } } /// Creates a new `Unique` if `ptr` is non-null. #[inline] pub const fn new(ptr: *mut T) -> Option { - if !ptr.is_null() { - // SAFETY: The pointer has already been checked and is not null. - Some(unsafe { Unique { pointer: ptr as _, _marker: PhantomData } }) + if let Some(pointer) = NonNull::new(ptr) { + Some(Unique { pointer, _marker: PhantomData }) } else { None } @@ -105,7 +101,7 @@ impl Unique { #[must_use = "`self` will be dropped if the result is not used"] #[inline] pub const fn as_ptr(self) -> *mut T { - self.pointer as *mut T + self.pointer.as_ptr() } /// Dereferences the content. @@ -118,7 +114,7 @@ impl Unique { pub const unsafe fn as_ref(&self) -> &T { // SAFETY: the caller must guarantee that `self` meets all the // requirements for a reference. - unsafe { &*self.as_ptr() } + unsafe { self.pointer.as_ref() } } /// Mutably dereferences the content. @@ -131,17 +127,14 @@ impl Unique { pub const unsafe fn as_mut(&mut self) -> &mut T { // SAFETY: the caller must guarantee that `self` meets all the // requirements for a mutable reference. - unsafe { &mut *self.as_ptr() } + unsafe { self.pointer.as_mut() } } /// Casts to a pointer of another type. #[must_use = "`self` will be dropped if the result is not used"] #[inline] pub const fn cast(self) -> Unique { - // SAFETY: Unique::new_unchecked() creates a new unique and needs - // the given pointer to not be null. - // Since we are passing self as a pointer, it cannot be null. - unsafe { Unique::new_unchecked(self.as_ptr() as *mut U) } + Unique::from(self.pointer.cast()) } } @@ -184,7 +177,17 @@ impl const From<&mut T> for Unique { /// This conversion is infallible since references cannot be null. #[inline] fn from(reference: &mut T) -> Self { - // SAFETY: A mutable reference cannot be null - unsafe { Unique { pointer: reference as *mut T, _marker: PhantomData } } + Self::from(NonNull::from(reference)) + } +} + +#[unstable(feature = "ptr_internals", issue = "none")] +impl const From> for Unique { + /// Converts a `NonNull` to a `Unique`. + /// + /// This conversion is infallible since `NonNull` cannot be null. + #[inline] + fn from(pointer: NonNull) -> Self { + Unique { pointer, _marker: PhantomData } } }