about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-04-30 13:58:00 +0000
committerbors <bors@rust-lang.org>2023-04-30 13:58:00 +0000
commit831c9298c8e6542e3ab395216e98aec21f60b470 (patch)
treefefa3361066acde0c66f593dcee9e6c3421fb29d
parent89158e210ce0b9550b42c65ede244087f2e144b5 (diff)
parent18d2c60975c356d36ce6138130b5e0fdc79b1424 (diff)
downloadrust-831c9298c8e6542e3ab395216e98aec21f60b470.tar.gz
rust-831c9298c8e6542e3ab395216e98aec21f60b470.zip
Auto merge of #103406 - Jules-Bertholet:from_clone_slice_to_box, r=dtolnay
Loosen `From<&[T]> for Box<[T]>` bound to `T: Clone`

Also loosens `From<Cow<'_, [T]>> for Box<[T]>`'s bound.

[Discussion on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/From.3C.26.5BT.5D.3E.20impls.20consistency)
-rw-r--r--library/alloc/src/boxed.rs39
1 files changed, 31 insertions, 8 deletions
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index ad86c193098..1768687e8cd 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -1455,9 +1455,36 @@ where
     }
 }
 
+/// Specialization trait used for `From<&[T]>`.
+#[cfg(not(no_global_oom_handling))]
+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))]
 #[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]>`
     ///
     /// This conversion allocates on the heap
@@ -1471,19 +1498,15 @@ impl<T: Copy> 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()
-        }
+        <Self as BoxFromSlice<T>>::from_slice(slice)
     }
 }
 
 #[cfg(not(no_global_oom_handling))]
 #[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]>`
     ///
     /// When `cow` is the `Cow::Borrowed` variant, this