Skip to content

Commit 1322177

Browse files
committed
Implement TryFrom for array reference types
There are many cases where a buffer with a static compile-time size is preferred over a slice with a dynamic size. This allows for performing a checked conversion from &[T] to &[T; N]. This may also lead to compile-time optimizations involving [T; N] such as loop unrolling.
1 parent 1b55d19 commit 1322177

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

src/libcore/array.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
use borrow::{Borrow, BorrowMut};
2323
use cmp::Ordering;
24+
use convert::TryFrom;
2425
use fmt;
2526
use hash::{Hash, self};
2627
use marker::Unsize;
@@ -57,6 +58,11 @@ unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
5758
}
5859
}
5960

61+
/// The error type returned when a conversion from a slice to an array fails.
62+
#[unstable(feature = "try_from", issue = "33417")]
63+
#[derive(Debug, Copy, Clone)]
64+
pub struct TryFromSliceError(());
65+
6066
macro_rules! __impl_slice_eq1 {
6167
($Lhs: ty, $Rhs: ty) => {
6268
__impl_slice_eq1! { $Lhs, $Rhs, Sized }
@@ -123,6 +129,34 @@ macro_rules! array_impls {
123129
}
124130
}
125131

132+
#[unstable(feature = "try_from", issue = "33417")]
133+
impl<'a, T> TryFrom<&'a [T]> for &'a [T; $N] {
134+
type Error = TryFromSliceError;
135+
136+
fn try_from(slice: &[T]) -> Result<&[T; $N], TryFromSliceError> {
137+
if slice.len() == $N {
138+
let ptr = slice.as_ptr() as *const [T; $N];
139+
unsafe { Ok(&*ptr) }
140+
} else {
141+
Err(TryFromSliceError(()))
142+
}
143+
}
144+
}
145+
146+
#[unstable(feature = "try_from", issue = "33417")]
147+
impl<'a, T> TryFrom<&'a mut [T]> for &'a mut [T; $N] {
148+
type Error = TryFromSliceError;
149+
150+
fn try_from(slice: &mut [T]) -> Result<&mut [T; $N], TryFromSliceError> {
151+
if slice.len() == $N {
152+
let ptr = slice.as_mut_ptr() as *mut [T; $N];
153+
unsafe { Ok(&mut *ptr) }
154+
} else {
155+
Err(TryFromSliceError(()))
156+
}
157+
}
158+
}
159+
126160
#[stable(feature = "rust1", since = "1.0.0")]
127161
impl<T: Hash> Hash for [T; $N] {
128162
fn hash<H: hash::Hasher>(&self, state: &mut H) {

0 commit comments

Comments
 (0)