Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the "main" constructors of NonZero/Shared/Unique return Option #42959

Merged
merged 13 commits into from
Jul 26, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/doc/nomicon
6 changes: 3 additions & 3 deletions src/liballoc/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
}
Expand Down Expand Up @@ -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)
})
}
}
Expand Down Expand Up @@ -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"))
Expand Down
6 changes: 3 additions & 3 deletions src/liballoc/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 _),
}
}
}
Expand Down Expand Up @@ -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(),
Expand Down
31 changes: 31 additions & 0 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down
20 changes: 8 additions & 12 deletions src/liballoc/btree/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
}
}
Expand Down Expand Up @@ -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)
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/liballoc/linked_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
6 changes: 3 additions & 3 deletions src/liballoc/raw_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand Down Expand Up @@ -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,
}
Expand All @@ -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,
}
Expand Down
30 changes: 14 additions & 16 deletions src/liballoc/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
})),
}
}

Expand Down Expand Up @@ -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 _)
}
}
}
Expand All @@ -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) }
}
}
}
Expand Down Expand Up @@ -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 _) }
}
}
}
Expand Down Expand Up @@ -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(),
Expand Down
4 changes: 2 additions & 2 deletions src/liballoc/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
}
}
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/vec_deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading