NonNull

Struct NonNull 

1.25.0 · Source
pub struct NonNull<T: PointeeSized> { /* private fields */ }
Expand description

*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<T>, 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<NonNull<T>> has the same size as *mut T. However the pointer may still dangle if it isn’t dereferenced.

Unlike *mut T, NonNull<T> is covariant over T. This is usually the correct choice for most data structures and safe abstractions, such as Box, Rc, Arc, Vec, and LinkedList.

In rare cases, if your type exposes a way to mutate the value of T through a NonNull<T>, and you need to prevent unsoundness from variance (for example, if T could be a reference with a shorter lifetime), you should add a field to make your type invariant, such as PhantomData<Cell<T>> or PhantomData<&'a mut T>.

Example of a type that must be invariant:

use std::cell::Cell;
use std::marker::PhantomData;
struct Invariant<T> {
    ptr: std::ptr::NonNull<T>,
    _invariant: PhantomData<Cell<T>>,
}

Notice that NonNull<T> 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<T>. The same goes for creating a mutable reference from a shared reference. When using this From instance without an UnsafeCell<T>, it is your responsibility to ensure that as_mut is never called, and as_ptr is never used for mutation.

§Representation

Thanks to the null pointer optimization, NonNull<T> and Option<NonNull<T>> are guaranteed to have the same size and alignment:

use std::ptr::NonNull;

assert_eq!(size_of::<NonNull<i16>>(), size_of::<Option<NonNull<i16>>>());
assert_eq!(align_of::<NonNull<i16>>(), align_of::<Option<NonNull<i16>>>());

assert_eq!(size_of::<NonNull<str>>(), size_of::<Option<NonNull<str>>>());
assert_eq!(align_of::<NonNull<str>>(), align_of::<Option<NonNull<str>>>());

Trait Implementations§

1.25.0 · Source§

impl<T: PointeeSized> !Send for NonNull<T>

NonNull pointers are not Send because the data they reference may be aliased.

1.25.0 · Source§

impl<T: PointeeSized> !Sync for NonNull<T>

NonNull pointers are not Sync because the data they reference may be aliased.

Auto Trait Implementations§

§

impl<T> Freeze for NonNull<T>
where T: ?Sized,

Blanket Implementations§

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.