@@ -1008,3 +1008,51 @@ where
10081008 }
10091009 }
10101010}
1011+
1012+ // #[stable(feature = "array_try_from_vec", since = "1.48.0")]
1013+ impl < T , A : Allocator , const N : usize > TryFrom < Vec < T , A > > for [ T ; N ] {
1014+ type Error = Vec < T , A > ;
1015+
1016+ /// Gets the entire contents of the `Vec<T>` as an array,
1017+ /// if its size exactly matches that of the requested array.
1018+ ///
1019+ /// # Examples
1020+ ///
1021+ /// ```
1022+ /// assert_eq!(vec![1, 2, 3].try_into(), Ok([1, 2, 3]));
1023+ /// assert_eq!(<Vec<i32>>::new().try_into(), Ok([]));
1024+ /// ```
1025+ ///
1026+ /// If the length doesn't match, the input comes back in `Err`:
1027+ /// ```
1028+ /// let r: Result<[i32; 4], _> = (0..10).collect::<Vec<_>>().try_into();
1029+ /// assert_eq!(r, Err(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
1030+ /// ```
1031+ ///
1032+ /// If you're fine with just getting a prefix of the `Vec<T>`,
1033+ /// you can call [`.truncate(N)`](Vec::truncate) first.
1034+ /// ```
1035+ /// let mut v = String::from("hello world").into_bytes();
1036+ /// v.sort();
1037+ /// v.truncate(2);
1038+ /// let [a, b]: [_; 2] = v.try_into().unwrap();
1039+ /// assert_eq!(a, b' ');
1040+ /// assert_eq!(b, b'd');
1041+ /// ```
1042+ fn try_from ( mut vec : Vec < T , A > ) -> Result < [ T ; N ] , Vec < T , A > > {
1043+ if vec. len ( ) != N {
1044+ return Err ( vec) ;
1045+ }
1046+
1047+ // SAFETY: `.set_len(0)` is always sound.
1048+ unsafe { vec. set_len ( 0 ) } ;
1049+
1050+ // SAFETY: A `Vec`'s pointer is always aligned properly, and
1051+ // the alignment the array needs is the same as the items.
1052+ // We checked earlier that we have sufficient items.
1053+ // The items will not double-drop as the `set_len`
1054+ // tells the `Vec` not to also drop them.
1055+ let array = unsafe { ptr:: read ( vec. as_ptr ( ) as * const [ T ; N ] ) } ;
1056+ Ok ( array)
1057+ }
1058+ }
0 commit comments