@@ -16,7 +16,7 @@ use crate::mem::{self, MaybeUninit};
1616use crate :: ops:: {
1717 ChangeOutputType , ControlFlow , FromResidual , Index , IndexMut , NeverShortCircuit , Residual , Try ,
1818} ;
19- use crate :: ptr:: { null, null_mut} ;
19+ use crate :: ptr:: { copy_nonoverlapping , null, null_mut} ;
2020use crate :: slice:: { Iter , IterMut } ;
2121
2222mod ascii;
@@ -154,6 +154,42 @@ pub const fn from_mut<T>(s: &mut T) -> &mut [T; 1] {
154154 unsafe { & mut * ( s as * mut T ) . cast :: < [ T ; 1 ] > ( ) }
155155}
156156
157+ /// Tries to create an array `[T; N]` by copying from a slice `&[T]`.
158+ /// Succeeds if `slice.len() == N`.
159+ ///
160+ /// # Example
161+ ///
162+ /// ```
163+ /// use core::array;
164+ ///
165+ /// let data = array::try_from_slice(&[255, 127, 63, 31]).unwrap();
166+ ///
167+ /// let value = u32::from_le_bytes(data);
168+ /// assert_eq!(value, 0x1F3F7FFF);
169+ /// ```
170+ #[ inline]
171+ #[ unstable( feature = "array_try_from_slice" , issue = "133440" ) ]
172+ #[ rustc_const_unstable( feature = "array_try_from_slice" , issue = "133440" ) ]
173+ pub const fn try_from_slice < T , const N : usize > ( slice : & [ T ] ) -> Result < [ T ; N ] , TryFromSliceError >
174+ where
175+ T : Copy ,
176+ {
177+ if slice. len ( ) == N {
178+ // SAFETY: `MaybeUninit` always supports being in an unitialised state, even as an array.
179+ let mut me: [ MaybeUninit < T > ; N ] = unsafe { MaybeUninit :: uninit ( ) . assume_init ( ) } ;
180+
181+ // SAFETY: `me` and `slice` are both exclusive as the former is a mutable reference. They also both contain `N` elements. `T` additionally implements `Copy`.
182+ unsafe { copy_nonoverlapping ( slice. as_ptr ( ) , me. as_mut_ptr ( ) as * mut T , N ) } ;
183+
184+ // SAFETY: `MaybeUninit<T>` is transparent to `T`, and every item has also been initialised.
185+ let me = unsafe { transmute_unchecked ( me) } ;
186+
187+ Ok ( me)
188+ } else {
189+ Err ( TryFromSliceError ( ( ) ) )
190+ }
191+ }
192+
157193/// The error type returned when a conversion from a slice to an array fails.
158194#[ stable( feature = "try_from" , since = "1.34.0" ) ]
159195#[ rustc_allowed_through_unstable_modules]
@@ -214,8 +250,8 @@ impl<T, const N: usize> BorrowMut<[T]> for [T; N] {
214250 }
215251}
216252
217- /// Tries to create an array `[T; N]` by copying from a slice `&[T]`. Succeeds if
218- /// `slice.len() == N`.
253+ /// Tries to create an array `[T; N]` by copying from a slice `&[T]`.
254+ /// Succeeds if `slice.len() == N`.
219255///
220256/// ```
221257/// let bytes: [u8; 3] = [1, 0, 2];
@@ -235,7 +271,7 @@ where
235271
236272 #[ inline]
237273 fn try_from ( slice : & [ T ] ) -> Result < [ T ; N ] , TryFromSliceError > {
238- < & Self > :: try_from ( slice) . copied ( )
274+ try_from_slice ( slice)
239275 }
240276}
241277
@@ -260,7 +296,7 @@ where
260296
261297 #[ inline]
262298 fn try_from ( slice : & mut [ T ] ) -> Result < [ T ; N ] , TryFromSliceError > {
263- < Self > :: try_from ( & * slice)
299+ try_from_slice ( slice)
264300 }
265301}
266302
0 commit comments