@@ -780,24 +780,27 @@ where
780
780
}
781
781
782
782
/// Pulls `N` items from `iter` and returns them as an array. If the iterator
783
- /// yields fewer than `N` items, `None ` is returned and all already yielded
784
- /// items are dropped .
783
+ /// yields fewer than `N` items, `Err ` is returned containing an iterator over
784
+ /// the already yielded items .
785
785
///
786
786
/// Since the iterator is passed as a mutable reference and this function calls
787
787
/// `next` at most `N` times, the iterator can still be used afterwards to
788
788
/// retrieve the remaining items.
789
789
///
790
790
/// If `iter.next()` panicks, all items already yielded by the iterator are
791
791
/// dropped.
792
- fn try_collect_into_array < I , T , R , const N : usize > ( iter : & mut I ) -> Option < R :: TryType >
792
+ #[ inline]
793
+ fn try_collect_into_array < I , T , R , const N : usize > (
794
+ iter : & mut I ,
795
+ ) -> Result < R :: TryType , IntoIter < T , N > >
793
796
where
794
797
I : Iterator ,
795
798
I :: Item : Try < Output = T , Residual = R > ,
796
799
R : Residual < [ T ; N ] > ,
797
800
{
798
801
if N == 0 {
799
802
// SAFETY: An empty array is always inhabited and has no validity invariants.
800
- return unsafe { Some ( Try :: from_output ( mem:: zeroed ( ) ) ) } ;
803
+ return Ok ( Try :: from_output ( unsafe { mem:: zeroed ( ) } ) ) ;
801
804
}
802
805
803
806
struct Guard < ' a , T , const N : usize > {
@@ -821,35 +824,49 @@ where
821
824
let mut array = MaybeUninit :: uninit_array :: < N > ( ) ;
822
825
let mut guard = Guard { array_mut : & mut array, initialized : 0 } ;
823
826
824
- while let Some ( item_rslt) = iter. next ( ) {
825
- let item = match item_rslt. branch ( ) {
826
- ControlFlow :: Break ( r) => {
827
- return Some ( FromResidual :: from_residual ( r) ) ;
827
+ for _ in 0 ..N {
828
+ match iter. next ( ) {
829
+ Some ( item_rslt) => {
830
+ let item = match item_rslt. branch ( ) {
831
+ ControlFlow :: Break ( r) => {
832
+ return Ok ( FromResidual :: from_residual ( r) ) ;
833
+ }
834
+ ControlFlow :: Continue ( elem) => elem,
835
+ } ;
836
+
837
+ // SAFETY: `guard.initialized` starts at 0, is increased by one in the
838
+ // loop and the loop is aborted once it reaches N (which is
839
+ // `array.len()`).
840
+ unsafe {
841
+ guard. array_mut . get_unchecked_mut ( guard. initialized ) . write ( item) ;
842
+ }
843
+ guard. initialized += 1 ;
844
+ }
845
+ None => {
846
+ let alive = 0 ..guard. initialized ;
847
+ mem:: forget ( guard) ;
848
+ // SAFETY: `array` was initialized with exactly `initialized`
849
+ // number of elements.
850
+ return Err ( unsafe { IntoIter :: new_unchecked ( array, alive) } ) ;
828
851
}
829
- ControlFlow :: Continue ( elem) => elem,
830
- } ;
831
-
832
- // SAFETY: `guard.initialized` starts at 0, is increased by one in the
833
- // loop and the loop is aborted once it reaches N (which is
834
- // `array.len()`).
835
- unsafe {
836
- guard. array_mut . get_unchecked_mut ( guard. initialized ) . write ( item) ;
837
- }
838
- guard. initialized += 1 ;
839
-
840
- // Check if the whole array was initialized.
841
- if guard. initialized == N {
842
- mem:: forget ( guard) ;
843
-
844
- // SAFETY: the condition above asserts that all elements are
845
- // initialized.
846
- let out = unsafe { MaybeUninit :: array_assume_init ( array) } ;
847
- return Some ( Try :: from_output ( out) ) ;
848
852
}
849
853
}
850
854
851
- // This is only reached if the iterator is exhausted before
852
- // `guard.initialized` reaches `N`. Also note that `guard` is dropped here,
853
- // dropping all already initialized elements.
854
- None
855
+ mem:: forget ( guard) ;
856
+ // SAFETY: All elements of the array were populated in the loop above.
857
+ let output = unsafe { MaybeUninit :: array_assume_init ( array) } ;
858
+ Ok ( Try :: from_output ( output) )
859
+ }
860
+
861
+ /// Returns the next chunk of `N` items from the iterator or errors with an
862
+ /// iterator over the remainder. Used for `Iterator::next_chunk`.
863
+ #[ inline]
864
+ pub ( crate ) fn iter_next_chunk < I , const N : usize > (
865
+ iter : & mut I ,
866
+ ) -> Result < [ I :: Item ; N ] , IntoIter < I :: Item , N > >
867
+ where
868
+ I : Iterator ,
869
+ {
870
+ let mut map = iter. map ( NeverShortCircuit ) ;
871
+ try_collect_into_array ( & mut map) . map ( |NeverShortCircuit ( arr) | arr)
855
872
}
0 commit comments