@@ -1342,3 +1342,51 @@ mod tests {
13421342 }
13431343 }
13441344}
1345+
1346+ // #[stable(feature = "array_try_from_vec", since = "1.48.0")]
1347+ impl < T , A : Allocator , const N : usize > TryFrom < Vec < T , A > > for [ T ; N ] {
1348+ type Error = Vec < T , A > ;
1349+
1350+ /// Gets the entire contents of the `Vec<T>` as an array,
1351+ /// if its size exactly matches that of the requested array.
1352+ ///
1353+ /// # Examples
1354+ ///
1355+ /// ```
1356+ /// assert_eq!(vec![1, 2, 3].try_into(), Ok([1, 2, 3]));
1357+ /// assert_eq!(<Vec<i32>>::new().try_into(), Ok([]));
1358+ /// ```
1359+ ///
1360+ /// If the length doesn't match, the input comes back in `Err`:
1361+ /// ```
1362+ /// let r: Result<[i32; 4], _> = (0..10).collect::<Vec<_>>().try_into();
1363+ /// assert_eq!(r, Err(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
1364+ /// ```
1365+ ///
1366+ /// If you're fine with just getting a prefix of the `Vec<T>`,
1367+ /// you can call [`.truncate(N)`](Vec::truncate) first.
1368+ /// ```
1369+ /// let mut v = String::from("hello world").into_bytes();
1370+ /// v.sort();
1371+ /// v.truncate(2);
1372+ /// let [a, b]: [_; 2] = v.try_into().unwrap();
1373+ /// assert_eq!(a, b' ');
1374+ /// assert_eq!(b, b'd');
1375+ /// ```
1376+ fn try_from ( mut vec : Vec < T , A > ) -> Result < [ T ; N ] , Vec < T , A > > {
1377+ if vec. len ( ) != N {
1378+ return Err ( vec) ;
1379+ }
1380+
1381+ // SAFETY: `.set_len(0)` is always sound.
1382+ unsafe { vec. dec_len ( vec. len ( ) ) } ;
1383+
1384+ // SAFETY: A `Vec`'s pointer is always aligned properly, and
1385+ // the alignment the array needs is the same as the items.
1386+ // We checked earlier that we have sufficient items.
1387+ // The items will not double-drop as the `set_len`
1388+ // tells the `Vec` not to also drop them.
1389+ let array = unsafe { ptr:: read ( vec. as_ptr ( ) as * const [ T ; N ] ) } ;
1390+ Ok ( array)
1391+ }
1392+ }
0 commit comments