Skip to content

Commit 185e079

Browse files
committed
Auto merge of #56998 - dwijnand:from-Arc/Rc-to-NonNull, r=<try>
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
2 parents ec19464 + 98b46ba commit 185e079

File tree

6 files changed

+47
-0
lines changed

6 files changed

+47
-0
lines changed

src/liballoc/boxed.rs

+9
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,15 @@ impl From<Box<str>> for Box<[u8]> {
527527
}
528528
}
529529

530+
#[allow(incoherent_fundamental_impls)]
531+
#[unstable(feature = "box_into_raw_non_null", issue = "47336")]
532+
impl<T: ?Sized> Into<NonNull<T>> for Box<T> {
533+
#[inline]
534+
fn into(self) -> NonNull<T> {
535+
Box::into_unique(self).into()
536+
}
537+
}
538+
530539
impl Box<dyn Any> {
531540
#[inline]
532541
#[stable(feature = "rust1", since = "1.0.0")]

src/liballoc/boxed_test.rs

+8
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,11 @@ fn boxed_slice_from_iter() {
138138
assert_eq!(boxed.len(), 100);
139139
assert_eq!(boxed[7], 7);
140140
}
141+
142+
#[test]
143+
fn to_nonnull() {
144+
let boxed: Box<i32> = Box::from(0);
145+
let ptr: std::ptr::NonNull<i32> = boxed.into();
146+
let deref = unsafe { *ptr.as_ref() };
147+
assert_eq!(deref, 0);
148+
}

src/liballoc/rc.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,14 @@ impl<T> From<Vec<T>> for Rc<[T]> {
11761176
}
11771177
}
11781178

1179+
#[unstable(feature = "rc_into_nonnull", reason = "newly added", issue = "0")]
1180+
impl<T: ?Sized> Into<NonNull<T>> for Rc<T> {
1181+
#[inline]
1182+
fn into(self) -> NonNull<T> {
1183+
unsafe { NonNull::new_unchecked(Rc::into_raw(self) as *mut _) }
1184+
}
1185+
}
1186+
11791187
/// `Weak` is a version of [`Rc`] that holds a non-owning reference to the
11801188
/// managed value. The value is accessed by calling [`upgrade`] on the `Weak`
11811189
/// pointer, which returns an [`Option`]`<`[`Rc`]`<T>>`.

src/liballoc/sync.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1572,6 +1572,14 @@ impl<T> From<Vec<T>> for Arc<[T]> {
15721572
}
15731573
}
15741574

1575+
#[unstable(feature = "arc_into_nonnull", reason = "newly added", issue = "0")]
1576+
impl<T: ?Sized> Into<NonNull<T>> for Arc<T> {
1577+
#[inline]
1578+
fn into(self) -> NonNull<T> {
1579+
unsafe { NonNull::new_unchecked(Arc::into_raw(self) as *mut _) }
1580+
}
1581+
}
1582+
15751583
#[cfg(test)]
15761584
mod tests {
15771585
use std::boxed::Box;

src/liballoc/tests/arc.rs

+7
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,10 @@ fn eq() {
8585
assert!(!(x != x));
8686
assert_eq!(*x.0.borrow(), 0);
8787
}
88+
89+
#[test]
90+
fn to_nonnull() {
91+
let ptr: std::ptr::NonNull<i32> = Arc::new(0).into();
92+
let deref = unsafe { *ptr.as_ref() };
93+
assert_eq!(deref, 0);
94+
}

src/liballoc/tests/rc.rs

+7
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,10 @@ fn eq() {
8585
assert!(!(x != x));
8686
assert_eq!(*x.0.borrow(), 0);
8787
}
88+
89+
#[test]
90+
fn to_nonnull() {
91+
let ptr: std::ptr::NonNull<i32> = Rc::new(0).into();
92+
let deref = unsafe { *ptr.as_ref() };
93+
assert_eq!(deref, 0);
94+
}

0 commit comments

Comments
 (0)