use crate::cmp::Ordering; use crate::convert::From; use crate::fmt; use crate::hash; use crate::marker::Unsize; use crate::mem; use crate::ops::{CoerceUnsized, DispatchFromDyn}; use crate::ptr::Unique; // ignore-tidy-undocumented-unsafe /// `*mut T` but non-zero and covariant. /// /// This is often the correct thing to use when building data structures using /// raw pointers, but is ultimately more dangerous to use because of its additional /// properties. If you're not sure if you should use `NonNull`, just use `*mut T`! /// /// Unlike `*mut T`, the pointer must always be non-null, even if the pointer /// is never dereferenced. This is so that enums may use this forbidden value /// as a discriminant -- `Option>` has the same size as `*mut T`. /// However the pointer may still dangle if it isn't dereferenced. /// /// Unlike `*mut T`, `NonNull` is covariant over `T`. If this is incorrect /// for your use case, you should include some [`PhantomData`] in your type to /// provide invariance, such as `PhantomData>` or `PhantomData<&'a mut T>`. /// Usually this won't be necessary; covariance is correct for most safe abstractions, /// such as `Box`, `Rc`, `Arc`, `Vec`, and `LinkedList`. This is the case because they /// provide a public API that follows the normal shared XOR mutable rules of Rust. /// /// Notice that `NonNull` has a `From` instance for `&T`. However, this does /// not change the fact that mutating through a (pointer derived from a) shared /// reference is undefined behavior unless the mutation happens inside an /// [`UnsafeCell`]. The same goes for creating a mutable reference from a shared /// reference. When using this `From` instance without an `UnsafeCell`, /// it is your responsibility to ensure that `as_mut` is never called, and `as_ptr` /// is never used for mutation. /// /// [`PhantomData`]: ../marker/struct.PhantomData.html /// [`UnsafeCell`]: ../cell/struct.UnsafeCell.html #[stable(feature = "nonnull", since = "1.25.0")] #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] #[rustc_nonnull_optimization_guaranteed] pub struct NonNull { pointer: *const T, } /// `NonNull` pointers are not `Send` because the data they reference may be aliased. // N.B., this impl is unnecessary, but should provide better error messages. #[stable(feature = "nonnull", since = "1.25.0")] impl !Send for NonNull {} /// `NonNull` pointers are not `Sync` because the data they reference may be aliased. // N.B., this impl is unnecessary, but should provide better error messages. #[stable(feature = "nonnull", since = "1.25.0")] impl !Sync for NonNull {} impl NonNull { /// Creates a new `NonNull` that is dangling, but well-aligned. /// /// This is useful for initializing types which lazily allocate, like /// `Vec::new` does. /// /// Note that the pointer value may potentially represent a valid pointer to /// a `T`, which means this must not be used as a "not yet initialized" /// sentinel value. Types that lazily allocate must track initialization by /// some other means. #[stable(feature = "nonnull", since = "1.25.0")] #[rustc_const_stable(feature = "const_nonnull_dangling", since = "1.32.0")] #[inline] pub const fn dangling() -> Self { unsafe { let ptr = mem::align_of::() as *mut T; NonNull::new_unchecked(ptr) } } } impl NonNull { /// Creates a new `NonNull`. /// /// # Safety /// /// `ptr` must be non-null. #[stable(feature = "nonnull", since = "1.25.0")] #[rustc_const_stable(feature = "const_nonnull_new_unchecked", since = "1.32.0")] #[inline] pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { NonNull { pointer: ptr as _ } } /// Creates a new `NonNull` if `ptr` is non-null. #[stable(feature = "nonnull", since = "1.25.0")] #[inline] pub fn new(ptr: *mut T) -> Option { if !ptr.is_null() { Some(unsafe { Self::new_unchecked(ptr) }) } else { None } } /// Acquires the underlying `*mut` pointer. #[stable(feature = "nonnull", since = "1.25.0")] #[rustc_const_stable(feature = "const_nonnull_as_ptr", since = "1.32.0")] #[inline] pub const fn as_ptr(self) -> *mut T { self.pointer as *mut T } /// Dereferences the content. /// /// The resulting lifetime is bound to self so this behaves "as if" /// it were actually an instance of T that is getting borrowed. If a longer /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`. #[stable(feature = "nonnull", since = "1.25.0")] #[inline] pub unsafe fn as_ref(&self) -> &T { &*self.as_ptr() } /// Mutably dereferences the content. /// /// The resulting lifetime is bound to self so this behaves "as if" /// it were actually an instance of T that is getting borrowed. If a longer /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`. #[stable(feature = "nonnull", since = "1.25.0")] #[inline] pub unsafe fn as_mut(&mut self) -> &mut T { &mut *self.as_ptr() } /// Casts to a pointer of another type. #[stable(feature = "nonnull_cast", since = "1.27.0")] #[rustc_const_stable(feature = "const_nonnull_cast", since = "1.32.0")] #[inline] pub const fn cast(self) -> NonNull { unsafe { NonNull::new_unchecked(self.as_ptr() as *mut U) } } } #[stable(feature = "nonnull", since = "1.25.0")] impl Clone for NonNull { #[inline] fn clone(&self) -> Self { *self } } #[stable(feature = "nonnull", since = "1.25.0")] impl Copy for NonNull {} #[unstable(feature = "coerce_unsized", issue = "27732")] impl CoerceUnsized> for NonNull where T: Unsize {} #[unstable(feature = "dispatch_from_dyn", issue = "none")] impl DispatchFromDyn> for NonNull where T: Unsize {} #[stable(feature = "nonnull", since = "1.25.0")] impl fmt::Debug for NonNull { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } #[stable(feature = "nonnull", since = "1.25.0")] impl fmt::Pointer for NonNull { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } #[stable(feature = "nonnull", since = "1.25.0")] impl Eq for NonNull {} #[stable(feature = "nonnull", since = "1.25.0")] impl PartialEq for NonNull { #[inline] fn eq(&self, other: &Self) -> bool { self.as_ptr() == other.as_ptr() } } #[stable(feature = "nonnull", since = "1.25.0")] impl Ord for NonNull { #[inline] fn cmp(&self, other: &Self) -> Ordering { self.as_ptr().cmp(&other.as_ptr()) } } #[stable(feature = "nonnull", since = "1.25.0")] impl PartialOrd for NonNull { #[inline] fn partial_cmp(&self, other: &Self) -> Option { self.as_ptr().partial_cmp(&other.as_ptr()) } } #[stable(feature = "nonnull", since = "1.25.0")] impl hash::Hash for NonNull { #[inline] fn hash(&self, state: &mut H) { self.as_ptr().hash(state) } } #[unstable(feature = "ptr_internals", issue = "none")] impl From> for NonNull { #[inline] fn from(unique: Unique) -> Self { unsafe { NonNull::new_unchecked(unique.as_ptr()) } } } #[stable(feature = "nonnull", since = "1.25.0")] impl From<&mut T> for NonNull { #[inline] fn from(reference: &mut T) -> Self { unsafe { NonNull { pointer: reference as *mut T } } } } #[stable(feature = "nonnull", since = "1.25.0")] impl From<&T> for NonNull { #[inline] fn from(reference: &T) -> Self { unsafe { NonNull { pointer: reference as *const T } } } }