about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2019-05-25 09:03:45 +0200
committerRalf Jung <post@ralfj.de>2019-05-25 09:03:45 +0200
commitc2e7eb6ff0493e89d0fcaf5bd8aa527c2e7c7c26 (patch)
tree6c905fea0a7bcde0d826ac2284e125d6812d7b70
parent524580312039e4fa5ccf91e8f7093cd755bc1aad (diff)
downloadrust-c2e7eb6ff0493e89d0fcaf5bd8aa527c2e7c7c26.tar.gz
rust-c2e7eb6ff0493e89d0fcaf5bd8aa527c2e7c7c26.zip
split core::ptr module into multiple files
-rw-r--r--src/libcore/ptr/mod.rs (renamed from src/libcore/ptr.rs)395
-rw-r--r--src/libcore/ptr/non_null.rs226
-rw-r--r--src/libcore/ptr/unique.rs180
3 files changed, 414 insertions, 387 deletions
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr/mod.rs
index 4bb4d3ee466..80ac67d8eb5 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr/mod.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-filelength
-
 //! Manually manage memory through raw pointers.
 //!
 //! *[See also the pointer primitive types](../../std/primitive.pointer.html).*
@@ -65,14 +63,10 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use crate::convert::From;
 use crate::intrinsics;
-use crate::ops::{CoerceUnsized, DispatchFromDyn};
 use crate::fmt;
 use crate::hash;
-use crate::marker::{PhantomData, Unsize};
 use crate::mem::{self, MaybeUninit};
-
 use crate::cmp::Ordering::{self, Less, Equal, Greater};
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -84,6 +78,14 @@ pub use crate::intrinsics::copy;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use crate::intrinsics::write_bytes;
 
+mod non_null;
+#[stable(feature = "nonnull", since = "1.25.0")]
+pub use non_null::NonNull;
+
+mod unique;
+#[unstable(feature = "ptr_internals", issue = "0")]
+pub use unique::Unique;
+
 /// Executes the destructor (if any) of the pointed-to value.
 ///
 /// This is semantically equivalent to calling [`ptr::read`] and discarding
@@ -2742,384 +2744,3 @@ impl<T: ?Sized> PartialOrd for *mut T {
     #[inline]
     fn ge(&self, other: &*mut T) -> bool { *self >= *other }
 }
