about summary refs log tree commit diff
diff options
context:
space:
mode:
m---------src/doc/nomicon0
-rw-r--r--src/liballoc/allocator.rs6
-rw-r--r--src/liballoc/arc.rs6
-rw-r--r--src/liballoc/boxed.rs31
-rw-r--r--src/liballoc/btree/node.rs20
-rw-r--r--src/liballoc/linked_list.rs6
-rw-r--r--src/liballoc/raw_vec.rs6
-rw-r--r--src/liballoc/rc.rs30
-rw-r--r--src/liballoc/vec.rs4
-rw-r--r--src/liballoc/vec_deque.rs2
-rw-r--r--src/libcore/nonzero.rs89
-rw-r--r--src/libcore/ptr.rs62
-rw-r--r--src/libcore/tests/nonzero.rs6
-rw-r--r--src/libcore/tests/ptr.rs2
-rw-r--r--src/librustc/ty/subst.rs4
-rw-r--r--src/librustc_data_structures/array_vec.rs2
-rw-r--r--src/librustc_data_structures/obligation_forest/node_index.rs2
-rw-r--r--src/librustc_mir/dataflow/move_paths/mod.rs2
-rw-r--r--src/libstd/collections/hash/table.rs6
-rw-r--r--src/test/run-pass/issue-23433.rs2
-rw-r--r--src/test/ui/print_type_sizes/nullable.rs16
21 files changed, 218 insertions, 86 deletions
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject 81134a4dff811403b3b2f349b0c59a819f0fe0c
+Subproject f8fd6710399a1a557155cb5be4922fe6a6f694c
diff --git a/src/liballoc/allocator.rs b/src/liballoc/allocator.rs
index ca5388b4701..efc59d2cbc8 100644
--- a/src/liballoc/allocator.rs
+++ b/src/liballoc/allocator.rs
@@ -892,7 +892,7 @@ pub unsafe trait Alloc {
     {
         let k = Layout::new::<T>();
         if k.size() > 0 {
-            unsafe { self.alloc(k).map(|p| Unique::new(p as *mut T)) }
+            unsafe { self.alloc(k).map(|p| Unique::new_unchecked(p as *mut T)) }
         } else {
             Err(AllocErr::invalid_input("zero-sized type invalid for alloc_one"))
         }
@@ -963,7 +963,7 @@ pub unsafe trait Alloc {
                 unsafe {
                     self.alloc(layout.clone())
                         .map(|p| {
-                            Unique::new(p as *mut T)
+                            Unique::new_unchecked(p as *mut T)
                         })
                 }
             }
@@ -1012,7 +1012,7 @@ pub unsafe trait Alloc {
         match (Layout::array::<T>(n_old), Layout::array::<T>(n_new), ptr.as_ptr()) {
             (Some(ref k_old), Some(ref k_new), ptr) if k_old.size() > 0 && k_new.size() > 0 => {
                 self.realloc(ptr as *mut u8, k_old.clone(), k_new.clone())
-                    .map(|p|Unique::new(p as *mut T))
+                    .map(|p|Unique::new_unchecked(p as *mut T))
             }
             _ => {
                 Err(AllocErr::invalid_input("invalid layout for realloc_array"))
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index 85c7efb7ac5..9e314251934 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -280,7 +280,7 @@ impl<T> Arc<T> {
             weak: atomic::AtomicUsize::new(1),
             data: data,
         };
-        Arc { ptr: unsafe { Shared::new(Box::into_raw(x)) } }
+        Arc { ptr: Shared::from(Box::into_unique(x)) }
     }
 
     /// Returns the contained value, if the `Arc` has exactly one strong reference.
@@ -382,7 +382,7 @@ impl<T> Arc<T> {
         // `data` field from the pointer.
         let ptr = (ptr as *const u8).offset(-offset_of!(ArcInner<T>, data));
         Arc {
-            ptr: Shared::new(ptr as *mut u8 as *mut _),
+            ptr: Shared::new_unchecked(ptr as *mut u8 as *mut _),
         }
     }
 }
@@ -842,7 +842,7 @@ impl<T> Weak<T> {
     pub fn new() -> Weak<T> {
         unsafe {
             Weak {
-                ptr: Shared::new(Box::into_raw(box ArcInner {
+                ptr: Shared::from(Box::into_unique(box ArcInner {
                     strong: atomic::AtomicUsize::new(0),
                     weak: atomic::AtomicUsize::new(1),
                     data: uninitialized(),
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 94f5f4042e1..6318d22059f 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -297,6 +297,37 @@ impl<T: ?Sized> Box<T> {
     pub fn into_raw(b: Box<T>) -> *mut T {
         unsafe { mem::transmute(b) }
     }
+
+    /// Consumes the `Box`, returning the wrapped pointer as `Unique<T>`.
+    ///
+    /// After calling this function, the caller is responsible for the
+    /// memory previously managed by the `Box`. In particular, the
+    /// caller should properly destroy `T` and release the memory. The
+    /// proper way to do so is to convert the raw pointer back into a
+    /// `Box` with the [`Box::from_raw`] function.
+    ///
+    /// Note: this is an associated function, which means that you have
+    /// to call it as `Box::into_unique(b)` instead of `b.into_unique()`. This
+    /// is so that there is no conflict with a method on the inner type.
+    ///
+    /// [`Box::from_raw`]: struct.Box.html#method.from_raw
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique)]
+    ///
+    /// fn main() {
+    ///     let x = Box::new(5);
+    ///     let ptr = Box::into_unique(x);
+    /// }
+    /// ```
+    #[unstable(feature = "unique", reason = "needs an RFC to flesh out design",
+               issue = "27730")]
+    #[inline]
+    pub fn into_unique(b: Box<T>) -> Unique<T> {
+        unsafe { mem::transmute(b) }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/liballoc/btree/node.rs b/src/liballoc/btree/node.rs
index 0eaff6f2192..06d3a113b94 100644
--- a/src/liballoc/btree/node.rs
+++ b/src/liballoc/btree/node.rs
@@ -140,24 +140,22 @@ struct BoxedNode<K, V> {
 
 impl<K, V> BoxedNode<K, V> {
     fn from_leaf(node: Box<LeafNode<K, V>>) -> Self {
-        unsafe {
-            BoxedNode { ptr: Unique::new(Box::into_raw(node)) }
-        }
+        BoxedNode { ptr: Box::into_unique(node) }
     }
 
     fn from_internal(node: Box<InternalNode<K, V>>) -> Self {
         unsafe {
-            BoxedNode { ptr: Unique::new(Box::into_raw(node) as *mut LeafNode<K, V>) }
+            BoxedNode { ptr: Unique::new_unchecked(Box::into_raw(node) as *mut LeafNode<K, V>) }
         }
     }
 
     unsafe fn from_ptr(ptr: NonZero<*const LeafNode<K, V>>) -> Self {
-        BoxedNode { ptr: Unique::new(ptr.get() as *mut LeafNode<K, V>) }
+        BoxedNode { ptr: Unique::new_unchecked(ptr.get() as *mut LeafNode<K, V>) }
     }
 
     fn as_ptr(&self) -> NonZero<*const LeafNode<K, V>> {
         unsafe {
-            NonZero::new(self.ptr.as_ptr())
+            NonZero::from(self.ptr.as_ref())
         }
     }
 }
@@ -384,21 +382,19 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
         >,
         Self
     > {
-        if self.as_leaf().parent.is_null() {
-            Err(self)
-        } else {
+        if let Some(non_zero) = NonZero::new(self.as_leaf().parent as *const LeafNode<K, V>) {
             Ok(Handle {
                 node: NodeRef {
                     height: self.height + 1,
-                    node: unsafe {
-                        NonZero::new(self.as_leaf().parent as *mut LeafNode<K, V>)
-                    },
+                    node: non_zero,
                     root: self.root,
                     _marker: PhantomData
                 },
                 idx: self.as_leaf().parent_idx as usize,
                 _marker: PhantomData
             })
+        } else {
+            Err(self)
         }
     }
 
diff --git a/src/liballoc/linked_list.rs b/src/liballoc/linked_list.rs
index e8973b7d285..850dd6adcf0 100644
--- a/src/liballoc/linked_list.rs
+++ b/src/liballoc/linked_list.rs
@@ -157,7 +157,7 @@ impl<T> LinkedList<T> {
         unsafe {
             node.next = self.head;
             node.prev = None;
-            let node = Some(Shared::new(Box::into_raw(node)));
+            let node = Some(Shared::from(Box::into_unique(node)));
 
             match self.head {
                 None => self.tail = node,
@@ -192,7 +192,7 @@ impl<T> LinkedList<T> {
         unsafe {
             node.next = None;
             node.prev = self.tail;
-            let node = Some(Shared::new(Box::into_raw(node)));
+            let node = Some(Shared::from(Box::into_unique(node)));
 
             match self.tail {
                 None => self.head = node,
@@ -921,7 +921,7 @@ impl<'a, T> IterMut<'a, T> {
                     Some(prev) => prev,
                 };
 
-                let node = Some(Shared::new(Box::into_raw(box Node {
+                let node = Some(Shared::from(Box::into_unique(box Node {
                     next: Some(head),
                     prev: Some(prev),
                     element: element,
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index d1aab4c70be..ca55831220d 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -104,7 +104,7 @@ impl<T, A: Alloc> RawVec<T, A> {
             };
 
             RawVec {
-                ptr: Unique::new(ptr as *mut _),
+                ptr: Unique::new_unchecked(ptr as *mut _),
                 cap: cap,
                 a: a,
             }
@@ -159,7 +159,7 @@ impl<T, A: Alloc> RawVec<T, A> {
     /// If the ptr and capacity come from a RawVec created via `a`, then this is guaranteed.
     pub unsafe fn from_raw_parts_in(ptr: *mut T, cap: usize, a: A) -> Self {
         RawVec {
-            ptr: Unique::new(ptr),
+            ptr: Unique::new_unchecked(ptr),
             cap: cap,
             a: a,
         }
@@ -176,7 +176,7 @@ impl<T> RawVec<T, Heap> {
     /// If the ptr and capacity come from a RawVec, then this is guaranteed.
     pub unsafe fn from_raw_parts(ptr: *mut T, cap: usize) -> Self {
         RawVec {
-            ptr: Unique::new(ptr),
+            ptr: Unique::new_unchecked(ptr),
             cap: cap,
             a: Heap,
         }
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 9e72238fbd4..a2184054b37 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -303,18 +303,16 @@ impl<T> Rc<T> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(value: T) -> Rc<T> {
-        unsafe {
-            Rc {
-                // there is an implicit weak pointer owned by all the strong
-                // pointers, which ensures that the weak destructor never frees
-                // the allocation while the strong destructor is running, even
-                // if the weak pointer is stored inside the strong one.
-                ptr: Shared::new(Box::into_raw(box RcBox {
-                    strong: Cell::new(1),
-                    weak: Cell::new(1),
-                    value: value,
-                })),
-            }
+        Rc {
+            // there is an implicit weak pointer owned by all the strong
+            // pointers, which ensures that the weak destructor never frees
+            // the allocation while the strong destructor is running, even
+            // if the weak pointer is stored inside the strong one.
+            ptr: Shared::from(Box::into_unique(box RcBox {
+                strong: Cell::new(1),
+                weak: Cell::new(1),
+                value: value,
+            })),
         }
     }
 
@@ -418,7 +416,7 @@ impl<T> Rc<T> {
 
         let ptr = (ptr as *const u8).offset(-offset_of!(RcBox<T>, value));
         Rc {
-            ptr: Shared::new(ptr as *mut u8 as *mut _)
+            ptr: Shared::new_unchecked(ptr as *mut u8 as *mut _)
         }
     }
 }
@@ -443,7 +441,7 @@ impl Rc<str> {
             // Combine the allocation address and the string length into a fat pointer to `RcBox`.
             let rcbox_ptr: *mut RcBox<str> = mem::transmute([ptr as usize, value.len()]);
             assert!(aligned_len * size_of::<usize>() == size_of_val(&*rcbox_ptr));
-            Rc { ptr: Shared::new(rcbox_ptr) }
+            Rc { ptr: Shared::new_unchecked(rcbox_ptr) }
         }
     }
 }
@@ -476,7 +474,7 @@ impl<T> Rc<[T]> {
             // Free the original allocation without freeing its (moved) contents.
             box_free(Box::into_raw(value));
 
-            Rc { ptr: Shared::new(ptr as *mut _) }
+            Rc { ptr: Shared::new_unchecked(ptr as *mut _) }
         }
     }
 }
@@ -1016,7 +1014,7 @@ impl<T> Weak<T> {
     pub fn new() -> Weak<T> {
         unsafe {
             Weak {
-                ptr: Shared::new(Box::into_raw(box RcBox {
+                ptr: Shared::from(Box::into_unique(box RcBox {
                     strong: Cell::new(0),
                     weak: Cell::new(1),
                     value: uninitialized(),
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 780a51aec3b..8a1d14b48a1 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -1126,7 +1126,7 @@ impl<T> Vec<T> {
                 tail_start: end,
                 tail_len: len - end,
                 iter: range_slice.iter(),
-                vec: Shared::new(self as *mut _),
+                vec: Shared::from(self),
             }
         }
     }
@@ -1727,7 +1727,7 @@ impl<T> IntoIterator for Vec<T> {
             let cap = self.buf.cap();
             mem::forget(self);
             IntoIter {
-                buf: Shared::new(begin),
+                buf: Shared::new_unchecked(begin),
                 cap: cap,
                 ptr: begin,
                 end: end,
diff --git a/src/liballoc/vec_deque.rs b/src/liballoc/vec_deque.rs
index 18175a5d01b..fdd6c79ef2e 100644
--- a/src/liballoc/vec_deque.rs
+++ b/src/liballoc/vec_deque.rs
@@ -893,7 +893,7 @@ impl<T> VecDeque<T> {
         self.head = drain_tail;
 
         Drain {
-            deque: unsafe { Shared::new(self as *mut _) },
+            deque: Shared::from(&mut *self),
             after_tail: drain_head,
             after_head: head,
             iter: Iter {
diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs
index 977438051d9..3ff1068b937 100644
--- a/src/libcore/nonzero.rs
+++ b/src/libcore/nonzero.rs
@@ -16,22 +16,48 @@
 use ops::CoerceUnsized;
 
 /// Unsafe trait to indicate what types are usable with the NonZero struct
-pub unsafe trait Zeroable {}
-
-unsafe impl<T:?Sized> Zeroable for *const T {}
-unsafe impl<T:?Sized> Zeroable for *mut T {}
-unsafe impl Zeroable for isize {}
-unsafe impl Zeroable for usize {}
-unsafe impl Zeroable for i8 {}
-unsafe impl Zeroable for u8 {}
-unsafe impl Zeroable for i16 {}
-unsafe impl Zeroable for u16 {}
-unsafe impl Zeroable for i32 {}
-unsafe impl Zeroable for u32 {}
-unsafe impl Zeroable for i64 {}
-unsafe impl Zeroable for u64 {}
-unsafe impl Zeroable for i128 {}
-unsafe impl Zeroable for u128 {}
+pub unsafe trait Zeroable {
+    /// Whether this value is zero
+    fn is_zero(&self) -> bool;
+}
+
+macro_rules! impl_zeroable_for_pointer_types {
+    ( $( $Ptr: ty )+ ) => {
+        $(
+            /// For fat pointers to be considered "zero", only the "data" part needs to be null.
+            unsafe impl<T: ?Sized> Zeroable for $Ptr {
+                #[inline]
+                fn is_zero(&self) -> bool {
+                    // Cast because `is_null` is only available on thin pointers
+                    (*self as *mut u8).is_null()
+                }
+            }
+        )+
+    }
+}
+
+macro_rules! impl_zeroable_for_integer_types {
+    ( $( $Int: ty )+ ) => {
+        $(
+            unsafe impl Zeroable for $Int {
+                #[inline]
+                fn is_zero(&self) -> bool {
+                    *self == 0
+                }
+            }
+        )+
+    }
+}
+
+impl_zeroable_for_pointer_types! {
+    *const T
+    *mut T
+}
+
+impl_zeroable_for_integer_types! {
+    usize u8 u16 u32 u64 u128
+    isize i8 i16 i32 i64 i128
+}
 
 /// A wrapper type for raw pointers and integers that will never be
 /// NULL or 0 that might allow certain optimizations.
@@ -43,10 +69,20 @@ impl<T: Zeroable> NonZero<T> {
     /// Creates an instance of NonZero with the provided value.
     /// You must indeed ensure that the value is actually "non-zero".
     #[inline]
-    pub const unsafe fn new(inner: T) -> NonZero<T> {
+    pub const unsafe fn new_unchecked(inner: T) -> Self {
         NonZero(inner)
     }
 
+    /// Creates an instance of NonZero with the provided value.
+    #[inline]
+    pub fn new(inner: T) -> Option<Self> {
+        if inner.is_zero() {
+            None
+        } else {
+            Some(NonZero(inner))
+        }
+    }
+
     /// Gets the inner value.
     pub fn get(self) -> T {
         self.0
@@ -54,3 +90,22 @@ impl<T: Zeroable> NonZero<T> {
 }
 
 impl<T: Zeroable+CoerceUnsized<U>, U: Zeroable> CoerceUnsized<NonZero<U>> for NonZero<T> {}
+
+impl<'a, T: ?Sized> From<&'a mut T> for NonZero<*mut T> {
+    fn from(reference: &'a mut T) -> Self {
+        NonZero(reference)
+    }
+}
+
+impl<'a, T: ?Sized> From<&'a mut T> for NonZero<*const T> {
+    fn from(reference: &'a mut T) -> Self {
+        let ptr: *mut T = reference;
+        NonZero(ptr)
+    }
+}
+
+impl<'a, T: ?Sized> From<&'a T> for NonZero<*const T> {
+    fn from(reference: &'a T) -> Self {
+        NonZero(reference)
+    }
+}
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index b19e07b8578..60cf1a20530 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -16,6 +16,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+use convert::From;
 use intrinsics;
 use ops::CoerceUnsized;
 use fmt;
@@ -1098,7 +1099,7 @@ impl<T: Sized> Unique<T> {
     pub fn empty() -> Self {
         unsafe {
             let ptr = mem::align_of::<T>() as *mut T;
-            Unique::new(ptr)
+            Unique::new_unchecked(ptr)
         }
     }
 }
@@ -1110,8 +1111,13 @@ impl<T: ?Sized> Unique<T> {
     /// # Safety
     ///
     /// `ptr` must be non-null.
-    pub const unsafe fn new(ptr: *mut T) -> Unique<T> {
-        Unique { pointer: NonZero::new(ptr), _marker: PhantomData }
+    pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
+        Unique { pointer: NonZero::new_unchecked(ptr), _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 })
     }
 
     /// Acquires the underlying `*mut` pointer.
@@ -1138,14 +1144,14 @@ impl<T: ?Sized> Unique<T> {
     }
 }
 
-#[unstable(feature = "shared", issue = "27730")]
+#[unstable(feature = "unique", issue = "27730")]
 impl<T: ?Sized> Clone for Unique<T> {
     fn clone(&self) -> Self {
         *self
     }
 }
 
-#[unstable(feature = "shared", issue = "27730")]
+#[unstable(feature = "unique", issue = "27730")]
 impl<T: ?Sized> Copy for Unique<T> { }
 
 #[unstable(feature = "unique", issue = "27730")]
@@ -1158,6 +1164,20 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> {
     }
 }
 
+#[unstable(feature = "unique", issue = "27730")]
+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 }
+    }
+}
+
+#[unstable(feature = "unique", issue = "27730")]
+impl<'a, T: ?Sized> From<&'a T> for Unique<T> {
+    fn from(reference: &'a T) -> Self {
+        Unique { pointer: NonZero::from(reference), _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
@@ -1212,7 +1232,7 @@ impl<T: Sized> Shared<T> {
     pub fn empty() -> Self {
         unsafe {
             let ptr = mem::align_of::<T>() as *mut T;
-            Shared::new(ptr)
+            Shared::new_unchecked(ptr)
         }
     }
 }
@@ -1224,8 +1244,13 @@ impl<T: ?Sized> Shared<T> {
     /// # Safety
     ///
     /// `ptr` must be non-null.
-    pub unsafe fn new(ptr: *mut T) -> Self {
-        Shared { pointer: NonZero::new(ptr), _marker: PhantomData }
+    pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
+        Shared { pointer: NonZero::new_unchecked(ptr), _marker: PhantomData }
+    }
+
+    /// Creates a new `Shared` if `ptr` is non-null.
+    pub fn new(ptr: *mut T) -> Option<Self> {
+        NonZero::new(ptr as *const T).map(|nz| Shared { pointer: nz, _marker: PhantomData })
     }
 
     /// Acquires the underlying `*mut` pointer.
@@ -1278,3 +1303,24 @@ impl<T: ?Sized> fmt::Pointer for Shared<T> {
         fmt::Pointer::fmt(&self.as_ptr(), f)
     }
 }
+
+#[unstable(feature = "shared", issue = "27730")]
+impl<T: ?Sized> From<Unique<T>> for Shared<T> {
+    fn from(unique: Unique<T>) -> Self {
+        Shared { pointer: unique.pointer, _marker: PhantomData }
+    }
+}
+
+#[unstable(feature = "shared", issue = "27730")]
+impl<'a, T: ?Sized> From<&'a mut T> for Shared<T> {
+    fn from(reference: &'a mut T) -> Self {
+        Shared { pointer: NonZero::from(reference), _marker: PhantomData }
+    }
+}
+
+#[unstable(feature = "shared", issue = "27730")]
+impl<'a, T: ?Sized> From<&'a T> for Shared<T> {
+    fn from(reference: &'a T) -> Self {
+        Shared { pointer: NonZero::from(reference), _marker: PhantomData }
+    }
+}
diff --git a/src/libcore/tests/nonzero.rs b/src/libcore/tests/nonzero.rs
index 588fffda35f..a795dd57504 100644
--- a/src/libcore/tests/nonzero.rs
+++ b/src/libcore/tests/nonzero.rs
@@ -16,7 +16,7 @@ use std::mem::size_of;
 #[test]
 fn test_create_nonzero_instance() {
     let _a = unsafe {
-        NonZero::new(21)
+        NonZero::new_unchecked(21)
     };
 }
 
@@ -28,14 +28,14 @@ fn test_size_nonzero_in_option() {
 #[test]
 fn test_match_on_nonzero_option() {
     let a = Some(unsafe {
-        NonZero::new(42)
+        NonZero::new_unchecked(42)
     });
     match a {
         Some(val) => assert_eq!(val.get(), 42),
         None => panic!("unexpected None while matching on Some(NonZero(_))")
     }
 
-    match unsafe { Some(NonZero::new(43)) } {
+    match unsafe { Some(NonZero::new_unchecked(43)) } {
         Some(val) => assert_eq!(val.get(), 43),
         None => panic!("unexpected None while matching on Some(NonZero(_))")
     }
diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs
index e28dc6a6881..c2d53840f8f 100644
--- a/src/libcore/tests/ptr.rs
+++ b/src/libcore/tests/ptr.rs
@@ -167,7 +167,7 @@ fn test_set_memory() {
 #[test]
 fn test_unsized_unique() {
     let xs: &[i32] = &[1, 2, 3];
-    let ptr = unsafe { Unique::new(xs as *const [i32] as *mut [i32]) };
+    let ptr = unsafe { Unique::new_unchecked(xs as *const [i32] as *mut [i32]) };
     let ys = unsafe { ptr.as_ref() };
     let zs: &[i32] = &[1, 2, 3];
     assert!(ys == zs);
diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs
index f6112d4887d..e2881ac9b79 100644
--- a/src/librustc/ty/subst.rs
+++ b/src/librustc/ty/subst.rs
@@ -47,7 +47,7 @@ impl<'tcx> From<Ty<'tcx>> for Kind<'tcx> {
         let ptr = ty as *const _ as usize;
         Kind {
             ptr: unsafe {
-                NonZero::new(ptr | TYPE_TAG)
+                NonZero::new_unchecked(ptr | TYPE_TAG)
             },
             marker: PhantomData
         }
@@ -62,7 +62,7 @@ impl<'tcx> From<ty::Region<'tcx>> for Kind<'tcx> {
         let ptr = r as *const _ as usize;
         Kind {
             ptr: unsafe {
-                NonZero::new(ptr | REGION_TAG)
+                NonZero::new_unchecked(ptr | REGION_TAG)
             },
             marker: PhantomData
         }
diff --git a/src/librustc_data_structures/array_vec.rs b/src/librustc_data_structures/array_vec.rs
index 078bb801751..ced73e9e426 100644
--- a/src/librustc_data_structures/array_vec.rs
+++ b/src/librustc_data_structures/array_vec.rs
@@ -146,7 +146,7 @@ impl<A: Array> ArrayVec<A> {
                 tail_start: end,
                 tail_len: len - end,
                 iter: range_slice.iter(),
-                array_vec: Shared::new(self as *mut _),
+                array_vec: Shared::from(self),
             }
         }
     }
diff --git a/src/librustc_data_structures/obligation_forest/node_index.rs b/src/librustc_data_structures/obligation_forest/node_index.rs
index 023c56ca59b..a72cc6b57ea 100644
--- a/src/librustc_data_structures/obligation_forest/node_index.rs
+++ b/src/librustc_data_structures/obligation_forest/node_index.rs
@@ -19,7 +19,7 @@ pub struct NodeIndex {
 impl NodeIndex {
     pub fn new(value: usize) -> NodeIndex {
         assert!(value < (u32::MAX as usize));
-        unsafe { NodeIndex { index: NonZero::new((value as u32) + 1) } }
+        NodeIndex { index: NonZero::new((value as u32) + 1).unwrap() }
     }
 
     pub fn get(self) -> usize {
diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs
index 648c376de1c..fbf977b98f9 100644
--- a/src/librustc_mir/dataflow/move_paths/mod.rs
+++ b/src/librustc_mir/dataflow/move_paths/mod.rs
@@ -42,7 +42,7 @@ pub(crate) mod indexes {
 
             impl Idx for $Index {
                 fn new(idx: usize) -> Self {
-                    unsafe { $Index(NonZero::new(idx + 1)) }
+                    $Index(NonZero::new(idx + 1).unwrap())
                 }
                 fn index(self) -> usize {
                     self.0.get() - 1
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index 06f4f7643ec..3844690860b 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -44,7 +44,7 @@ impl TaggedHashUintPtr {
     #[inline]
     unsafe fn new(ptr: *mut HashUint) -> Self {
         debug_assert!(ptr as usize & 1 == 0 || ptr as usize == EMPTY as usize);
-        TaggedHashUintPtr(Unique::new(ptr))
+        TaggedHashUintPtr(Unique::new_unchecked(ptr))
     }
 
     #[inline]
@@ -56,7 +56,7 @@ impl TaggedHashUintPtr {
             } else {
                 usize_ptr &= !1;
             }
-            self.0 = Unique::new(usize_ptr as *mut HashUint)
+            self.0 = Unique::new_unchecked(usize_ptr as *mut HashUint)
         }
     }
 
@@ -877,7 +877,7 @@ impl<K, V> RawTable<K, V> {
                 elems_left: elems_left,
                 marker: marker::PhantomData,
             },
-            table: unsafe { Shared::new(self) },
+            table: Shared::from(self),
             marker: marker::PhantomData,
         }
     }
diff --git a/src/test/run-pass/issue-23433.rs b/src/test/run-pass/issue-23433.rs
index 82f80586b9f..aa13d6fad47 100644
--- a/src/test/run-pass/issue-23433.rs
+++ b/src/test/run-pass/issue-23433.rs
@@ -16,7 +16,7 @@ use std::ptr::Unique;
 
 fn main() {
     let mut a = [0u8; 5];
-    let b: Option<Unique<[u8]>> = unsafe { Some(Unique::new(&mut a)) };
+    let b: Option<Unique<[u8]>> = Some(Unique::from(&mut a));
     match b {
         Some(_) => println!("Got `Some`"),
         None => panic!("Unexpected `None`"),
diff --git a/src/test/ui/print_type_sizes/nullable.rs b/src/test/ui/print_type_sizes/nullable.rs
index f7fdcac81da..5052c59a39d 100644
--- a/src/test/ui/print_type_sizes/nullable.rs
+++ b/src/test/ui/print_type_sizes/nullable.rs
@@ -42,7 +42,7 @@ impl Default for EmbeddedDiscr {
 }
 
 #[derive(Default)]
-pub struct IndirectNonZero<T: Zeroable> {
+pub struct IndirectNonZero<T: Zeroable + One> {
     pre: u8,
     nested: NestedNonZero<T>,
     post: u16,
@@ -54,14 +54,20 @@ pub struct NestedNonZero<T: Zeroable> {
     post: u16,
 }
 
-impl<T: Zeroable+Default> Default for NestedNonZero<T> {
+impl<T: Zeroable+One> Default for NestedNonZero<T> {
     fn default() -> Self {
-        unsafe {
-            NestedNonZero { pre: 0, val: NonZero::new(Default::default()), post: 0 }
-        }
+        NestedNonZero { pre: 0, val: NonZero::new(T::one()).unwrap(), post: 0 }
     }
 }
 
+pub trait One {
+    fn one() -> Self;
+}
+
+impl One for u32 {
+    fn one() -> Self { 1 }
+}
+
 pub fn main() {
     let _x: MyOption<NonZero<u32>> = Default::default();
     let _y: EmbeddedDiscr = Default::default();