@@ -6,7 +6,7 @@ use core::{
66 fmt, hash,
77 iter:: FusedIterator ,
88 marker:: PhantomData ,
9- mem:: { self , ManuallyDrop , MaybeUninit } ,
9+ mem:: { ManuallyDrop , MaybeUninit } ,
1010 ops:: { self , Range , RangeBounds } ,
1111 ptr:: { self , NonNull } ,
1212 slice,
@@ -16,7 +16,7 @@ use core::{
1616use zeroize:: Zeroize ;
1717
1818use crate :: {
19- len_type:: { check_capacity_fits, LenType } ,
19+ len_type:: { check_capacity_fits, to_len_type , LenType } ,
2020 CapacityError ,
2121} ;
2222
@@ -355,7 +355,7 @@ impl<T, LenT: LenType, const N: usize> Vec<T, N, LenT> {
355355 ///
356356 /// If the length of the provided array is greater than the capacity of the
357357 /// vector a compile-time error will be produced.
358- pub fn from_array < const M : usize > ( src : [ T ; M ] ) -> Self {
358+ pub const fn from_array < const M : usize > ( src : [ T ; M ] ) -> Self {
359359 const {
360360 assert ! ( N >= M ) ;
361361 }
@@ -364,26 +364,24 @@ impl<T, LenT: LenType, const N: usize> Vec<T, N, LenT> {
364364 // any Drop code for T.
365365 let src = ManuallyDrop :: new ( src) ;
366366
367- if N == M {
368- Self {
369- phantom : PhantomData ,
370- len : LenT :: from_usize ( N ) ,
371- // NOTE(unsafe) ManuallyDrop<[T; M]> and [MaybeUninit<T>; N]
372- // have the same layout when N == M.
373- buffer : unsafe { mem:: transmute_copy ( & src) } ,
374- }
375- } else {
376- let mut v = Self :: new ( ) ;
367+ let len: LenT = to_len_type ( M ) ;
377368
378- for ( src_elem, dst_elem) in src. iter ( ) . zip ( v. buffer . buffer . iter_mut ( ) ) {
379- // NOTE(unsafe) src element is not going to drop as src itself
380- // is wrapped in a ManuallyDrop.
381- dst_elem. write ( unsafe { ptr:: read ( src_elem) } ) ;
382- }
369+ let mut v = Self :: new ( ) ;
383370
384- unsafe { v. set_len ( M ) } ;
385- v
386- }
371+ // MaybeUninit::deref is non-const, so we just cast to it's internal value.
372+ let src_ptr: * const T = ptr:: from_ref ( & src) . cast ( ) ;
373+
374+ // Cast from buffer's [MaybeUninit<T>] to [T].
375+ let dst_ptr: * mut T = v. buffer . buffer . as_mut_ptr ( ) . cast ( ) ;
376+
377+ // SAFETY: Move/copy data from src to v's internal buffer.
378+ // * Using src_ptr as `*const T` is safe since src's ManuallyDrop<[T; M]> is transparent.
379+ // * Using dst_ptr as `*mut T` is safe since v's [MaybeUninit<T>; N] is an array of
380+ // transparent types.
381+ unsafe { ptr:: copy_nonoverlapping ( src_ptr, dst_ptr, M ) } ;
382+ v. len = len;
383+
384+ v
387385 }
388386
389387 /// Returns the contents of the vector as an array of length `M` if the length
@@ -466,6 +464,8 @@ impl<T, LenT: LenType, S: VecStorage<T> + ?Sized> VecInner<T, LenT, S> {
466464 /// [`mem::forget`], for example), the vector may have lost and leaked
467465 /// elements arbitrarily, including elements outside the range.
468466 ///
467+ /// [`mem::forget`]: core::mem::forget
468+ ///
469469 /// # Examples
470470 ///
471471 /// ```
0 commit comments