From 9adb45946dc9aa6a0f7203003330820d1f521887 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Bj=C3=B8rnager=20Jensen?= Date: Mon, 16 Dec 2024 10:42:26 +0100 Subject: [PATCH] Add 'into_array' conversion destructors for 'Box', 'Rc', and 'Arc'; --- alloc/src/boxed.rs | 20 ++++++++++++++++++++ alloc/src/rc.rs | 20 ++++++++++++++++++++ alloc/src/sync.rs | 20 ++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/alloc/src/boxed.rs b/alloc/src/boxed.rs index 23b85fbd4ebc3..ca3bd24a42031 100644 --- a/alloc/src/boxed.rs +++ b/alloc/src/boxed.rs @@ -761,6 +761,26 @@ impl Box<[T]> { }; unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, Global).into_box(len)) } } + + /// Converts the boxed slice into a boxed array. + /// + /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub fn into_array(self) -> Option> { + if self.len() == N { + let ptr = Self::into_raw(self) as *mut [T; N]; + + // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. + let me = unsafe { Box::from_raw(ptr) }; + Some(me) + } else { + None + } + } } impl Box<[T], A> { diff --git a/alloc/src/rc.rs b/alloc/src/rc.rs index b7ec3af9818a0..e014404eff35b 100644 --- a/alloc/src/rc.rs +++ b/alloc/src/rc.rs @@ -1084,6 +1084,26 @@ impl Rc<[T]> { )) } } + + /// Converts the reference-counted slice into a reference-counted array. + /// + /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub fn into_array(self) -> Option> { + if self.len() == N { + let ptr = Self::into_raw(self) as *const [T; N]; + + // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. + let me = unsafe { Rc::from_raw(ptr) }; + Some(me) + } else { + None + } + } } impl Rc<[T], A> { diff --git a/alloc/src/sync.rs b/alloc/src/sync.rs index 9be0b3e3e8801..b34a6d3f660c8 100644 --- a/alloc/src/sync.rs +++ b/alloc/src/sync.rs @@ -1203,6 +1203,26 @@ impl Arc<[T]> { )) } } + + /// Converts the reference-counted slice into a reference-counted array. + /// + /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub fn into_array(self) -> Option> { + if self.len() == N { + let ptr = Self::into_raw(self) as *const [T; N]; + + // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. + let me = unsafe { Arc::from_raw(ptr) }; + Some(me) + } else { + None + } + } } impl Arc<[T], A> {