Loosen From<&[T]> for Box<[T]> bound to T: Clone

This commit is contained in:
Jules Bertholet 2022-10-22 12:13:03 -04:00
parent 1c42cb4ef0
commit 075ee26b68
No known key found for this signature in database
GPG Key ID: 32034DAFC38C1BFC

View File

@ -1455,9 +1455,35 @@ where
} }
} }
/// Specialization trait used for `From<&[T]>`.
trait BoxFromSlice<T> {
fn from_slice(slice: &[T]) -> Self;
}
#[cfg(not(no_global_oom_handling))]
impl<T: Clone> BoxFromSlice<T> for Box<[T]> {
#[inline]
default fn from_slice(slice: &[T]) -> Self {
slice.to_vec().into_boxed_slice()
}
}
#[cfg(not(no_global_oom_handling))]
impl<T: Copy> BoxFromSlice<T> 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))] #[cfg(not(no_global_oom_handling))]
#[stable(feature = "box_from_slice", since = "1.17.0")] #[stable(feature = "box_from_slice", since = "1.17.0")]
impl<T: Copy> From<&[T]> for Box<[T]> { impl<T: Clone> From<&[T]> for Box<[T]> {
/// Converts a `&[T]` into a `Box<[T]>` /// Converts a `&[T]` into a `Box<[T]>`
/// ///
/// This conversion allocates on the heap /// This conversion allocates on the heap
@ -1471,19 +1497,15 @@ impl<T: Copy> From<&[T]> for Box<[T]> {
/// ///
/// println!("{boxed_slice:?}"); /// println!("{boxed_slice:?}");
/// ``` /// ```
#[inline]
fn from(slice: &[T]) -> Box<[T]> { fn from(slice: &[T]) -> Box<[T]> {
let len = slice.len(); <Self as BoxFromSlice<T>>::from_slice(slice)
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))] #[cfg(not(no_global_oom_handling))]
#[stable(feature = "box_from_cow", since = "1.45.0")] #[stable(feature = "box_from_cow", since = "1.45.0")]
impl<T: Copy> From<Cow<'_, [T]>> for Box<[T]> { impl<T: Clone> From<Cow<'_, [T]>> for Box<[T]> {
/// Converts a `Cow<'_, [T]>` into a `Box<[T]>` /// Converts a `Cow<'_, [T]>` into a `Box<[T]>`
/// ///
/// When `cow` is the `Cow::Borrowed` variant, this /// When `cow` is the `Cow::Borrowed` variant, this