From 0a08ad0443631ca86e61526916fb4ee61fe1abce Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 29 Jun 2017 01:03:35 +0200 Subject: Rename {NonZero,Shared,Unique}::new to new_unchecked --- src/liballoc/allocator.rs | 6 +++--- src/liballoc/arc.rs | 6 +++--- src/liballoc/btree/node.rs | 10 +++++----- src/liballoc/linked_list.rs | 6 +++--- src/liballoc/raw_vec.rs | 6 +++--- src/liballoc/rc.rs | 10 +++++----- src/liballoc/vec.rs | 4 ++-- src/liballoc/vec_deque.rs | 2 +- 8 files changed, 25 insertions(+), 25 deletions(-) (limited to 'src/liballoc') 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::(); 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 85c7efb7ac5..cc792c9f83f 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: unsafe { Shared::new_unchecked(Box::into_raw(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::new_unchecked(Box::into_raw(box ArcInner { strong: atomic::AtomicUsize::new(0), weak: atomic::AtomicUsize::new(1), data: uninitialized(), diff --git a/src/liballoc/btree/node.rs b/src/liballoc/btree/node.rs index 0eaff6f2192..0a752702b12 100644 --- a/src/liballoc/btree/node.rs +++ b/src/liballoc/btree/node.rs @@ -141,23 +141,23 @@ struct BoxedNode { impl BoxedNode { fn from_leaf(node: Box>) -> Self { unsafe { - BoxedNode { ptr: Unique::new(Box::into_raw(node)) } + BoxedNode { ptr: Unique::new_unchecked(Box::into_raw(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::new_unchecked(self.ptr.as_ptr()) } } } @@ -391,7 +391,7 @@ impl NodeRef { node: NodeRef { height: self.height + 1, node: unsafe { - NonZero::new(self.as_leaf().parent as *mut LeafNode) + NonZero::new_unchecked(self.as_leaf().parent as *mut LeafNode) }, root: self.root, _marker: PhantomData diff --git a/src/liballoc/linked_list.rs b/src/liballoc/linked_list.rs index e8973b7d285..08d6fac3849 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::new_unchecked(Box::into_raw(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::new_unchecked(Box::into_raw(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::new_unchecked(Box::into_raw(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 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 9e72238fbd4..6ff6b6b0372 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -309,7 +309,7 @@ impl Rc { // 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 { + ptr: Shared::new_unchecked(Box::into_raw(box RcBox { strong: Cell::new(1), weak: Cell::new(1), value: value, @@ -418,7 +418,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 +443,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 +476,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 +1016,7 @@ impl Weak { pub fn new() -> Weak { unsafe { Weak { - ptr: Shared::new(Box::into_raw(box RcBox { + ptr: Shared::new_unchecked(Box::into_raw(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..bc1521c4069 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::new_unchecked(self as *mut _), } } } @@ -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 18175a5d01b..a99b7bbe053 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: unsafe { Shared::new_unchecked(self as *mut _) }, after_tail: drain_head, after_head: head, iter: Iter { -- cgit 1.4.1-3-g733a5 From cbd2b6b4842754495a2673df234e2496494245be Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 14 Jul 2017 12:47:06 +0200 Subject: 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(-) (limited to 'src/liballoc') diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index cc792c9f83f..9e314251934 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 94f5f4042e1..6318d22059f 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 0a752702b12..05ac9cba5e0 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 08d6fac3849..850dd6adcf0 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 6ff6b6b0372..a2184054b37 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(), -- cgit 1.4.1-3-g733a5 From a4edae95ad0e85b50845be1757670929ff60c88a Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 14 Jul 2017 13:05:21 +0200 Subject: Add conversions from references to NonZero pointers, Unique, and Shared --- src/liballoc/btree/node.rs | 2 +- src/liballoc/vec.rs | 2 +- src/liballoc/vec_deque.rs | 2 +- src/libcore/nonzero.rs | 19 +++++++++++++++++++ src/libcore/ptr.rs | 28 ++++++++++++++++++++++++++++ src/librustc_data_structures/array_vec.rs | 2 +- src/libstd/collections/hash/table.rs | 2 +- 7 files changed, 52 insertions(+), 5 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/btree/node.rs b/src/liballoc/btree/node.rs index 05ac9cba5e0..a6cbab8497b 100644 --- a/src/liballoc/btree/node.rs +++ b/src/liballoc/btree/node.rs @@ -155,7 +155,7 @@ impl BoxedNode { fn as_ptr(&self) -> NonZero<*const LeafNode> { unsafe { - NonZero::new_unchecked(self.ptr.as_ptr()) + NonZero::from(self.ptr.as_ref()) } } } diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index bc1521c4069..8a1d14b48a1 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_unchecked(self as *mut _), + vec: Shared::from(self), } } } diff --git a/src/liballoc/vec_deque.rs b/src/liballoc/vec_deque.rs index a99b7bbe053..fdd6c79ef2e 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_unchecked(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 65ebb8c5ae3..3ff1068b937 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -90,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 29e2114f38a..9413a908cb1 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -1164,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 @@ -1296,3 +1310,17 @@ impl From> for Shared { 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/librustc_data_structures/array_vec.rs b/src/librustc_data_structures/array_vec.rs index de028f61090..ced73e9e426 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_unchecked(self as *mut _), + array_vec: Shared::from(self), } } } diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index f3aec589e7d..3844690860b 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -877,7 +877,7 @@ impl RawTable { elems_left: elems_left, marker: marker::PhantomData, }, - table: unsafe { Shared::new_unchecked(self) }, + table: Shared::from(self), marker: marker::PhantomData, } } -- cgit 1.4.1-3-g733a5 From 938552a2289d6018e78d9626f011d8eea59be7d9 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 17 Jul 2017 14:28:02 +0200 Subject: Use checked NonZero constructor instead of explicit null check in btree --- src/liballoc/btree/node.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/btree/node.rs b/src/liballoc/btree/node.rs index a6cbab8497b..06d3a113b94 100644 --- a/src/liballoc/btree/node.rs +++ b/src/liballoc/btree/node.rs @@ -382,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_unchecked(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) } } -- cgit 1.4.1-3-g733a5