@@ -1289,3 +1289,51 @@ mod tests {
12891289 }
12901290 }
12911291}
1292+
1293+ // #[stable(feature = "array_try_from_vec", since = "1.48.0")]
1294+ impl < T , A : Allocator , const N : usize > TryFrom < Vec < T , A > > for [ T ; N ] {
1295+ type Error = Vec < T , A > ;
1296+
1297+ /// Gets the entire contents of the `Vec<T>` as an array,
1298+ /// if its size exactly matches that of the requested array.
1299+ ///
1300+ /// # Examples
1301+ ///
1302+ /// ```
1303+ /// assert_eq!(vec![1, 2, 3].try_into(), Ok([1, 2, 3]));
1304+ /// assert_eq!(<Vec<i32>>::new().try_into(), Ok([]));
1305+ /// ```
1306+ ///
1307+ /// If the length doesn't match, the input comes back in `Err`:
1308+ /// ```
1309+ /// let r: Result<[i32; 4], _> = (0..10).collect::<Vec<_>>().try_into();
1310+ /// assert_eq!(r, Err(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
1311+ /// ```
1312+ ///
1313+ /// If you're fine with just getting a prefix of the `Vec<T>`,
1314+ /// you can call [`.truncate(N)`](Vec::truncate) first.
1315+ /// ```
1316+ /// let mut v = String::from("hello world").into_bytes();
1317+ /// v.sort();
1318+ /// v.truncate(2);
1319+ /// let [a, b]: [_; 2] = v.try_into().unwrap();
1320+ /// assert_eq!(a, b' ');
1321+ /// assert_eq!(b, b'd');
1322+ /// ```
1323+ fn try_from ( mut vec : Vec < T , A > ) -> Result < [ T ; N ] , Vec < T , A > > {
1324+ if vec. len ( ) != N {
1325+ return Err ( vec) ;
1326+ }
1327+
1328+ // SAFETY: `.set_len(0)` is always sound.
1329+ unsafe { vec. dec_len ( vec. len ( ) ) } ;
1330+
1331+ // SAFETY: A `Vec`'s pointer is always aligned properly, and
1332+ // the alignment the array needs is the same as the items.
1333+ // We checked earlier that we have sufficient items.
1334+ // The items will not double-drop as the `set_len`
1335+ // tells the `Vec` not to also drop them.
1336+ let array = unsafe { ptr:: read ( vec. as_ptr ( ) as * const [ T ; N ] ) } ;
1337+ Ok ( array)
1338+ }
1339+ }
0 commit comments