@@ -1622,6 +1622,22 @@ impl<T, const N: usize> From<[T; N]> for Box<[T]> {
16221622 }
16231623}
16241624
1625+ /// Casts a boxed slice to a boxed array.
1626+ ///
1627+ /// # Safety
1628+ ///
1629+ /// `boxed_slice.len()` must be exactly `N`.
1630+ unsafe fn boxed_slice_as_array_unchecked < T , A : Allocator , const N : usize > (
1631+ boxed_slice : Box < [ T ] , A > ,
1632+ ) -> Box < [ T ; N ] , A > {
1633+ debug_assert_eq ! ( boxed_slice. len( ) , N ) ;
1634+
1635+ let ( ptr, alloc) = Box :: into_raw_with_allocator ( boxed_slice) ;
1636+ // SAFETY: Pointer and allocator came from an existing box,
1637+ // and our safety condition requires that the length is exactly `N`
1638+ unsafe { Box :: from_raw_in ( ptr as * mut [ T ; N ] , alloc) }
1639+ }
1640+
16251641#[ stable( feature = "boxed_slice_try_from" , since = "1.43.0" ) ]
16261642impl < T , const N : usize > TryFrom < Box < [ T ] > > for Box < [ T ; N ] > {
16271643 type Error = Box < [ T ] > ;
@@ -1637,13 +1653,46 @@ impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> {
16371653 /// `boxed_slice.len()` does not equal `N`.
16381654 fn try_from ( boxed_slice : Box < [ T ] > ) -> Result < Self , Self :: Error > {
16391655 if boxed_slice. len ( ) == N {
1640- Ok ( unsafe { Box :: from_raw ( Box :: into_raw ( boxed_slice) as * mut [ T ; N ] ) } )
1656+ Ok ( unsafe { boxed_slice_as_array_unchecked ( boxed_slice) } )
16411657 } else {
16421658 Err ( boxed_slice)
16431659 }
16441660 }
16451661}
16461662
1663+ #[ cfg( not( no_global_oom_handling) ) ]
1664+ #[ stable( feature = "boxed_array_try_from_vec" , since = "CURRENT_RUSTC_VERSION" ) ]
1665+ impl < T , const N : usize > TryFrom < Vec < T > > for Box < [ T ; N ] > {
1666+ type Error = Vec < T > ;
1667+
1668+ /// Attempts to convert a `Vec<T>` into a `Box<[T; N]>`.
1669+ ///
1670+ /// Like [`Vec::into_boxed_slice`], this is in-place if `vec.capacity() == N`,
1671+ /// but will require a reallocation otherwise.
1672+ ///
1673+ /// # Errors
1674+ ///
1675+ /// Returns the original `Vec<T>` in the `Err` variant if
1676+ /// `boxed_slice.len()` does not equal `N`.
1677+ ///
1678+ /// # Examples
1679+ ///
1680+ /// This can be used with [`vec!`] to create an array on the heap:
1681+ ///
1682+ /// ```
1683+ /// let state: Box<[f32; 100]> = vec![1.0; 100].try_into().unwrap();
1684+ /// assert_eq!(state.len(), 100);
1685+ /// ```
1686+ fn try_from ( vec : Vec < T > ) -> Result < Self , Self :: Error > {
1687+ if vec. len ( ) == N {
1688+ let boxed_slice = vec. into_boxed_slice ( ) ;
1689+ Ok ( unsafe { boxed_slice_as_array_unchecked ( boxed_slice) } )
1690+ } else {
1691+ Err ( vec)
1692+ }
1693+ }
1694+ }
1695+
16471696impl < A : Allocator > Box < dyn Any , A > {
16481697 /// Attempt to downcast the box to a concrete type.
16491698 ///
0 commit comments