From 075ee26b6884514a65b0822b8745a6f5f35e8720 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sat, 22 Oct 2022 12:13:03 -0400 Subject: [PATCH 1/2] Loosen `From<&[T]> for Box<[T]>` bound to T: Clone --- library/alloc/src/boxed.rs | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index ad86c19309831..2a26661cab4a7 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1455,9 +1455,35 @@ where } } +/// Specialization trait used for `From<&[T]>`. +trait BoxFromSlice { + fn from_slice(slice: &[T]) -> Self; +} + +#[cfg(not(no_global_oom_handling))] +impl BoxFromSlice for Box<[T]> { + #[inline] + default fn from_slice(slice: &[T]) -> Self { + slice.to_vec().into_boxed_slice() + } +} + +#[cfg(not(no_global_oom_handling))] +impl BoxFromSlice for Box<[T]> { + #[inline] + fn from_slice(slice: &[T]) -> Self { + let len = slice.len(); + let buf = RawVec::with_capacity(len); + unsafe { + ptr::copy_nonoverlapping(slice.as_ptr(), buf.ptr(), len); + buf.into_box(slice.len()).assume_init() + } + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "box_from_slice", since = "1.17.0")] -impl From<&[T]> for Box<[T]> { +impl From<&[T]> for Box<[T]> { /// Converts a `&[T]` into a `Box<[T]>` /// /// This conversion allocates on the heap @@ -1471,19 +1497,15 @@ impl From<&[T]> for Box<[T]> { /// /// println!("{boxed_slice:?}"); /// ``` + #[inline] fn from(slice: &[T]) -> Box<[T]> { - let len = slice.len(); - let buf = RawVec::with_capacity(len); - unsafe { - ptr::copy_nonoverlapping(slice.as_ptr(), buf.ptr(), len); - buf.into_box(slice.len()).assume_init() - } + >::from_slice(slice) } } #[cfg(not(no_global_oom_handling))] #[stable(feature = "box_from_cow", since = "1.45.0")] -impl From> for Box<[T]> { +impl From> for Box<[T]> { /// Converts a `Cow<'_, [T]>` into a `Box<[T]>` /// /// When `cow` is the `Cow::Borrowed` variant, this From 18d2c60975c356d36ce6138130b5e0fdc79b1424 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sat, 29 Apr 2023 18:10:10 -0400 Subject: [PATCH 2/2] `cfg`-gate `BoxFromSlice` trait Co-authored-by: David Tolnay --- library/alloc/src/boxed.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 2a26661cab4a7..1768687e8cd02 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1456,6 +1456,7 @@ where } /// Specialization trait used for `From<&[T]>`. +#[cfg(not(no_global_oom_handling))] trait BoxFromSlice { fn from_slice(slice: &[T]) -> Self; }