about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorJake Goulding <jake.goulding@gmail.com>2019-06-04 08:15:47 -0400
committerJake Goulding <jake.goulding@gmail.com>2019-08-05 10:26:53 -0400
commit32324d22c33dda31eadf49c5f27d6e6ff38a3ef1 (patch)
tree4ceca954cd7f02dfd8000317f3021fb8e4e3dd35 /src/liballoc
parent4be067558962c004b638e4c6f162d50f7c0c98b6 (diff)
downloadrust-32324d22c33dda31eadf49c5f27d6e6ff38a3ef1.tar.gz
rust-32324d22c33dda31eadf49c5f27d6e6ff38a3ef1.zip
Add implementations for converting boxed slices into boxed arrays
This mirrors the implementations of reference slices into arrays.
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/boxed.rs19
-rw-r--r--src/liballoc/lib.rs2
-rw-r--r--src/liballoc/rc.rs19
-rw-r--r--src/liballoc/rc/tests.rs14
-rw-r--r--src/liballoc/sync.rs19
-rw-r--r--src/liballoc/sync/tests.rs14
-rw-r--r--src/liballoc/tests.rs13
7 files changed, 94 insertions, 6 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 488fda0b247..c92db517cad 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -76,9 +76,10 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use core::any::Any;
+use core::array::LengthAtMost32;
 use core::borrow;
 use core::cmp::Ordering;
-use core::convert::From;
+use core::convert::{From, TryFrom};
 use core::fmt;
 use core::future::Future;
 use core::hash::{Hash, Hasher};
@@ -612,6 +613,22 @@ impl From<Box<str>> for Box<[u8]> {
     }
 }
 
+#[unstable(feature = "boxed_slice_try_from", issue = "0")]
+impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]>
+where
+    [T; N]: LengthAtMost32,
+{
+    type Error = Box<[T]>;
+
+    fn try_from(boxed_slice: Box<[T]>) -> Result<Self, Self::Error> {
+        if boxed_slice.len() == N {
+            Ok(unsafe { Box::from_raw(Box::into_raw(boxed_slice) as *mut [T; N]) })
+        } else {
+            Err(boxed_slice)
+        }
+    }
+}
+
 impl Box<dyn Any> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 98fa754759a..deea74daa52 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -82,9 +82,9 @@
 #![feature(box_syntax)]
 #![feature(cfg_target_has_atomic)]
 #![feature(coerce_unsized)]
-#![cfg_attr(not(bootstrap), feature(const_in_array_repeat_expressions))]
 #![feature(const_generic_impls_guard)]
 #![feature(const_generics)]
+#![cfg_attr(not(bootstrap), feature(const_in_array_repeat_expressions))]
 #![feature(dispatch_from_dyn)]
 #![feature(core_intrinsics)]
 #![feature(dropck_eyepatch)]
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index e33aac3af47..0c406a92029 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -232,6 +232,7 @@ use crate::boxed::Box;
 use std::boxed::Box;
 
 use core::any::Any;
+use core::array::LengthAtMost32;
 use core::borrow;
 use core::cell::Cell;
 use core::cmp::Ordering;
@@ -245,7 +246,7 @@ use core::ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn};
 use core::pin::Pin;
 use core::ptr::{self, NonNull};
 use core::slice::{self, from_raw_parts_mut};
-use core::convert::From;
+use core::convert::{From, TryFrom};
 use core::usize;
 
 use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error};
@@ -1257,6 +1258,22 @@ impl<T> From<Vec<T>> for Rc<[T]> {
     }
 }
 
