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>>>());Implementations§
Source§impl<T: PointeeSized> NonNull<T>
impl<T: PointeeSized> NonNull<T>
1.89.0 (const: 1.89.0) · Sourcepub const fn from_ref(r: &T) -> Self
pub const fn from_ref(r: &T) -> Self
Converts a reference to a NonNull pointer.
1.89.0 (const: 1.89.0) · Sourcepub const fn from_mut(r: &mut T) -> Self
pub const fn from_mut(r: &mut T) -> Self
Converts a mutable reference to a NonNull pointer.
1.25.0 (const: 1.32.0) · Sourcepub const fn as_ptr(self) -> *mut T
pub const fn as_ptr(self) -> *mut T
Acquires the underlying *mut pointer.
§Examples
1.25.0 (const: 1.73.0) · Sourcepub const unsafe fn as_ref<'a>(&self) -> &'a T
pub const unsafe fn as_ref<'a>(&self) -> &'a T
Returns a shared reference to the value. If the value may be uninitialized, as_uninit_ref
must be used instead.
For the mutable counterpart see as_mut.
§Safety
When calling this method, you have to ensure that the pointer is convertible to a reference.
§Examples
1.25.0 (const: 1.83.0) · Sourcepub const unsafe fn as_mut<'a>(&mut self) -> &'a mut T
pub const unsafe fn as_mut<'a>(&mut self) -> &'a mut T
Returns a unique reference to the value. If the value may be uninitialized, as_uninit_mut
must be used instead.
For the shared counterpart see as_ref.
§Safety
When calling this method, you have to ensure that the pointer is convertible to a reference.
§Examples
1.27.0 (const: 1.36.0) · Sourcepub const fn cast<U>(self) -> NonNull<U>
pub const fn cast<U>(self) -> NonNull<U>
Casts to a pointer of another type.
§Examples
1.80.0 (const: 1.80.0) · Sourcepub const unsafe fn add(self, count: usize) -> Selfwhere
T: Sized,
pub const unsafe fn add(self, count: usize) -> Selfwhere
T: Sized,
Adds an offset to a pointer (convenience for .offset(count as isize)).
count is in units of T; e.g., a count of 3 represents a pointer
offset of 3 * size_of::<T>() bytes.
§Safety
If any of the following conditions are violated, the result is Undefined Behavior:
-
The computed offset,
count * size_of::<T>()bytes, must not overflowisize. -
If the computed offset is non-zero, then
selfmust be derived from a pointer to some allocation, and the entire memory range betweenselfand the result must be in bounds of that allocation. In particular, this range must not “wrap around” the edge of the address space.
Allocations can never be larger than isize::MAX bytes, so if the computed offset
stays in bounds of the allocation, it is guaranteed to satisfy the first requirement.
This implies, for instance, that vec.as_ptr().add(vec.len()) (for vec: Vec<T>) is always
safe.
§Examples
Trait Implementations§
1.25.0 · Source§impl<T: PointeeSized> Clone for NonNull<T>
impl<T: PointeeSized> Clone for NonNull<T>
1.25.0 · Source§impl<T: PointeeSized> PartialEq for NonNull<T>
impl<T: PointeeSized> PartialEq for NonNull<T>
impl<T: PointeeSized> Copy for NonNull<T>
impl<T: PointeeSized> !Send for NonNull<T>
NonNull pointers are not Send because the data they reference may be aliased.
impl<T: PointeeSized> !Sync for NonNull<T>
NonNull pointers are not Sync because the data they reference may be aliased.