From cbd2b6b4842754495a2673df234e2496494245be Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 14 Jul 2017 12:47:06 +0200 Subject: [PATCH] Add Box::into_unique --- src/liballoc/arc.rs | 4 ++-- src/liballoc/boxed.rs | 31 +++++++++++++++++++++++++++++++ src/liballoc/btree/node.rs | 4 +--- src/liballoc/linked_list.rs | 6 +++--- src/liballoc/rc.rs | 24 +++++++++++------------- 5 files changed, 48 insertions(+), 21 deletions(-) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index cc792c9f83f7..9e3142519341 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_unchecked(Box::into_raw(x)) } } + Arc { ptr: Shared::from(Box::into_unique(x)) } } /// Returns the contained value, if the `Arc` has exactly one strong reference. @@ -842,7 +842,7 @@ impl Weak { pub fn new() -> Weak { unsafe { Weak { - ptr: Shared::new_unchecked(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 94f5f4042e13..6318d22059f9 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 0a752702b121..05ac9cba5e09 100644 --- a/src/liballoc/btree/node.rs +++ b/src/liballoc/btree/node.rs @@ -140,9 +140,7 @@ struct BoxedNode { impl BoxedNode { fn from_leaf(node: Box>) -> Self { - unsafe { - BoxedNode { ptr: Unique::new_unchecked(Box::into_raw(node)) } - } + BoxedNode { ptr: Box::into_unique(node) } } fn from_internal(node: Box>) -> Self { diff --git a/src/liballoc/linked_list.rs b/src/liballoc/linked_list.rs index 08d6fac3849b..850dd6adcf0a 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_unchecked(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_unchecked(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_unchecked(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/rc.rs b/src/liballoc/rc.rs index 6ff6b6b03725..a2184054b377 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_unchecked(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, + })), } } @@ -1016,7 +1014,7 @@ impl Weak { pub fn new() -> Weak { unsafe { Weak { - ptr: Shared::new_unchecked(Box::into_raw(box RcBox { + ptr: Shared::from(Box::into_unique(box RcBox { strong: Cell::new(0), weak: Cell::new(1), value: uninitialized(),