@@ -1622,6 +1622,22 @@ impl<T, const N: usize> From<[T; N]> for Box<[T]> {
1622
1622
}
1623
1623
}
1624
1624
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
+
1625
1641
#[ stable( feature = "boxed_slice_try_from" , since = "1.43.0" ) ]
1626
1642
impl < T , const N : usize > TryFrom < Box < [ T ] > > for Box < [ T ; N ] > {
1627
1643
type Error = Box < [ T ] > ;
@@ -1637,13 +1653,46 @@ impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> {
1637
1653
/// `boxed_slice.len()` does not equal `N`.
1638
1654
fn try_from ( boxed_slice : Box < [ T ] > ) -> Result < Self , Self :: Error > {
1639
1655
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) } )
1641
1657
} else {
1642
1658
Err ( boxed_slice)
1643
1659
}
1644
1660
}
1645
1661
}
1646
1662
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
+
1647
1696
impl < A : Allocator > Box < dyn Any , A > {
1648
1697
/// Attempt to downcast the box to a concrete type.
1649
1698
///
0 commit comments