@@ -11,7 +11,7 @@ use crate::convert::Infallible;
1111use crate :: error:: Error ;
1212use crate :: hash:: { self , Hash } ;
1313use crate :: intrinsics:: transmute_unchecked;
14- use crate :: iter:: { TrustedLen , UncheckedIterator , repeat_n} ;
14+ use crate :: iter:: { TrustedLen , repeat_n} ;
1515use crate :: marker:: Destruct ;
1616use crate :: mem:: { self , ManuallyDrop , MaybeUninit } ;
1717use crate :: ops:: {
@@ -52,7 +52,10 @@ pub use iter::IntoIter;
5252#[ must_use = "cloning is often expensive and is not expected to have side effects" ]
5353#[ stable( feature = "array_repeat" , since = "1.91.0" ) ]
5454pub fn repeat < T : Clone , const N : usize > ( val : T ) -> [ T ; N ] {
55- from_trusted_iterator ( repeat_n ( val, N ) )
55+ let mut iter = repeat_n ( val, N ) ;
56+ // SAFETY: Unless a panic occurs, from_fn will call the closure N times,
57+ // and repeat_n's next() will return Some for N times.
58+ from_fn ( move |_| unsafe { iter. next ( ) . unwrap_unchecked ( ) } )
5659}
5760
5861/// Creates an array where each element is produced by calling `f` with
@@ -464,7 +467,15 @@ trait SpecArrayClone: Clone {
464467impl < T : Clone > SpecArrayClone for T {
465468 #[ inline]
466469 default fn clone < const N : usize > ( array : & [ T ; N ] ) -> [ T ; N ] {
467- from_trusted_iterator ( array. iter ( ) . cloned ( ) )
470+ let mut ptr: * const T = array. as_ptr ( ) ;
471+ // SAFETY: Unless a panic occurs, from_fn will call the closure N times,
472+ // so our pointer arithmetic will be in bounds for the N-element array.
473+ // This works even for ZSTs, since in that case, add() is a no-op.
474+ from_fn ( move |_| unsafe {
475+ let old = ptr;
476+ ptr = ptr. add ( 1 ) ;
477+ ( & * old) . clone ( )
478+ } )
468479 }
469480}
470481
@@ -877,39 +888,6 @@ impl<T, const N: usize> [T; N] {
877888 }
878889}
879890
880- /// Populate an array from the first `N` elements of `iter`
881- ///
882- /// # Panics
883- ///
884- /// If the iterator doesn't actually have enough items.
885- ///
886- /// By depending on `TrustedLen`, however, we can do that check up-front (where
887- /// it easily optimizes away) so it doesn't impact the loop that fills the array.
888- #[ inline]
889- fn from_trusted_iterator < T , const N : usize > ( iter : impl UncheckedIterator < Item = T > ) -> [ T ; N ] {
890- try_from_trusted_iterator ( iter. map ( NeverShortCircuit ) ) . 0
891- }
892-
893- #[ inline]
894- fn try_from_trusted_iterator < T , R , const N : usize > (
895- iter : impl UncheckedIterator < Item = R > ,
896- ) -> ChangeOutputType < R , [ T ; N ] >
897- where
898- R : Try < Output = T > ,
899- R :: Residual : Residual < [ T ; N ] > ,
900- {
901- assert ! ( iter. size_hint( ) . 0 >= N ) ;
902- fn next < T > ( mut iter : impl UncheckedIterator < Item = T > ) -> impl FnMut ( usize ) -> T {
903- move |_| {
904- // SAFETY: We know that `from_fn` will call this at most N times,
905- // and we checked to ensure that we have at least that many items.
906- unsafe { iter. next_unchecked ( ) }
907- }
908- }
909-
910- try_from_fn ( next ( iter) )
911- }
912-
913891/// Version of [`try_from_fn`] using a passed-in slice in order to avoid
914892/// needing to monomorphize for every array length.
915893///
0 commit comments