@@ -11,7 +11,7 @@ use core::iter::{
1111 TrustedRandomAccessNoCoerce ,
1212} ;
1313use core:: marker:: PhantomData ;
14- use core:: mem:: { self , ManuallyDrop , MaybeUninit , SizedTypeProperties } ;
14+ use core:: mem:: { ManuallyDrop , MaybeUninit , SizedTypeProperties } ;
1515use core:: num:: NonZero ;
1616#[ cfg( not( no_global_oom_handling) ) ]
1717use core:: ops:: Deref ;
@@ -200,27 +200,23 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
200200
201201 #[ inline]
202202 fn next ( & mut self ) -> Option < T > {
203- if T :: IS_ZST {
204- if self . ptr . as_ptr ( ) == self . end as * mut _ {
205- None
206- } else {
207- // `ptr` has to stay where it is to remain aligned, so we reduce the length by 1 by
208- // reducing the `end`.
209- self . end = self . end . wrapping_byte_sub ( 1 ) ;
210-
211- // Make up a value of this ZST.
212- Some ( unsafe { mem:: zeroed ( ) } )
203+ let ptr = if T :: IS_ZST {
204+ if self . ptr . as_ptr ( ) == self . end as * mut T {
205+ return None ;
213206 }
207+ // `ptr` has to stay where it is to remain aligned, so we reduce the length by 1 by
208+ // reducing the `end`.
209+ self . end = self . end . wrapping_byte_sub ( 1 ) ;
210+ self . ptr
214211 } else {
215212 if self . ptr == non_null ! ( self . end, T ) {
216- None
217- } else {
218- let old = self . ptr ;
219- self . ptr = unsafe { old. add ( 1 ) } ;
220-
221- Some ( unsafe { ptr:: read ( old. as_ptr ( ) ) } )
213+ return None ;
222214 }
223- }
215+ let old = self . ptr ;
216+ self . ptr = unsafe { old. add ( 1 ) } ;
217+ old
218+ } ;
219+ Some ( unsafe { ptr. read ( ) } )
224220 }
225221
226222 #[ inline]
@@ -305,7 +301,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
305301 // Also note the implementation of `Self: TrustedRandomAccess` requires
306302 // that `T: Copy` so reading elements from the buffer doesn't invalidate
307303 // them for `Drop`.
308- unsafe { if T :: IS_ZST { mem :: zeroed ( ) } else { self . ptr . add ( i) . read ( ) } }
304+ unsafe { self . ptr . add ( i) . read ( ) }
309305 }
310306}
311307
@@ -314,23 +310,22 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
314310 #[ inline]
315311 fn next_back ( & mut self ) -> Option < T > {
316312 if T :: IS_ZST {
317- if self . end as * mut _ == self . ptr . as_ptr ( ) {
318- None
319- } else {
320- // See above for why 'ptr.offset' isn't used
321- self . end = self . end . wrapping_byte_sub ( 1 ) ;
322-
323- // Make up a value of this ZST.
324- Some ( unsafe { mem:: zeroed ( ) } )
313+ if self . ptr . as_ptr ( ) == self . end as * mut _ {
314+ return None ;
325315 }
316+ // See above for why 'ptr.offset' isn't used
317+ self . end = self . end . wrapping_byte_sub ( 1 ) ;
318+ // Note that even though this is next_back() we're reading from `self.ptr`, not
319+ // `self.end`. We track our length using the byte offset from `self.ptr` to `self.end`,
320+ // so the end pointer may not be suitably aligned for T.
321+ Some ( unsafe { ptr:: read ( self . ptr . as_ptr ( ) ) } )
326322 } else {
327- if non_null ! ( self . end, T ) == self . ptr {
328- None
329- } else {
330- let new_end = unsafe { non_null ! ( self . end, T ) . sub ( 1 ) } ;
331- * non_null ! ( mut self . end, T ) = new_end;
332-
333- Some ( unsafe { ptr:: read ( new_end. as_ptr ( ) ) } )
323+ if self . ptr == non_null ! ( self . end, T ) {
324+ return None ;
325+ }
326+ unsafe {
327+ self . end = self . end . sub ( 1 ) ;
328+ Some ( ptr:: read ( self . end ) )
334329 }
335330 }
336331 }
0 commit comments