diff --git a/src/doc/nomicon b/src/doc/nomicon index 81134a4dff811..f8fd6710399a1 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 81134a4dff811403b3b2f349b0c59a819f0fe0c1 +Subproject commit f8fd6710399a1a557155cb5be4922fe6a6f694c0 diff --git a/src/liballoc/allocator.rs b/src/liballoc/allocator.rs index ca5388b470147..efc59d2cbc86f 100644 --- a/src/liballoc/allocator.rs +++ b/src/liballoc/allocator.rs @@ -892,7 +892,7 @@ pub unsafe trait Alloc { { let k = Layout::new::(); 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::(n_old), Layout::array::(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 85c7efb7ac50c..9e31425193417 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -280,7 +280,7 @@ impl Arc { 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 Arc { // `data` field from the pointer. let ptr = (ptr as *const u8).offset(-offset_of!(ArcInner, 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 Weak { pub fn new() -> Weak { 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 94f5f4042e134..6318d22059f96 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -297,6 +297,37 @@ impl Box { pub fn into_raw(b: Box) -> *mut T { unsafe { mem::transmute(b) } } + + /// Consumes the `Box`, returning the wrapped pointer as `Unique`. + /// + /// 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) -> Unique { + 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 0eaff6f2192c8..06d3a113b9474 100644 --- a/src/liballoc/btree/node.rs +++ b/src/liballoc/btree/node.rs @@ -140,24 +140,22 @@ struct BoxedNode { impl BoxedNode { fn from_leaf(node: Box>) -> Self { - unsafe { - BoxedNode { ptr: Unique::new(Box::into_raw(node)) } - } + BoxedNode { ptr: Box::into_unique(node) } } fn from_internal(node: Box>) -> Self { unsafe { - BoxedNode { ptr: Unique::new(Box::into_raw(node) as *mut LeafNode) } + BoxedNode { ptr: Unique::new_unchecked(Box::into_raw(node) as *mut LeafNode) } } } unsafe fn from_ptr(ptr: NonZero<*const LeafNode>) -> Self { - BoxedNode { ptr: Unique::new(ptr.get() as *mut LeafNode) } + BoxedNode { ptr: Unique::new_unchecked(ptr.get() as *mut LeafNode) } } fn as_ptr(&self) -> NonZero<*const LeafNode> { unsafe { - NonZero::new(self.ptr.as_ptr()) + NonZero::from(self.ptr.as_ref()) } } } @@ -384,21 +382,19 @@ impl NodeRef { >, 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) { Ok(Handle { node: NodeRef { height: self.height + 1, - node: unsafe { - NonZero::new(self.as_leaf().parent as *mut LeafNode) - }, + 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 e8973b7d28537..850dd6adcf0af 100644 --- a/src/liballoc/linked_list.rs +++ b/src/liballoc/linked_list.rs @@ -157,7 +157,7 @@ impl LinkedList { 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 LinkedList { 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 d1aab4c70be4a..ca55831220da6 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -104,7 +104,7 @@ impl RawVec { }; RawVec { - ptr: Unique::new(ptr as *mut _), + ptr: Unique::new_unchecked(ptr as *mut _), cap: cap, a: a, } @@ -159,7 +159,7 @@ impl RawVec { /// 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 RawVec { /// 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 9e72238fbd463..a2184054b377e 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -303,18 +303,16 @@ impl Rc { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn new(value: T) -> Rc { - 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 Rc { let ptr = (ptr as *const u8).offset(-offset_of!(RcBox, 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 { // Combine the allocation address and the string length into a fat pointer to `RcBox`. let rcbox_ptr: *mut RcBox = mem::transmute([ptr as usize, value.len()]); assert!(aligned_len * size_of::() == size_of_val(&*rcbox_ptr)); - Rc { ptr: Shared::new(rcbox_ptr) } + Rc { ptr: Shared::new_unchecked(rcbox_ptr) } } } } @@ -476,7 +474,7 @@ impl 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 Weak { pub fn new() -> Weak { 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 780a51aec3bab..8a1d14b48a1a3 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1126,7 +1126,7 @@ impl Vec { 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 IntoIterator for Vec { 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 18175a5d01bd2..fdd6c79ef2e9d 100644 --- a/src/liballoc/vec_deque.rs +++ b/src/liballoc/vec_deque.rs @@ -893,7 +893,7 @@ impl VecDeque { 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 977438051d93b..3ff1068b93763 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 Zeroable for *const T {} -unsafe impl 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 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 NonZero { /// 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 { + 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 { + 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 NonZero { } impl, U: Zeroable> CoerceUnsized> for NonZero {} + +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 b19e07b8578c0..60cf1a2053068 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 Unique { pub fn empty() -> Self { unsafe { let ptr = mem::align_of::() as *mut T; - Unique::new(ptr) + Unique::new_unchecked(ptr) } } } @@ -1110,8 +1111,13 @@ impl Unique { /// # Safety /// /// `ptr` must be non-null. - pub const unsafe fn new(ptr: *mut T) -> Unique { - 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 { + NonZero::new(ptr as *const T).map(|nz| Unique { pointer: nz, _marker: PhantomData }) } /// Acquires the underlying `*mut` pointer. @@ -1138,14 +1144,14 @@ impl Unique { } } -#[unstable(feature = "shared", issue = "27730")] +#[unstable(feature = "unique", issue = "27730")] impl Clone for Unique { fn clone(&self) -> Self { *self } } -#[unstable(feature = "shared", issue = "27730")] +#[unstable(feature = "unique", issue = "27730")] impl Copy for Unique { } #[unstable(feature = "unique", issue = "27730")] @@ -1158,6 +1164,20 @@ impl fmt::Pointer for Unique { } } +#[unstable(feature = "unique", issue = "27730")] +impl<'a, T: ?Sized> From<&'a mut T> for Unique { + 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 { + 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`, `Arc`, or doubly-linked lists, which @@ -1212,7 +1232,7 @@ impl Shared { pub fn empty() -> Self { unsafe { let ptr = mem::align_of::() as *mut T; - Shared::new(ptr) + Shared::new_unchecked(ptr) } } } @@ -1224,8 +1244,13 @@ impl Shared { /// # 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 { + NonZero::new(ptr as *const T).map(|nz| Shared { pointer: nz, _marker: PhantomData }) } /// Acquires the underlying `*mut` pointer. @@ -1278,3 +1303,24 @@ impl fmt::Pointer for Shared { fmt::Pointer::fmt(&self.as_ptr(), f) } } + +#[unstable(feature = "shared", issue = "27730")] +impl From> for Shared { + fn from(unique: Unique) -> Self { + Shared { pointer: unique.pointer, _marker: PhantomData } + } +} + +#[unstable(feature = "shared", issue = "27730")] +impl<'a, T: ?Sized> From<&'a mut T> for Shared { + 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 { + 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 588fffda35fca..a795dd575043d 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 e28dc6a6881fd..c2d53840f8f57 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 f6112d4887d7d..e2881ac9b798e 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -47,7 +47,7 @@ impl<'tcx> From> 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> 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 078bb801751d0..ced73e9e42627 100644 --- a/src/librustc_data_structures/array_vec.rs +++ b/src/librustc_data_structures/array_vec.rs @@ -146,7 +146,7 @@ impl ArrayVec { 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 023c56ca59be8..a72cc6b57eade 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 d7ed0938e886a..dd970fdff91ec 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 06f4f7643ec83..3844690860b5a 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 RawTable { 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 82f80586b9f94..aa13d6fad47c9 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> = unsafe { Some(Unique::new(&mut a)) }; + let b: Option> = 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 f7fdcac81daad..5052c59a39dcf 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 { +pub struct IndirectNonZero { pre: u8, nested: NestedNonZero, post: u16, @@ -54,14 +54,20 @@ pub struct NestedNonZero { post: u16, } -impl Default for NestedNonZero { +impl Default for NestedNonZero { 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> = Default::default(); let _y: EmbeddedDiscr = Default::default();