@@ -3,7 +3,7 @@ use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedF
33use  crate :: num:: NonZero ; 
44use  crate :: ops:: Try ; 
55use  core:: array; 
6- use  core:: mem:: { ManuallyDrop ,   MaybeUninit } ; 
6+ use  core:: mem:: MaybeUninit ; 
77use  core:: ops:: ControlFlow ; 
88
99/// An iterator that filters the elements of `iter` with `predicate`. 
@@ -27,6 +27,41 @@ impl<I, P> Filter<I, P> {
2727    } 
2828} 
2929
30+ impl < I ,  P >  Filter < I ,  P > 
31+ where 
32+     I :  Iterator , 
33+     P :  FnMut ( & I :: Item )  -> bool , 
34+ { 
35+     #[ inline]  
36+     fn  next_chunk_dropless < const  N :  usize > ( 
37+         & mut  self , 
38+     )  -> Result < [ I :: Item ;  N ] ,  array:: IntoIter < I :: Item ,  N > >  { 
39+         let  mut  array:  [ MaybeUninit < I :: Item > ;  N ]  = [ const  {  MaybeUninit :: uninit ( )  } ;  N ] ; 
40+         let  mut  initialized = 0 ; 
41+ 
42+         let  result = self . iter . try_for_each ( |element| { 
43+             let  idx = initialized; 
44+             initialized = idx + ( self . predicate ) ( & element)  as  usize ; 
45+ 
46+             // SAFETY: Loop conditions ensure the index is in bounds. 
47+             unsafe  {  array. get_unchecked_mut ( idx)  } . write ( element) ; 
48+ 
49+             if  initialized < N  {  ControlFlow :: Continue ( ( ) )  }  else  {  ControlFlow :: Break ( ( ) )  } 
50+         } ) ; 
51+ 
52+         match  result { 
53+             ControlFlow :: Break ( ( ) )  => { 
54+                 // SAFETY: The loop above is only explicitly broken when the array has been fully initialized 
55+                 Ok ( unsafe  {  MaybeUninit :: array_assume_init ( array)  } ) 
56+             } 
57+             ControlFlow :: Continue ( ( ) )  => { 
58+                 // SAFETY: The range is in bounds since the loop breaks when reaching N elements. 
59+                 Err ( unsafe  {  array:: IntoIter :: new_unchecked ( array,  0 ..initialized)  } ) 
60+             } 
61+         } 
62+     } 
63+ } 
64+ 
3065#[ stable( feature = "core_impl_debug" ,  since = "1.9.0" ) ]  
3166impl < I :  fmt:: Debug ,  P >  fmt:: Debug  for  Filter < I ,  P >  { 
3267    fn  fmt ( & self ,  f :  & mut  fmt:: Formatter < ' _ > )  -> fmt:: Result  { 
@@ -64,52 +99,15 @@ where
6499    fn  next_chunk < const  N :  usize > ( 
65100        & mut  self , 
66101    )  -> Result < [ Self :: Item ;  N ] ,  array:: IntoIter < Self :: Item ,  N > >  { 
67-         let  mut  array:  [ MaybeUninit < Self :: Item > ;  N ]  = [ const  {  MaybeUninit :: uninit ( )  } ;  N ] ; 
68- 
69-         struct  Guard < ' a ,  T >  { 
70-             array :  & ' a  mut  [ MaybeUninit < T > ] , 
71-             initialized :  usize , 
72-         } 
73- 
74-         impl < T >  Drop  for  Guard < ' _ ,  T >  { 
75-             #[ inline]  
76-             fn  drop ( & mut  self )  { 
77-                 if  const  {  crate :: mem:: needs_drop :: < T > ( )  }  { 
78-                     // SAFETY: self.initialized is always <= N, which also is the length of the array. 
79-                     unsafe  { 
80-                         core:: ptr:: drop_in_place ( MaybeUninit :: slice_assume_init_mut ( 
81-                             self . array . get_unchecked_mut ( ..self . initialized ) , 
82-                         ) ) ; 
83-                     } 
84-                 } 
102+         let  fun = const  { 
103+             if  crate :: mem:: needs_drop :: < I :: Item > ( )  { 
104+                 array:: iter_next_chunk :: < I :: Item ,  N > 
105+             }  else  { 
106+                 Self :: next_chunk_dropless :: < N > 
85107            } 
86-         } 
87- 
88-         let  mut  guard = Guard  {  array :  & mut  array,  initialized :  0  } ; 
89- 
90-         let  result = self . iter . try_for_each ( |element| { 
91-             let  idx = guard. initialized ; 
92-             guard. initialized  = idx + ( self . predicate ) ( & element)  as  usize ; 
93- 
94-             // SAFETY: Loop conditions ensure the index is in bounds. 
95-             unsafe  {  guard. array . get_unchecked_mut ( idx)  } . write ( element) ; 
96- 
97-             if  guard. initialized  < N  {  ControlFlow :: Continue ( ( ) )  }  else  {  ControlFlow :: Break ( ( ) )  } 
98-         } ) ; 
108+         } ; 
99109
100-         let  guard = ManuallyDrop :: new ( guard) ; 
101- 
102-         match  result { 
103-             ControlFlow :: Break ( ( ) )  => { 
104-                 // SAFETY: The loop above is only explicitly broken when the array has been fully initialized 
105-                 Ok ( unsafe  {  MaybeUninit :: array_assume_init ( array)  } ) 
106-             } 
107-             ControlFlow :: Continue ( ( ) )  => { 
108-                 let  initialized = guard. initialized ; 
109-                 // SAFETY: The range is in bounds since the loop breaks when reaching N elements. 
110-                 Err ( unsafe  {  array:: IntoIter :: new_unchecked ( array,  0 ..initialized)  } ) 
111-             } 
112-         } 
110+         fun ( self ) 
113111    } 
114112
115113    #[ inline]  
0 commit comments