-
-/// 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
-/// `Box<T>`, `Vec<T>`, `String`, and `HashMap<K, V>`.
-///
-/// Unlike `*mut T`, `Unique<T>` behaves "as if" it were an instance of `T`.
-/// It implements `Send`/`Sync` if `T` is `Send`/`Sync`. It also implies
-/// the kind of strong aliasing guarantees an instance of `T` can expect:
-/// the referent of the pointer should not be modified without a unique path to
-/// its owning Unique.
-///
-/// If you're uncertain of whether it's correct to use `Unique` for your purposes,
-/// 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
-/// as a discriminant -- `Option<Unique<T>>` has the same size as `Unique<T>`.
-/// However the pointer may still dangle if it isn't dereferenced.
-///
-/// Unlike `*mut T`, `Unique<T>` is covariant over `T`. This should always be correct
-/// for any type which upholds Unique's aliasing requirements.
-#[unstable(feature = "ptr_internals", issue = "0",
-           reason = "use NonNull instead and consider PhantomData<T> \
-                     (if you also use #[may_dangle]), Send, and/or Sync")]
-#[doc(hidden)]
-#[repr(transparent)]
-#[rustc_layout_scalar_valid_range_start(1)]
-pub struct Unique<T: ?Sized> {
-    pointer: *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>,
-}
-
-#[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 = "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 = "ptr_internals", issue = "0")]
-unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
-
-#[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.
-    ///
-    /// 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.
-    // FIXME: rename to dangling() to match NonNull?
-    pub const fn empty() -> Self {
-        unsafe {
-            Unique::new_unchecked(mem::align_of::<T>() as *mut T)
-        }
-    }
-}
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized> Unique<T> {
-    /// Creates a new `Unique`.
-    ///
-    /// # Safety
-    ///
-    /// `ptr` must be non-null.
-    pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
-        Unique { pointer: ptr as _, _marker: PhantomData }
-    }
-
-    /// Creates a new `Unique` if `ptr` is non-null.
-    pub fn new(ptr: *mut T) -> Option<Self> {
-        if !ptr.is_null() {
-            Some(unsafe { Unique { pointer: ptr as _, _marker: PhantomData } })
-        } else {
-            None
-        }
-    }
-
-    /// Acquires the underlying `*mut` pointer.
-    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()`.
-    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()`.
-    pub unsafe fn as_mut(&mut self) -> &mut T {
-        &mut *self.as_ptr()
-    }
-}
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized> Clone for Unique<T> {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized> Copy for Unique<T> { }
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> { }
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> { }
-
-#[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 = "ptr_internals", issue = "0")]
-impl<T: ?Sized> From<&mut T> for Unique<T> {
-    fn from(reference: &mut T) -> Self {
-        unsafe { Unique { pointer: reference as *mut T, _marker: PhantomData } }
-    }
-}
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized> From<&T> for Unique<T> {
-    fn from(reference: &T) -> Self {
-        unsafe { Unique { pointer: reference as *const T, _marker: PhantomData } }
-    }
-}
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<'a, T: ?Sized> From<NonNull<T>> for Unique<T> {
-    fn from(p: NonNull<T>) -> Self {
-        unsafe { Unique { pointer: p.pointer, _marker: PhantomData } }
-    }
-}
-
-/// `*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`. 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 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<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.
-///
-/// [`PhantomData`]: ../marker/struct.PhantomData.html
-/// [`UnsafeCell<T>`]: ../cell/struct.UnsafeCell.html
-#[stable(feature = "nonnull", since = "1.25.0")]
-#[repr(transparent)]
-#[rustc_layout_scalar_valid_range_start(1)]
-#[cfg_attr(not(stage0), rustc_nonnull_optimization_guaranteed)]
-pub struct NonNull<T: ?Sized> {
-    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<T: ?Sized> !Send for NonNull<T> { }
-
-/// `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<T: ?Sized> !Sync for NonNull<T> { }
-
-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.
-    ///
-    /// 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")]
-    #[inline]
-    pub const fn dangling() -> Self {
-        unsafe {
-            let ptr = mem::align_of::<T>() as *mut T;
-            NonNull::new_unchecked(ptr)
-        }
-    }
-}
-
-impl<T: ?Sized> NonNull<T> {
-    /// Creates a new `NonNull`.
-    ///
-    /// # Safety
-    ///
-    /// `ptr` must be non-null.
-    #[stable(feature = "nonnull", since = "1.25.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<Self> {
-        if !ptr.is_null() {
-            Some(unsafe { Self::new_unchecked(ptr) })
-        } else {
-            None
-        }
-    }
-
-    /// Acquires the underlying `*mut` pointer.
-    #[stable(feature = "nonnull", since = "1.25.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()
-    }
-
-    /// Cast to a pointer of another type
-    #[stable(feature = "nonnull_cast", since = "1.27.0")]
-    #[inline]
-    pub const fn cast<U>(self) -> NonNull<U> {
-        unsafe {
-            NonNull::new_unchecked(self.as_ptr() as *mut U)
-        }
-    }
-}
-
-#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> Clone for NonNull<T> {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-
-#[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 = "dispatch_from_dyn", issue = "0")]
-impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<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)
-    }
-}
-
-#[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)
-    }
-}
-
-#[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> {
-    #[inline]
-    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> {
-    #[inline]
-    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> {
-    #[inline]
-    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> {
-    #[inline]
-    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> {
-    #[inline]
-    fn from(unique: Unique<T>) -> Self {
-        unsafe { NonNull { pointer: unique.pointer } }
-    }
-}
-
-#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> From<&mut T> for NonNull<T> {
-    #[inline]
-    fn from(reference: &mut T) -> Self {
-        unsafe { NonNull { pointer: reference as *mut T } }
-    }
-}
-
-#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> From<&T> for NonNull<T> {
-    #[inline]
-    fn from(reference: &T) -> Self {
-        unsafe { NonNull { pointer: reference as *const T } }
-    }
-}
diff --git a/src/libcore/ptr/non_null.rs b/src/libcore/ptr/non_null.rs
new file mode 100644
index 00000000000..0a6985e334c
--- /dev/null
+++ b/src/libcore/ptr/non_null.rs
@@ -0,0 +1,226 @@
+use crate::convert::From;
+use crate::ops::{CoerceUnsized, DispatchFromDyn};
+use crate::fmt;
+use crate::hash;
+use crate::marker::Unsize;
+use crate::mem;
+use crate::ptr::Unique;
+use crate::cmp::Ordering;
+
+/// `*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`. 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 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<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.
+///
+/// [`PhantomData`]: ../marker/struct.PhantomData.html
+/// [`UnsafeCell<T>`]: ../cell/struct.UnsafeCell.html
+#[stable(feature = "nonnull", since = "1.25.0")]
+#[repr(transparent)]
+#[rustc_layout_scalar_valid_range_start(1)]
+#[cfg_attr(not(stage0), rustc_nonnull_optimization_guaranteed)]
+pub struct NonNull<T: ?Sized> {
+    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<T: ?Sized> !Send for NonNull<T> { }
+
+/// `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<T: ?Sized> !Sync for NonNull<T> { }
+
+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.
+    ///
+    /// 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")]
+    #[inline]
+    pub const fn dangling() -> Self {
+        unsafe {
+            let ptr = mem::align_of::<T>() as *mut T;
+            NonNull::new_unchecked(ptr)
+        }
+    }
+}
+
+impl<T: ?Sized> NonNull<T> {
+    /// Creates a new `NonNull`.
+    ///
+    /// # Safety
+    ///
+    /// `ptr` must be non-null.
+    #[stable(feature = "nonnull", since = "1.25.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<Self> {
+        if !ptr.is_null() {
+            Some(unsafe { Self::new_unchecked(ptr) })
+        } else {
+            None
+        }
+    }
+
+    /// Acquires the underlying `*mut` pointer.
+    #[stable(feature = "nonnull", since = "1.25.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()
+    }
+
+    /// Cast to a pointer of another type
+    #[stable(feature = "nonnull_cast", since = "1.27.0")]
+    #[inline]
+    pub const fn cast<U>(self) -> NonNull<U> {
+        unsafe {
+            NonNull::new_unchecked(self.as_ptr() as *mut U)
+        }
+    }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> Clone for NonNull<T> {
+    #[inline]
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+
+#[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 = "dispatch_from_dyn", issue = "0")]
+impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<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)
+    }
+}
+
+#[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)
+    }
+}
+
+#[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> {
+    #[inline]
+    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> {
+    #[inline]
+    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> {
+    #[inline]
+    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> {
+    #[inline]
+    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> {
+    #[inline]
+    fn from(unique: Unique<T>) -> Self {
+        unsafe { NonNull::new_unchecked(unique.as_ptr()) }
+    }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> From<&mut T> for NonNull<T> {
+    #[inline]
+    fn from(reference: &mut T) -> Self {
+        unsafe { NonNull { pointer: reference as *mut T } }
+    }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> From<&T> for NonNull<T> {
+    #[inline]
+    fn from(reference: &T) -> Self {
+        unsafe { NonNull { pointer: reference as *const T } }
+    }
+}
diff --git a/src/libcore/ptr/unique.rs b/src/libcore/ptr/unique.rs
new file mode 100644
index 00000000000..5911518919e
--- /dev/null
+++ b/src/libcore/ptr/unique.rs
@@ -0,0 +1,180 @@
+use crate::convert::From;
+use crate::ops::{CoerceUnsized, DispatchFromDyn};
+use crate::fmt;
+use crate::marker::{PhantomData, Unsize};
+use crate::mem;
+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
+/// `Box<T>`, `Vec<T>`, `String`, and `HashMap<K, V>`.
+///
+/// Unlike `*mut T`, `Unique<T>` behaves "as if" it were an instance of `T`.
+/// It implements `Send`/`Sync` if `T` is `Send`/`Sync`. It also implies
+/// the kind of strong aliasing guarantees an instance of `T` can expect:
+/// the referent of the pointer should not be modified without a unique path to
+/// its owning Unique.
+///
+/// If you're uncertain of whether it's correct to use `Unique` for your purposes,
+/// 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
+/// as a discriminant -- `Option<Unique<T>>` has the same size as `Unique<T>`.
+/// However the pointer may still dangle if it isn't dereferenced.
+///
+/// Unlike `*mut T`, `Unique<T>` is covariant over `T`. This should always be correct
+/// for any type which upholds Unique's aliasing requirements.
+#[unstable(feature = "ptr_internals", issue = "0",
+           reason = "use NonNull instead and consider PhantomData<T> \
+                     (if you also use #[may_dangle]), Send, and/or Sync")]
+#[doc(hidden)]
+#[repr(transparent)]
+#[rustc_layout_scalar_valid_range_start(1)]
+pub struct Unique<T: ?Sized> {
+    pointer: *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>,
+}
+
+/// `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 = "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 = "ptr_internals", issue = "0")]
+unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
+
+#[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.
+    ///
+    /// 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.
+    // FIXME: rename to dangling() to match NonNull?
+    #[inline]
+    pub const fn empty() -> Self {
+        unsafe {
+            Unique::new_unchecked(mem::align_of::<T>() as *mut T)
+        }
+    }
+}
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized> Unique<T> {
+    /// Creates a new `Unique`.
+    ///
+    /// # Safety
+    ///
+    /// `ptr` must be non-null.
+    #[inline]
+    pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
+        Unique { pointer: ptr as _, _marker: PhantomData }
+    }
+
+    /// Creates a new `Unique` if `ptr` is non-null.
+    #[inline]
+    pub fn new(ptr: *mut T) -> Option<Self> {
+        if !ptr.is_null() {
+            Some(unsafe { Unique { pointer: ptr as _, _marker: PhantomData } })
+        } else {
+            None
+        }
+    }
+
+    /// Acquires the underlying `*mut` pointer.
+    #[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()`.
+    #[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()`.
+    #[inline]
+    pub unsafe fn as_mut(&mut self) -> &mut T {
+        &mut *self.as_ptr()
+    }
+}
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized> Clone for Unique<T> {
+    #[inline]
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized> Copy for Unique<T> { }
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> { }
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> { }
+
+#[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)
+    }
+}
+
+#[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 = "ptr_internals", issue = "0")]
+impl<T: ?Sized> From<&mut T> for Unique<T> {
+    #[inline]
+    fn from(reference: &mut T) -> Self {
+        unsafe { Unique { pointer: reference as *mut T, _marker: PhantomData } }
+    }
+}
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized> From<&T> for Unique<T> {
+    #[inline]
+    fn from(reference: &T) -> Self {
+        unsafe { Unique { pointer: reference as *const T, _marker: PhantomData } }
+    }
+}
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<'a, T: ?Sized> From<NonNull<T>> for Unique<T> {
+    #[inline]
+    fn from(p: NonNull<T>) -> Self {
+        unsafe { Unique::new_unchecked(p.as_ptr()) }
+    }
+}