+#[unstable(feature = "boxed_slice_try_from", issue = "0")]
+impl<T, const N: usize> TryFrom<Rc<[T]>> for Rc<[T; N]>
+where
+    [T; N]: LengthAtMost32,
+{
+    type Error = Rc<[T]>;
+
+    fn try_from(boxed_slice: Rc<[T]>) -> Result<Self, Self::Error> {
+        if boxed_slice.len() == N {
+            Ok(unsafe { Rc::from_raw(Rc::into_raw(boxed_slice) as *mut [T; N]) })
+        } else {
+            Err(boxed_slice)
+        }
+    }
+}
+
 #[stable(feature = "shared_from_iter", since = "1.37.0")]
 impl<T> iter::FromIterator<T> for Rc<[T]> {
     /// Takes each element in the `Iterator` and collects it into an `Rc<[T]>`.
diff --git a/src/liballoc/rc/tests.rs b/src/liballoc/rc/tests.rs
index 72816a5c120..6fd3f909357 100644
--- a/src/liballoc/rc/tests.rs
+++ b/src/liballoc/rc/tests.rs
@@ -6,7 +6,7 @@ use std::option::Option::{self, None, Some};
 use std::result::Result::{Err, Ok};
 use std::mem::drop;
 use std::clone::Clone;
-use std::convert::From;
+use std::convert::{From, TryInto};
 
 #[test]
 fn test_clone() {
@@ -425,3 +425,15 @@ fn test_downcast() {
     assert!(r2str.is_ok());
     assert_eq!(r2str.unwrap(), Rc::new("abc"));
 }
+
+#[test]
+fn test_array_from_slice() {
+    let v = vec![1, 2, 3];
+    let r: Rc<[u32]> = Rc::from(v);
+
+    let a: Result<Rc<[u32; 3]>, _> = r.clone().try_into();
+    assert!(a.is_ok());
+
+    let a: Result<Rc<[u32; 2]>, _> = r.clone().try_into();
+    assert!(a.is_err());
+}
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index e11873218e8..7d3b2656a7b 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -7,6 +7,7 @@
 //! [arc]: struct.Arc.html
 
 use core::any::Any;
+use core::array::LengthAtMost32;
 use core::sync::atomic;
 use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
 use core::borrow;
@@ -21,7 +22,7 @@ use core::ptr::{self, NonNull};
 use core::marker::{Unpin, Unsize, PhantomData};
 use core::hash::{Hash, Hasher};
 use core::{isize, usize};
-use core::convert::From;
+use core::convert::{From, TryFrom};
 use core::slice::{self, from_raw_parts_mut};
 
 use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error};
@@ -1826,6 +1827,22 @@ impl<T> From<Vec<T>> for Arc<[T]> {
     }
 }
 
+#[unstable(feature = "boxed_slice_try_from", issue = "0")]
+impl<T, const N: usize> TryFrom<Arc<[T]>> for Arc<[T; N]>
+where
+    [T; N]: LengthAtMost32,
+{
+    type Error = Arc<[T]>;
+
+    fn try_from(boxed_slice: Arc<[T]>) -> Result<Self, Self::Error> {
+        if boxed_slice.len() == N {
+            Ok(unsafe { Arc::from_raw(Arc::into_raw(boxed_slice) as *mut [T; N]) })
+        } else {
+            Err(boxed_slice)
+        }
+    }
+}
+
 #[stable(feature = "shared_from_iter", since = "1.37.0")]
 impl<T> iter::FromIterator<T> for Arc<[T]> {
     /// Takes each element in the `Iterator` and collects it into an `Arc<[T]>`.
diff --git a/src/liballoc/sync/tests.rs b/src/liballoc/sync/tests.rs
index 2e0c62f50c1..9220f5e0333 100644
--- a/src/liballoc/sync/tests.rs
+++ b/src/liballoc/sync/tests.rs
@@ -9,7 +9,7 @@ use std::option::Option::{self, None, Some};
 use std::sync::atomic::{self, Ordering::{Acquire, SeqCst}};
 use std::thread;
 use std::sync::Mutex;
-use std::convert::From;
+use std::convert::{From, TryInto};
 
 use crate::vec::Vec;
 
@@ -478,3 +478,15 @@ fn test_downcast() {
     assert!(r2str.is_ok());
     assert_eq!(r2str.unwrap(), Arc::new("abc"));
 }
+
+#[test]
+fn test_array_from_slice() {
+    let v = vec![1, 2, 3];
+    let r: Arc<[u32]> = Arc::from(v);
+
+    let a: Result<Arc<[u32; 3]>, _> = r.clone().try_into();
+    assert!(a.is_ok());
+
+    let a: Result<Arc<[u32; 2]>, _> = r.clone().try_into();
+    assert!(a.is_err());
+}
diff --git a/src/liballoc/tests.rs b/src/liballoc/tests.rs
index 654eabd0703..ed46ba8a1b9 100644
--- a/src/liballoc/tests.rs
+++ b/src/liballoc/tests.rs
@@ -1,6 +1,7 @@
 //! Test for `boxed` mod.
 
 use core::any::Any;
+use core::convert::TryInto;
 use core::ops::Deref;
 use core::result::Result::{Err, Ok};
 use core::clone::Clone;
@@ -138,3 +139,15 @@ fn boxed_slice_from_iter() {
     assert_eq!(boxed.len(), 100);
     assert_eq!(boxed[7], 7);
 }
+
+#[test]
+fn test_array_from_slice() {
+    let v = vec![1, 2, 3];
+    let r: Box<[u32]> = v.into_boxed_slice();
+
+    let a: Result<Box<[u32; 3]>, _> = r.clone().try_into();
+    assert!(a.is_ok());
+
+    let a: Result<Box<[u32; 2]>, _> = r.clone().try_into();
+    assert!(a.is_err());
+}