@@ -1399,3 +1399,51 @@ mod tests {
13991399 }
14001400 }
14011401}
1402+
1403+ // #[stable(feature = "array_try_from_vec", since = "1.48.0")]
1404+ impl < T , A : Allocator , const N : usize > TryFrom < Vec < T , A > > for [ T ; N ] {
1405+ type Error = Vec < T , A > ;
1406+
1407+ /// Gets the entire contents of the `Vec<T>` as an array,
1408+ /// if its size exactly matches that of the requested array.
1409+ ///
1410+ /// # Examples
1411+ ///
1412+ /// ```
1413+ /// assert_eq!(vec![1, 2, 3].try_into(), Ok([1, 2, 3]));
1414+ /// assert_eq!(<Vec<i32>>::new().try_into(), Ok([]));
1415+ /// ```
1416+ ///
1417+ /// If the length doesn't match, the input comes back in `Err`:
1418+ /// ```
1419+ /// let r: Result<[i32; 4], _> = (0..10).collect::<Vec<_>>().try_into();
1420+ /// assert_eq!(r, Err(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
1421+ /// ```
1422+ ///
1423+ /// If you're fine with just getting a prefix of the `Vec<T>`,
1424+ /// you can call [`.truncate(N)`](Vec::truncate) first.
1425+ /// ```
1426+ /// let mut v = String::from("hello world").into_bytes();
1427+ /// v.sort();
1428+ /// v.truncate(2);
1429+ /// let [a, b]: [_; 2] = v.try_into().unwrap();
1430+ /// assert_eq!(a, b' ');
1431+ /// assert_eq!(b, b'd');
1432+ /// ```
1433+ fn try_from ( mut vec : Vec < T , A > ) -> Result < [ T ; N ] , Vec < T , A > > {
1434+ if vec. len ( ) != N {
1435+ return Err ( vec) ;
1436+ }
1437+
1438+ // SAFETY: `.set_len(0)` is always sound.
1439+ unsafe { vec. dec_len ( vec. len ( ) ) } ;
1440+
1441+ // SAFETY: A `Vec`'s pointer is always aligned properly, and
1442+ // the alignment the array needs is the same as the items.
1443+ // We checked earlier that we have sufficient items.
1444+ // The items will not double-drop as the `set_len`
1445+ // tells the `Vec` not to also drop them.
1446+ let array = unsafe { ptr:: read ( vec. as_ptr ( ) as * const [ T ; N ] ) } ;
1447+ Ok ( array)
1448+ }
1449+ }
0 commit comments