use hash;
use marker::{PhantomData, Unsize};
use mem;
-use nonzero::NonZero;
+#[allow(deprecated)] use nonzero::NonZero;
use cmp::Ordering::{self, Less, Equal, Greater};
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_ptr_null")]
pub const fn null<T>() -> *const T { 0 as *const T }
/// Creates a null mutable raw pointer.
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_ptr_null_mut")]
pub const fn null_mut<T>() -> *mut T { 0 as *mut T }
/// Swaps the values at two mutable locations of the same type, without
-/// deinitializing either. They may overlap, unlike `mem::swap` which is
-/// otherwise equivalent.
+/// deinitializing either.
+///
+/// The values pointed at by `x` and `y` may overlap, unlike `mem::swap` which
+/// is otherwise equivalent. If the values do overlap, then the overlapping
+/// region of memory from `x` will be used. This is demonstrated in the
+/// examples section below.
///
/// # Safety
///
/// as arguments.
///
/// Ensure that these pointers are valid before calling `swap`.
+///
+/// # Examples
+///
+/// Swapping two non-overlapping regions:
+///
+/// ```
+/// use std::ptr;
+///
+/// let mut array = [0, 1, 2, 3];
+///
+/// let x = array[0..].as_mut_ptr() as *mut [u32; 2];
+/// let y = array[2..].as_mut_ptr() as *mut [u32; 2];
+///
+/// unsafe {
+/// ptr::swap(x, y);
+/// assert_eq!([2, 3, 0, 1], array);
+/// }
+/// ```
+///
+/// Swapping two overlapping regions:
+///
+/// ```
+/// use std::ptr;
+///
+/// let mut array = [0, 1, 2, 3];
+///
+/// let x = array[0..].as_mut_ptr() as *mut [u32; 3];
+/// let y = array[1..].as_mut_ptr() as *mut [u32; 3];
+///
+/// unsafe {
+/// ptr::swap(x, y);
+/// assert_eq!([1, 0, 1, 2], array);
+/// }
+/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
/// Basic usage:
///
/// ```
-/// #![feature(swap_nonoverlapping)]
-///
/// use std::ptr;
///
/// let mut x = [1, 2, 3, 4];
/// assert_eq!(y, [1, 2, 9]);
/// ```
#[inline]
-#[unstable(feature = "swap_nonoverlapping", issue = "42818")]
+#[stable(feature = "swap_nonoverlapping", since = "1.27.0")]
pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
let x = x as *mut u8;
let y = y as *mut u8;
impl<T: ?Sized> *const T {
/// Returns `true` if the pointer is null.
///
+ /// Note that unsized types have many possible null pointers, as only the
+ /// raw data pointer is considered, not their length, vtable, etc.
+ /// Therefore, two pointers that are null may still not compare equal to
+ /// each other.
+ ///
/// # Examples
///
/// Basic usage:
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- pub fn is_null(self) -> bool where T: Sized {
- self == null()
+ pub fn is_null(self) -> bool {
+ // Compare via a cast to a thin pointer, so fat pointers are only
+ // considering their "data" part for null-ness.
+ (self as *const u8) == null()
}
/// Returns `None` if the pointer is null, or else returns a reference to
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[inline]
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
- // Check for null via a cast to a thin pointer, so fat pointers are only
- // considering their "data" part for null-ness.
- if (self as *const u8).is_null() {
+ if self.is_null() {
None
} else {
Some(&*self)
/// * Both the starting and resulting pointer must be either in bounds or one
/// byte past the end of an allocated object.
///
- /// * The computed offset, **in bytes**, cannot overflow or underflow an
- /// `isize`.
+ /// * The computed offset, **in bytes**, cannot overflow an `isize`.
///
/// * The offset being in bounds cannot rely on "wrapping around" the address
/// space. That is, the infinite-precision sum, **in bytes** must fit in a usize.
/// `mem::size_of::<T>()` then the result of the division is rounded towards
/// zero.
///
- /// This function returns `None` if `T` is a zero-sized typed.
+ /// This function returns `None` if `T` is a zero-sized type.
///
/// # Examples
///
///
/// ```
/// #![feature(offset_to)]
+ /// #![allow(deprecated)]
///
/// fn main() {
/// let a = [0; 5];
/// }
/// ```
#[unstable(feature = "offset_to", issue = "41079")]
+ #[rustc_deprecated(since = "1.27.0", reason = "Replaced by `wrapping_offset_from`, with the \
+ opposite argument order. If you're writing unsafe code, consider `offset_from`.")]
#[inline]
pub fn offset_to(self, other: *const T) -> Option<isize> where T: Sized {
let size = mem::size_of::<T>();
if size == 0 {
None
} else {
- let diff = (other as isize).wrapping_sub(self as isize);
- Some(diff / size as isize)
+ Some(other.wrapping_offset_from(self))
}
}
+ /// Calculates the distance between two pointers. The returned value is in
+ /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+ ///
+ /// This function is the inverse of [`offset`].
+ ///
+ /// [`offset`]: #method.offset
+ /// [`wrapping_offset_from`]: #method.wrapping_offset_from
+ ///
+ /// # Safety
+ ///
+ /// If any of the following conditions are violated, the result is Undefined
+ /// Behavior:
+ ///
+ /// * Both the starting and other pointer must be either in bounds or one
+ /// byte past the end of the same allocated object.
+ ///
+ /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`.
+ ///
+ /// * The distance between the pointers, in bytes, must be an exact multiple
+ /// of the size of `T`.
+ ///
+ /// * The distance being in bounds cannot rely on "wrapping around" the address space.
+ ///
+ /// The compiler and standard library generally try to ensure allocations
+ /// never reach a size where an offset is a concern. For instance, `Vec`
+ /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
+ /// `ptr_into_vec.offset_from(vec.as_ptr())` is always safe.
+ ///
+ /// Most platforms fundamentally can't even construct such an allocation.
+ /// For instance, no known 64-bit platform can ever serve a request
+ /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
+ /// However, some 32-bit and 16-bit platforms may successfully serve a request for
+ /// more than `isize::MAX` bytes with things like Physical Address
+ /// Extension. As such, memory acquired directly from allocators or memory
+ /// mapped files *may* be too large to handle with this function.
+ ///
+ /// Consider using [`wrapping_offset_from`] instead if these constraints are
+ /// difficult to satisfy. The only advantage of this method is that it
+ /// enables more aggressive compiler optimizations.
+ ///
+ /// # Panics
+ ///
+ /// This function panics if `T` is a Zero-Sized Type ("ZST").
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(ptr_offset_from)]
+ ///
+ /// let a = [0; 5];
+ /// let ptr1: *const i32 = &a[1];
+ /// let ptr2: *const i32 = &a[3];
+ /// unsafe {
+ /// assert_eq!(ptr2.offset_from(ptr1), 2);
+ /// assert_eq!(ptr1.offset_from(ptr2), -2);
+ /// assert_eq!(ptr1.offset(2), ptr2);
+ /// assert_eq!(ptr2.offset(-2), ptr1);
+ /// }
+ /// ```
+ #[unstable(feature = "ptr_offset_from", issue = "41079")]
+ #[inline]
+ pub unsafe fn offset_from(self, origin: *const T) -> isize where T: Sized {
+ let pointee_size = mem::size_of::<T>();
+ assert!(0 < pointee_size && pointee_size <= isize::max_value() as usize);
+
+ // This is the same sequence that Clang emits for pointer subtraction.
+ // It can be neither `nsw` nor `nuw` because the input is treated as
+ // unsigned but then the output is treated as signed, so neither works.
+ let d = isize::wrapping_sub(self as _, origin as _);
+ intrinsics::exact_div(d, pointee_size as _)
+ }
+
+ /// Calculates the distance between two pointers. The returned value is in
+ /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+ ///
+ /// If the address different between the two pointers is not a multiple of
+ /// `mem::size_of::<T>()` then the result of the division is rounded towards
+ /// zero.
+ ///
+ /// Though this method is safe for any two pointers, note that its result
+ /// will be mostly useless if the two pointers aren't into the same allocated
+ /// object, for example if they point to two different local variables.
+ ///
+ /// # Panics
+ ///
+ /// This function panics if `T` is a zero-sized type.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(ptr_wrapping_offset_from)]
+ ///
+ /// let a = [0; 5];
+ /// let ptr1: *const i32 = &a[1];
+ /// let ptr2: *const i32 = &a[3];
+ /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2);
+ /// assert_eq!(ptr1.wrapping_offset_from(ptr2), -2);
+ /// assert_eq!(ptr1.wrapping_offset(2), ptr2);
+ /// assert_eq!(ptr2.wrapping_offset(-2), ptr1);
+ ///
+ /// let ptr1: *const i32 = 3 as _;
+ /// let ptr2: *const i32 = 13 as _;
+ /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2);
+ /// ```
+ #[unstable(feature = "ptr_wrapping_offset_from", issue = "41079")]
+ #[inline]
+ pub fn wrapping_offset_from(self, origin: *const T) -> isize where T: Sized {
+ let pointee_size = mem::size_of::<T>();
+ assert!(0 < pointee_size && pointee_size <= isize::max_value() as usize);
+
+ let d = isize::wrapping_sub(self as _, origin as _);
+ d.wrapping_div(pointee_size as _)
+ }
+
/// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
///
/// `count` is in units of T; e.g. a `count` of 3 represents a pointer
/// * Both the starting and resulting pointer must be either in bounds or one
/// byte past the end of an allocated object.
///
- /// * The computed offset, **in bytes**, cannot overflow or underflow an
- /// `isize`.
+ /// * The computed offset, **in bytes**, cannot overflow an `isize`.
///
/// * The offset being in bounds cannot rely on "wrapping around" the address
/// space. That is, the infinite-precision sum must fit in a `usize`.
/// Basic usage:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// let s: &str = "123";
/// let ptr: *const u8 = s.as_ptr();
///
/// println!("{}", *ptr.add(2) as char);
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn add(self, count: usize) -> Self
where T: Sized,
/// Basic usage:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// let s: &str = "123";
///
/// unsafe {
/// println!("{}", *end.sub(2) as char);
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn sub(self, count: usize) -> Self
where T: Sized,
/// Basic usage:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// // Iterate using a raw pointer in increments of two elements
/// let data = [1u8, 2, 3, 4, 5];
/// let mut ptr: *const u8 = data.as_ptr();
/// ptr = ptr.wrapping_add(step);
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub fn wrapping_add(self, count: usize) -> Self
where T: Sized,
/// Basic usage:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// // Iterate using a raw pointer in increments of two elements (backwards)
/// let data = [1u8, 2, 3, 4, 5];
/// let mut ptr: *const u8 = data.as_ptr();
/// ptr = ptr.wrapping_sub(step);
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub fn wrapping_sub(self, count: usize) -> Self
where T: Sized,
/// Basic usage:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// let x = 12;
/// let y = &x as *const i32;
///
/// assert_eq!(y.read(), 12);
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn read(self) -> T
where T: Sized,
/// Basic usage:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// let x = 12;
/// let y = &x as *const i32;
///
/// assert_eq!(y.read_volatile(), 12);
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn read_volatile(self) -> T
where T: Sized,
/// Basic usage:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// let x = 12;
/// let y = &x as *const i32;
///
/// assert_eq!(y.read_unaligned(), 12);
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn read_unaligned(self) -> T
where T: Sized,
/// Efficiently create a Rust vector from an unsafe buffer:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// # #[allow(dead_code)]
/// unsafe fn from_buf_raw<T: Copy>(ptr: *const T, elts: usize) -> Vec<T> {
/// let mut dst = Vec::with_capacity(elts);
/// dst
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn copy_to(self, dest: *mut T, count: usize)
where T: Sized,
/// Efficiently create a Rust vector from an unsafe buffer:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// # #[allow(dead_code)]
/// unsafe fn from_buf_raw<T: Copy>(ptr: *const T, elts: usize) -> Vec<T> {
/// let mut dst = Vec::with_capacity(elts);
/// dst
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize)
where T: Sized,
impl<T: ?Sized> *mut T {
/// Returns `true` if the pointer is null.
///
+ /// Note that unsized types have many possible null pointers, as only the
+ /// raw data pointer is considered, not their length, vtable, etc.
+ /// Therefore, two pointers that are null may still not compare equal to
+ /// each other.
+ ///
/// # Examples
///
/// Basic usage:
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- pub fn is_null(self) -> bool where T: Sized {
- self == null_mut()
+ pub fn is_null(self) -> bool {
+ // Compare via a cast to a thin pointer, so fat pointers are only
+ // considering their "data" part for null-ness.
+ (self as *mut u8) == null_mut()
}
/// Returns `None` if the pointer is null, or else returns a reference to
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[inline]
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
- // Check for null via a cast to a thin pointer, so fat pointers are only
- // considering their "data" part for null-ness.
- if (self as *const u8).is_null() {
+ if self.is_null() {
None
} else {
Some(&*self)
/// * Both the starting and resulting pointer must be either in bounds or one
/// byte past the end of an allocated object.
///
- /// * The computed offset, **in bytes**, cannot overflow or underflow an
- /// `isize`.
+ /// * The computed offset, **in bytes**, cannot overflow an `isize`.
///
/// * The offset being in bounds cannot rely on "wrapping around" the address
/// space. That is, the infinite-precision sum, **in bytes** must fit in a usize.
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[inline]
pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> {
- // Check for null via a cast to a thin pointer, so fat pointers are only
- // considering their "data" part for null-ness.
- if (self as *mut u8).is_null() {
+ if self.is_null() {
None
} else {
Some(&mut *self)
/// `mem::size_of::<T>()` then the result of the division is rounded towards
/// zero.
///
- /// This function returns `None` if `T` is a zero-sized typed.
+ /// This function returns `None` if `T` is a zero-sized type.
///
/// # Examples
///
///
/// ```
/// #![feature(offset_to)]
+ /// #![allow(deprecated)]
///
/// fn main() {
/// let mut a = [0; 5];
/// }
/// ```
#[unstable(feature = "offset_to", issue = "41079")]
+ #[rustc_deprecated(since = "1.27.0", reason = "Replaced by `wrapping_offset_from`, with the \
+ opposite argument order. If you're writing unsafe code, consider `offset_from`.")]
#[inline]
pub fn offset_to(self, other: *const T) -> Option<isize> where T: Sized {
let size = mem::size_of::<T>();
if size == 0 {
None
} else {
- let diff = (other as isize).wrapping_sub(self as isize);
- Some(diff / size as isize)
+ Some(other.wrapping_offset_from(self))
}
}
+ /// Calculates the distance between two pointers. The returned value is in
+ /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+ ///
+ /// This function is the inverse of [`offset`].
+ ///
+ /// [`offset`]: #method.offset-1
+ /// [`wrapping_offset_from`]: #method.wrapping_offset_from-1
+ ///
+ /// # Safety
+ ///
+ /// If any of the following conditions are violated, the result is Undefined
+ /// Behavior:
+ ///
+ /// * Both the starting and other pointer must be either in bounds or one
+ /// byte past the end of the same allocated object.
+ ///
+ /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`.
+ ///
+ /// * The distance between the pointers, in bytes, must be an exact multiple
+ /// of the size of `T`.
+ ///
+ /// * The distance being in bounds cannot rely on "wrapping around" the address space.
+ ///
+ /// The compiler and standard library generally try to ensure allocations
+ /// never reach a size where an offset is a concern. For instance, `Vec`
+ /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
+ /// `ptr_into_vec.offset_from(vec.as_ptr())` is always safe.
+ ///
+ /// Most platforms fundamentally can't even construct such an allocation.
+ /// For instance, no known 64-bit platform can ever serve a request
+ /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
+ /// However, some 32-bit and 16-bit platforms may successfully serve a request for
+ /// more than `isize::MAX` bytes with things like Physical Address
+ /// Extension. As such, memory acquired directly from allocators or memory
+ /// mapped files *may* be too large to handle with this function.
+ ///
+ /// Consider using [`wrapping_offset_from`] instead if these constraints are
+ /// difficult to satisfy. The only advantage of this method is that it
+ /// enables more aggressive compiler optimizations.
+ ///
+ /// # Panics
+ ///
+ /// This function panics if `T` is a Zero-Sized Type ("ZST").
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(ptr_offset_from)]
+ ///
+ /// let mut a = [0; 5];
+ /// let ptr1: *mut i32 = &mut a[1];
+ /// let ptr2: *mut i32 = &mut a[3];
+ /// unsafe {
+ /// assert_eq!(ptr2.offset_from(ptr1), 2);
+ /// assert_eq!(ptr1.offset_from(ptr2), -2);
+ /// assert_eq!(ptr1.offset(2), ptr2);
+ /// assert_eq!(ptr2.offset(-2), ptr1);
+ /// }
+ /// ```
+ #[unstable(feature = "ptr_offset_from", issue = "41079")]
+ #[inline]
+ pub unsafe fn offset_from(self, origin: *const T) -> isize where T: Sized {
+ (self as *const T).offset_from(origin)
+ }
+
+ /// Calculates the distance between two pointers. The returned value is in
+ /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+ ///
+ /// If the address different between the two pointers is not a multiple of
+ /// `mem::size_of::<T>()` then the result of the division is rounded towards
+ /// zero.
+ ///
+ /// Though this method is safe for any two pointers, note that its result
+ /// will be mostly useless if the two pointers aren't into the same allocated
+ /// object, for example if they point to two different local variables.
+ ///
+ /// # Panics
+ ///
+ /// This function panics if `T` is a zero-sized type.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(ptr_wrapping_offset_from)]
+ ///
+ /// let mut a = [0; 5];
+ /// let ptr1: *mut i32 = &mut a[1];
+ /// let ptr2: *mut i32 = &mut a[3];
+ /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2);
+ /// assert_eq!(ptr1.wrapping_offset_from(ptr2), -2);
+ /// assert_eq!(ptr1.wrapping_offset(2), ptr2);
+ /// assert_eq!(ptr2.wrapping_offset(-2), ptr1);
+ ///
+ /// let ptr1: *mut i32 = 3 as _;
+ /// let ptr2: *mut i32 = 13 as _;
+ /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2);
+ /// ```
+ #[unstable(feature = "ptr_wrapping_offset_from", issue = "41079")]
+ #[inline]
+ pub fn wrapping_offset_from(self, origin: *const T) -> isize where T: Sized {
+ (self as *const T).wrapping_offset_from(origin)
+ }
+
/// Computes the byte offset that needs to be applied in order to
/// make the pointer aligned to `align`.
/// If it is not possible to align the pointer, the implementation returns
/// * Both the starting and resulting pointer must be either in bounds or one
/// byte past the end of an allocated object.
///
- /// * The computed offset, **in bytes**, cannot overflow or underflow an
- /// `isize`.
+ /// * The computed offset, **in bytes**, cannot overflow an `isize`.
///
/// * The offset being in bounds cannot rely on "wrapping around" the address
/// space. That is, the infinite-precision sum must fit in a `usize`.
/// Basic usage:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// let s: &str = "123";
/// let ptr: *const u8 = s.as_ptr();
///
/// println!("{}", *ptr.add(2) as char);
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn add(self, count: usize) -> Self
where T: Sized,
/// Basic usage:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// let s: &str = "123";
///
/// unsafe {
/// println!("{}", *end.sub(2) as char);
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn sub(self, count: usize) -> Self
where T: Sized,
/// Basic usage:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// // Iterate using a raw pointer in increments of two elements
/// let data = [1u8, 2, 3, 4, 5];
/// let mut ptr: *const u8 = data.as_ptr();
/// ptr = ptr.wrapping_add(step);
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub fn wrapping_add(self, count: usize) -> Self
where T: Sized,
/// Basic usage:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// // Iterate using a raw pointer in increments of two elements (backwards)
/// let data = [1u8, 2, 3, 4, 5];
/// let mut ptr: *const u8 = data.as_ptr();
/// ptr = ptr.wrapping_sub(step);
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub fn wrapping_sub(self, count: usize) -> Self
where T: Sized,
/// Basic usage:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// let x = 12;
/// let y = &x as *const i32;
///
/// assert_eq!(y.read(), 12);
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn read(self) -> T
where T: Sized,
/// Beyond accepting a raw pointer, this is unsafe because it semantically
/// moves the value out of `self` without preventing further usage of `self`.
/// If `T` is not `Copy`, then care must be taken to ensure that the value at
- /// `src` is not used before the data is overwritten again (e.g. with `write`,
+ /// `self` is not used before the data is overwritten again (e.g. with `write`,
/// `write_bytes`, or `copy`). Note that `*self = foo` counts as a use
/// because it will attempt to drop the value previously at `*self`.
///
/// Basic usage:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// let x = 12;
/// let y = &x as *const i32;
///
/// assert_eq!(y.read_volatile(), 12);
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn read_volatile(self) -> T
where T: Sized,
/// Basic usage:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// let x = 12;
/// let y = &x as *const i32;
///
/// assert_eq!(y.read_unaligned(), 12);
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn read_unaligned(self) -> T
where T: Sized,
/// Efficiently create a Rust vector from an unsafe buffer:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// # #[allow(dead_code)]
/// unsafe fn from_buf_raw<T: Copy>(ptr: *const T, elts: usize) -> Vec<T> {
/// let mut dst = Vec::with_capacity(elts);
/// dst
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn copy_to(self, dest: *mut T, count: usize)
where T: Sized,
/// Efficiently create a Rust vector from an unsafe buffer:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// # #[allow(dead_code)]
/// unsafe fn from_buf_raw<T: Copy>(ptr: *const T, elts: usize) -> Vec<T> {
/// let mut dst = Vec::with_capacity(elts);
/// dst
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize)
where T: Sized,
/// Efficiently create a Rust vector from an unsafe buffer:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// # #[allow(dead_code)]
/// unsafe fn from_buf_raw<T: Copy>(ptr: *const T, elts: usize) -> Vec<T> {
- /// let mut dst = Vec::with_capacity(elts);
+ /// let mut dst: Vec<T> = Vec::with_capacity(elts);
/// dst.set_len(elts);
/// dst.as_mut_ptr().copy_from(ptr, elts);
/// dst
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn copy_from(self, src: *const T, count: usize)
where T: Sized,
/// Efficiently create a Rust vector from an unsafe buffer:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// # #[allow(dead_code)]
/// unsafe fn from_buf_raw<T: Copy>(ptr: *const T, elts: usize) -> Vec<T> {
- /// let mut dst = Vec::with_capacity(elts);
+ /// let mut dst: Vec<T> = Vec::with_capacity(elts);
/// dst.set_len(elts);
/// dst.as_mut_ptr().copy_from_nonoverlapping(ptr, elts);
/// dst
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn copy_from_nonoverlapping(self, src: *const T, count: usize)
where T: Sized,
///
/// This has all the same safety problems as `ptr::read` with respect to
/// invalid pointers, types, and double drops.
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn drop_in_place(self) {
drop_in_place(self)
/// Basic usage:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// let mut x = 0;
/// let y = &mut x as *mut i32;
/// let z = 12;
/// assert_eq!(y.read(), 12);
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn write(self, val: T)
where T: Sized,
/// # Examples
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// let mut vec = vec![0; 4];
/// unsafe {
/// let vec_ptr = vec.as_mut_ptr();
/// }
/// assert_eq!(vec, [b'a', b'a', 0, 0]);
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn write_bytes(self, val: u8, count: usize)
where T: Sized,
/// Basic usage:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// let mut x = 0;
/// let y = &mut x as *mut i32;
/// let z = 12;
/// assert_eq!(y.read_volatile(), 12);
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn write_volatile(self, val: T)
where T: Sized,
/// allocations or resources, so care must be taken not to overwrite an object
/// that should be dropped.
///
- /// Additionally, it does not drop `src`. Semantically, `src` is moved into the
- /// location pointed to by `dst`.
+ /// Additionally, it does not drop `self`. Semantically, `self` is moved into the
+ /// location pointed to by `val`.
///
/// This is appropriate for initializing uninitialized memory, or overwriting
/// memory that has previously been `read` from.
/// Basic usage:
///
/// ```
- /// #![feature(pointer_methods)]
- ///
/// let mut x = 0;
/// let y = &mut x as *mut i32;
/// let z = 12;
/// assert_eq!(y.read_unaligned(), 12);
/// }
/// ```
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn write_unaligned(self, val: T)
where T: Sized,
///
/// This is only unsafe because it accepts a raw pointer.
/// Otherwise, this operation is identical to `mem::replace`.
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn replace(self, src: T) -> T
where T: Sized,
/// as arguments.
///
/// Ensure that these pointers are valid before calling `swap`.
- #[unstable(feature = "pointer_methods", issue = "43941")]
+ #[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn swap(self, with: *mut T)
where T: Sized,
/// its owning Unique.
///
/// If you're uncertain of whether it's correct to use `Unique` for your purposes,
-/// consider using `Shared`, which has weaker semantics.
+/// consider using `NonNull`, which has weaker semantics.
///
/// 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
///
/// Unlike `*mut T`, `Unique<T>` is covariant over `T`. This should always be correct
/// for any type which upholds Unique's aliasing requirements.
-#[allow(missing_debug_implementations)]
-#[unstable(feature = "unique", reason = "needs an RFC to flesh out design",
- issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0",
+ reason = "use NonNull instead and consider PhantomData<T> \
+ (if you also use #[may_dangle]), Send, and/or Sync")]
+#[allow(deprecated)]
+#[doc(hidden)]
pub struct Unique<T: ?Sized> {
pointer: NonZero<*const T>,
// NOTE: this marker has no consequences for variance, but is necessary
_marker: PhantomData<T>,
}
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized> fmt::Debug for Unique<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Pointer::fmt(&self.as_ptr(), f)
+ }
+}
+
/// `Unique` pointers are `Send` if `T` is `Send` because the data they
/// reference is unaliased. Note that this aliasing invariant is
/// unenforced by the type system; the abstraction using the
/// `Unique` must enforce it.
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
/// `Unique` pointers are `Sync` if `T` is `Sync` because the data they
/// reference is unaliased. Note that this aliasing invariant is
/// unenforced by the type system; the abstraction using the
/// `Unique` must enforce it.
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: Sized> Unique<T> {
/// Creates a new `Unique` that is dangling, but well-aligned.
///
/// This is useful for initializing types which lazily allocate, like
/// `Vec::new` does.
- pub fn empty() -> Self {
+ // FIXME: rename to dangling() to match NonNull?
+ pub const fn empty() -> Self {
unsafe {
- let ptr = mem::align_of::<T>() as *mut T;
- Unique::new_unchecked(ptr)
+ Unique::new_unchecked(mem::align_of::<T>() as *mut T)
}
}
}
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
+#[allow(deprecated)]
impl<T: ?Sized> Unique<T> {
/// Creates a new `Unique`.
///
/// # Safety
///
/// `ptr` must be non-null.
- #[unstable(feature = "unique", issue = "27730")]
- #[rustc_const_unstable(feature = "const_unique_new")]
pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
- Unique { pointer: NonZero::new_unchecked(ptr), _marker: PhantomData }
+ Unique { pointer: NonZero(ptr as _), _marker: PhantomData }
}
/// Creates a new `Unique` if `ptr` is non-null.
pub fn new(ptr: *mut T) -> Option<Self> {
- NonZero::new(ptr as *const T).map(|nz| Unique { pointer: nz, _marker: PhantomData })
+ if !ptr.is_null() {
+ Some(Unique { pointer: NonZero(ptr as _), _marker: PhantomData })
+ } else {
+ None
+ }
}
/// Acquires the underlying `*mut` pointer.
pub fn as_ptr(self) -> *mut T {
- self.pointer.get() as *mut T
+ self.pointer.0 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.ptr()`.
+ /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
pub unsafe fn as_ref(&self) -> &T {
&*self.as_ptr()
}
///
/// 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.ptr()`.
+ /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
pub unsafe fn as_mut(&mut self) -> &mut T {
&mut *self.as_ptr()
}
}
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized> Clone for Unique<T> {
fn clone(&self) -> Self {
*self
}
}
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized> Copy for Unique<T> { }
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> { }
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized> fmt::Pointer for Unique<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Pointer::fmt(&self.as_ptr(), f)
}
}
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
+#[allow(deprecated)]
impl<'a, T: ?Sized> From<&'a mut T> for Unique<T> {
fn from(reference: &'a mut T) -> Self {
- Unique { pointer: NonZero::from(reference), _marker: PhantomData }
+ Unique { pointer: NonZero(reference as _), _marker: PhantomData }
}
}
-#[unstable(feature = "unique", issue = "27730")]
+#[unstable(feature = "ptr_internals", issue = "0")]
+#[allow(deprecated)]
impl<'a, T: ?Sized> From<&'a T> for Unique<T> {
fn from(reference: &'a T) -> Self {
- Unique { pointer: NonZero::from(reference), _marker: PhantomData }
+ Unique { pointer: NonZero(reference as _), _marker: PhantomData }
+ }
+}
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<'a, T: ?Sized> From<NonNull<T>> for Unique<T> {
+ fn from(p: NonNull<T>) -> Self {
+ Unique { pointer: p.pointer, _marker: PhantomData }
}
}
-/// A wrapper around a raw `*mut T` that indicates that the possessor
-/// of this wrapper has shared ownership of the referent. Useful for
-/// building abstractions like `Rc<T>`, `Arc<T>`, or doubly-linked lists, which
-/// internally use aliased raw pointers to manage the memory that they own.
+/// `*mut T` but non-zero and covariant.
///
-/// This is similar to `Unique`, except that it doesn't make any aliasing
-/// guarantees, and doesn't derive Send and Sync. Note that unlike `&T`,
-/// Shared has no special mutability requirements. Shared may mutate data
-/// aliased by other Shared pointers. More precise rules require Rust to
-/// develop an actual aliasing model.
+/// 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<Shared<T>>` has the same size as `Shared<T>`.
+/// 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`, `Shared<T>` is covariant over `T`. If this is incorrect
+/// Unlike `*mut T`, `NonNull<T>` 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<Cell<T>>` or `PhantomData<&'a mut T>`.
-/// Usually this won't be necessary; covariance is correct for Rc, Arc, and LinkedList
-/// because they provide a public API that follows the normal shared XOR mutable
-/// rules of Rust.
-#[allow(missing_debug_implementations)]
-#[unstable(feature = "shared", reason = "needs an RFC to flesh out design",
- issue = "27730")]
-pub struct Shared<T: ?Sized> {
- pointer: NonZero<*const T>,
- // NOTE: this marker has no consequences for variance, but is necessary
- // for dropck to understand that we logically own a `T`.
- //
- // For details, see:
- // https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data
- _marker: PhantomData<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.
+#[stable(feature = "nonnull", since = "1.25.0")]
+pub struct NonNull<T: ?Sized> {
+ #[allow(deprecated)] pointer: NonZero<*const T>,
}
-/// `Shared` pointers are not `Send` because the data they reference may be aliased.
+/// `NonNull` pointers are not `Send` because the data they reference may be aliased.
// NB: This impl is unnecessary, but should provide better error messages.
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: ?Sized> !Send for Shared<T> { }
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> !Send for NonNull<T> { }
-/// `Shared` pointers are not `Sync` because the data they reference may be aliased.
+/// `NonNull` pointers are not `Sync` because the data they reference may be aliased.
// NB: This impl is unnecessary, but should provide better error messages.
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: ?Sized> !Sync for Shared<T> { }
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> !Sync for NonNull<T> { }
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: Sized> Shared<T> {
- /// Creates a new `Shared` that is dangling, but well-aligned.
+impl<T: Sized> NonNull<T> {
+ /// Creates a new `NonNull` that is dangling, but well-aligned.
///
/// This is useful for initializing types which lazily allocate, like
/// `Vec::new` does.
- pub fn empty() -> Self {
+ #[stable(feature = "nonnull", since = "1.25.0")]
+ pub fn dangling() -> Self {
unsafe {
let ptr = mem::align_of::<T>() as *mut T;
- Shared::new_unchecked(ptr)
+ NonNull::new_unchecked(ptr)
}
}
}
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: ?Sized> Shared<T> {
- /// Creates a new `Shared`.
+#[allow(deprecated)]
+impl<T: ?Sized> NonNull<T> {
+ /// Creates a new `NonNull`.
///
/// # Safety
///
/// `ptr` must be non-null.
- #[unstable(feature = "shared", issue = "27730")]
- #[rustc_const_unstable(feature = "const_shared_new")]
+ #[stable(feature = "nonnull", since = "1.25.0")]
pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
- Shared { pointer: NonZero::new_unchecked(ptr), _marker: PhantomData }
+ NonNull { pointer: NonZero(ptr as _) }
}
- /// Creates a new `Shared` if `ptr` is non-null.
+ /// Creates a new `NonNull` if `ptr` is non-null.
+ #[stable(feature = "nonnull", since = "1.25.0")]
pub fn new(ptr: *mut T) -> Option<Self> {
- NonZero::new(ptr as *const T).map(|nz| Shared { pointer: nz, _marker: PhantomData })
+ if !ptr.is_null() {
+ Some(NonNull { pointer: NonZero(ptr as _) })
+ } else {
+ None
+ }
}
/// Acquires the underlying `*mut` pointer.
+ #[stable(feature = "nonnull", since = "1.25.0")]
pub fn as_ptr(self) -> *mut T {
- self.pointer.get() as *mut T
+ self.pointer.0 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.ptr()`.
+ /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
+ #[stable(feature = "nonnull", since = "1.25.0")]
pub unsafe fn as_ref(&self) -> &T {
&*self.as_ptr()
}
///
/// 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.ptr_mut()`.
+ /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
+ #[stable(feature = "nonnull", since = "1.25.0")]
pub unsafe fn as_mut(&mut self) -> &mut T {
&mut *self.as_ptr()
}
- /// Acquires the underlying pointer as a `*mut` pointer.
- #[rustc_deprecated(since = "1.19", reason = "renamed to `as_ptr` for ergonomics/consistency")]
- #[unstable(feature = "shared", issue = "27730")]
- pub unsafe fn as_mut_ptr(&self) -> *mut T {
- self.as_ptr()
+ /// Cast to a pointer of another type
+ #[stable(feature = "nonnull_cast", since = "1.27.0")]
+ pub fn cast<U>(self) -> NonNull<U> {
+ unsafe {
+ NonNull::new_unchecked(self.as_ptr() as *mut U)
+ }
+ }
+
+ /// Cast to an `Opaque` pointer
+ #[unstable(feature = "allocator_api", issue = "32838")]
+ pub fn as_opaque(self) -> NonNull<::alloc::Opaque> {
+ unsafe {
+ NonNull::new_unchecked(self.as_ptr() as _)
+ }
}
}
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: ?Sized> Clone for Shared<T> {
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> Clone for NonNull<T> {
fn clone(&self) -> Self {
*self
}
}
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: ?Sized> Copy for Shared<T> { }
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> Copy for NonNull<T> { }
+
+#[unstable(feature = "coerce_unsized", issue = "27732")]
+impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> { }
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: ?Sized, U: ?Sized> CoerceUnsized<Shared<U>> for Shared<T> where T: Unsize<U> { }
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> fmt::Debug for NonNull<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Pointer::fmt(&self.as_ptr(), f)
+ }
+}
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: ?Sized> fmt::Pointer for Shared<T> {
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> fmt::Pointer for NonNull<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Pointer::fmt(&self.as_ptr(), f)
}
}
-#[unstable(feature = "shared", issue = "27730")]
-impl<T: ?Sized> From<Unique<T>> for Shared<T> {
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> Eq for NonNull<T> {}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> PartialEq for NonNull<T> {
+ fn eq(&self, other: &Self) -> bool {
+ self.as_ptr() == other.as_ptr()
+ }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> Ord for NonNull<T> {
+ fn cmp(&self, other: &Self) -> Ordering {
+ self.as_ptr().cmp(&other.as_ptr())
+ }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> PartialOrd for NonNull<T> {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ self.as_ptr().partial_cmp(&other.as_ptr())
+ }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> hash::Hash for NonNull<T> {
+ fn hash<H: hash::Hasher>(&self, state: &mut H) {
+ self.as_ptr().hash(state)
+ }
+}
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
fn from(unique: Unique<T>) -> Self {
- Shared { pointer: unique.pointer, _marker: PhantomData }
+ NonNull { pointer: unique.pointer }
}
}
-#[unstable(feature = "shared", issue = "27730")]
-impl<'a, T: ?Sized> From<&'a mut T> for Shared<T> {
+#[stable(feature = "nonnull", since = "1.25.0")]
+#[allow(deprecated)]
+impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> {
fn from(reference: &'a mut T) -> Self {
- Shared { pointer: NonZero::from(reference), _marker: PhantomData }
+ NonNull { pointer: NonZero(reference as _) }
}
}
-#[unstable(feature = "shared", issue = "27730")]
-impl<'a, T: ?Sized> From<&'a T> for Shared<T> {
+#[stable(feature = "nonnull", since = "1.25.0")]
+#[allow(deprecated)]
+impl<'a, T: ?Sized> From<&'a T> for NonNull<T> {
fn from(reference: &'a T) -> Self {
- Shared { pointer: NonZero::from(reference), _marker: PhantomData }
+ NonNull { pointer: NonZero(reference as _) }
}
}