about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/array.rs53
-rw-r--r--src/libcore/tests/array.rs23
-rw-r--r--src/libstd/error.rs8
-rw-r--r--src/libstd/lib.rs2
4 files changed, 86 insertions, 0 deletions
diff --git a/src/libcore/array.rs b/src/libcore/array.rs
index 6a7926fecde..3d24f8902bd 100644
--- a/src/libcore/array.rs
+++ b/src/libcore/array.rs
@@ -21,6 +21,7 @@
 
 use borrow::{Borrow, BorrowMut};
 use cmp::Ordering;
+use convert::TryFrom;
 use fmt;
 use hash::{Hash, self};
 use marker::Unsize;
@@ -57,6 +58,30 @@ unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
     }
 }
 
+/// The error type returned when a conversion from a slice to an array fails.
+#[unstable(feature = "try_from", issue = "33417")]
+#[derive(Debug, Copy, Clone)]
+pub struct TryFromSliceError(());
+
+impl fmt::Display for TryFromSliceError {
+    #[inline]
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(self.__description(), f)
+    }
+}
+
+impl TryFromSliceError {
+    #[unstable(feature = "array_error_internals",
+           reason = "available through Error trait and this method should not \
+                     be exposed publicly",
+           issue = "0")]
+    #[inline]
+    #[doc(hidden)]
+    pub fn __description(&self) -> &str {
+        "could not convert slice to array"
+    }
+}
+
 macro_rules! __impl_slice_eq1 {
     ($Lhs: ty, $Rhs: ty) => {
         __impl_slice_eq1! { $Lhs, $Rhs, Sized }
@@ -123,6 +148,34 @@ macro_rules! array_impls {
                 }
             }
 
+            #[unstable(feature = "try_from", issue = "33417")]
+            impl<'a, T> TryFrom<&'a [T]> for &'a [T; $N] {
+                type Error = TryFromSliceError;
+
+                fn try_from(slice: &[T]) -> Result<&[T; $N], TryFromSliceError> {
+                    if slice.len() == $N {
+                        let ptr = slice.as_ptr() as *const [T; $N];
+                        unsafe { Ok(&*ptr) }
+                    } else {
+                        Err(TryFromSliceError(()))
+                    }
+                }
+            }
+
+            #[unstable(feature = "try_from", issue = "33417")]
+            impl<'a, T> TryFrom<&'a mut [T]> for &'a mut [T; $N] {
+                type Error = TryFromSliceError;
+
+                fn try_from(slice: &mut [T]) -> Result<&mut [T; $N], TryFromSliceError> {
+                    if slice.len() == $N {
+                        let ptr = slice.as_mut_ptr() as *mut [T; $N];
+                        unsafe { Ok(&mut *ptr) }
+                    } else {
+                        Err(TryFromSliceError(()))
+                    }
+                }
+            }
+
             #[stable(feature = "rust1", since = "1.0.0")]
             impl<T: Hash> Hash for [T; $N] {
                 fn hash<H: hash::Hasher>(&self, state: &mut H) {
diff --git a/src/libcore/tests/array.rs b/src/libcore/tests/array.rs
index 6af031dee58..6278d5e23e0 100644
--- a/src/libcore/tests/array.rs
+++ b/src/libcore/tests/array.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 use core::array::FixedSizeArray;
+use core::convert::TryFrom;
 
 #[test]
 fn fixed_size_array() {
@@ -26,3 +27,25 @@ fn fixed_size_array() {
     assert_eq!(FixedSizeArray::as_mut_slice(&mut empty_array).len(), 0);
     assert_eq!(FixedSizeArray::as_mut_slice(&mut empty_zero_sized).len(), 0);
 }
+
+#[test]
+fn array_try_from() {
+    macro_rules! test {
+        ($($N:expr)+) => {
+            $({
+                type Array = [u8; $N];
+                let array: Array = [0; $N];
+                let slice: &[u8] = &array[..];
+
+                let result = <&Array>::try_from(slice);
+                assert_eq!(&array, result.unwrap());
+            })+
+        }
+    }
+    test! {
+         0  1  2  3  4  5  6  7  8  9
+        10 11 12 13 14 15 16 17 18 19
+        20 21 22 23 24 25 26 27 28 29
+        30 31 32
+    }
+}
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 166439692d4..231b0be9276 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -57,6 +57,7 @@ use borrow::Cow;
 use cell;
 use char;
 use convert;
+use core::array;
 use fmt::{self, Debug, Display};
 use mem::transmute;
 use num;
@@ -282,6 +283,13 @@ impl Error for num::TryFromIntError {
     }
 }
 
+#[unstable(feature = "try_from", issue = "33417")]
+impl Error for array::TryFromSliceError {
+    fn description(&self) -> &str {
+        self.__description()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Error for num::ParseFloatError {
     fn description(&self) -> &str {
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 012883d0853..5cf1d225b90 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -243,6 +243,7 @@
 #![feature(allow_internal_unsafe)]
 #![feature(allow_internal_unstable)]
 #![feature(align_offset)]
+#![feature(array_error_internals)]
 #![feature(asm)]
 #![feature(attr_literals)]
 #![feature(box_syntax)]
@@ -267,6 +268,7 @@
 #![feature(core_intrinsics)]
 #![feature(dropck_eyepatch)]
 #![feature(exact_size_is_empty)]
+#![feature(fixed_size_array)]
 #![feature(float_from_str_radix)]
 #![feature(fn_traits)]
 #![feature(fnbox)]