Skip to content

Commit

Permalink
Auto merge of #56998 - dwijnand:from-Arc/Rc-to-NonNull, r=<try>
Browse files Browse the repository at this point in the history
Add Into<NonNull<T>> impls for Arc<T>/Rc<T>

/cc @withoutboats who mentioned to me this might be worth adding to the standard library, in withoutboats/smart#4
/cc @kennytm who last year didn't love the idea of having an Into<NonNull<T>> for Box<T>, in #46952
  • Loading branch information
bors committed Jan 2, 2019
2 parents ec19464 + 98b46ba commit 185e079
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,15 @@ impl From<Box<str>> for Box<[u8]> {
}
}

#[allow(incoherent_fundamental_impls)]
#[unstable(feature = "box_into_raw_non_null", issue = "47336")]
impl<T: ?Sized> Into<NonNull<T>> for Box<T> {
#[inline]
fn into(self) -> NonNull<T> {
Box::into_unique(self).into()
}
}

impl Box<dyn Any> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
8 changes: 8 additions & 0 deletions src/liballoc/boxed_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,11 @@ fn boxed_slice_from_iter() {
assert_eq!(boxed.len(), 100);
assert_eq!(boxed[7], 7);
}

#[test]
fn to_nonnull() {
let boxed: Box<i32> = Box::from(0);
let ptr: std::ptr::NonNull<i32> = boxed.into();
let deref = unsafe { *ptr.as_ref() };
assert_eq!(deref, 0);
}
8 changes: 8 additions & 0 deletions src/liballoc/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1176,6 +1176,14 @@ impl<T> From<Vec<T>> for Rc<[T]> {
}
}

#[unstable(feature = "rc_into_nonnull", reason = "newly added", issue = "0")]
impl<T: ?Sized> Into<NonNull<T>> for Rc<T> {
#[inline]
fn into(self) -> NonNull<T> {
unsafe { NonNull::new_unchecked(Rc::into_raw(self) as *mut _) }
}
}

/// `Weak` is a version of [`Rc`] that holds a non-owning reference to the
/// managed value. The value is accessed by calling [`upgrade`] on the `Weak`
/// pointer, which returns an [`Option`]`<`[`Rc`]`<T>>`.
Expand Down
8 changes: 8 additions & 0 deletions src/liballoc/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1572,6 +1572,14 @@ impl<T> From<Vec<T>> for Arc<[T]> {
}
}

#[unstable(feature = "arc_into_nonnull", reason = "newly added", issue = "0")]
impl<T: ?Sized> Into<NonNull<T>> for Arc<T> {
#[inline]
fn into(self) -> NonNull<T> {
unsafe { NonNull::new_unchecked(Arc::into_raw(self) as *mut _) }
}
}

#[cfg(test)]
mod tests {
use std::boxed::Box;
Expand Down
7 changes: 7 additions & 0 deletions src/liballoc/tests/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,10 @@ fn eq() {
assert!(!(x != x));
assert_eq!(*x.0.borrow(), 0);
}

#[test]
fn to_nonnull() {
let ptr: std::ptr::NonNull<i32> = Arc::new(0).into();
let deref = unsafe { *ptr.as_ref() };
assert_eq!(deref, 0);
}
7 changes: 7 additions & 0 deletions src/liballoc/tests/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,10 @@ fn eq() {
assert!(!(x != x));
assert_eq!(*x.0.borrow(), 0);
}

#[test]
fn to_nonnull() {
let ptr: std::ptr::NonNull<i32> = Rc::new(0).into();
let deref = unsafe { *ptr.as_ref() };
assert_eq!(deref, 0);
}

0 comments on commit 185e079

Please sign in to comment.