@@ -2337,18 +2337,25 @@ impl<'a, T> IntoIterator for &'a mut [T] {
23372337 }
23382338}
23392339
2340+ // Macro helper functions
2341+ #[ inline( always) ]
2342+ fn size_from_ptr < T > ( _: * const T ) -> usize {
2343+ mem:: size_of :: < T > ( )
2344+ }
2345+
23402346// Inlining is_empty and len makes a huge performance difference
23412347macro_rules! is_empty {
23422348 // The way we encode the length of a ZST iterator, this works both for ZST
23432349 // and non-ZST.
2344- ( $self: expr ) => { $self. ptr == $self. end}
2350+ ( $self: ident ) => { $self. ptr == $self. end}
23452351}
23462352macro_rules! len {
2347- ( $T: ty, $self: expr) => { {
2348- if mem:: size_of:: <$T>( ) == 0 {
2349- ( $self. end as usize ) . wrapping_sub( $self. ptr as usize )
2353+ ( $self: ident) => { {
2354+ let start = $self. ptr;
2355+ if size_from_ptr( start) == 0 {
2356+ ( $self. end as usize ) . wrapping_sub( start as usize )
23502357 } else {
2351- $self. end. offset_from( $self . ptr ) as usize
2358+ $self. end. offset_from( start ) as usize
23522359 }
23532360 } }
23542361}
@@ -2360,7 +2367,7 @@ macro_rules! iterator {
23602367 // Helper function for creating a slice from the iterator.
23612368 #[ inline( always) ]
23622369 fn make_slice( & self ) -> & ' a [ T ] {
2363- unsafe { from_raw_parts( self . ptr, len!( T , self ) ) }
2370+ unsafe { from_raw_parts( self . ptr, len!( self ) ) }
23642371 }
23652372
23662373 // Helper function for moving the start of the iterator forwards by `offset` elements,
@@ -2398,7 +2405,7 @@ macro_rules! iterator {
23982405 impl <' a, T > ExactSizeIterator for $name<' a, T > {
23992406 #[ inline( always) ]
24002407 fn len( & self ) -> usize {
2401- unsafe { len!( T , self ) }
2408+ unsafe { len!( self ) }
24022409 }
24032410
24042411 #[ inline( always) ]
@@ -2429,7 +2436,7 @@ macro_rules! iterator {
24292436
24302437 #[ inline]
24312438 fn size_hint( & self ) -> ( usize , Option <usize >) {
2432- let exact = unsafe { len!( T , self ) } ;
2439+ let exact = unsafe { len!( self ) } ;
24332440 ( exact, Some ( exact) )
24342441 }
24352442
@@ -2440,7 +2447,7 @@ macro_rules! iterator {
24402447
24412448 #[ inline]
24422449 fn nth( & mut self , n: usize ) -> Option <$elem> {
2443- if n >= unsafe { len!( T , self ) } {
2450+ if n >= unsafe { len!( self ) } {
24442451 // This iterator is now empty.
24452452 if mem:: size_of:: <T >( ) == 0 {
24462453 // We have to do it this way as `ptr` may never be 0, but `end`
@@ -2471,7 +2478,7 @@ macro_rules! iterator {
24712478 // manual unrolling is needed when there are conditional exits from the loop
24722479 let mut accum = init;
24732480 unsafe {
2474- while len!( T , self ) >= 4 {
2481+ while len!( self ) >= 4 {
24752482 accum = f( accum, & $( $mut_ ) * * self . post_inc_start( 1 ) ) ?;
24762483 accum = f( accum, & $( $mut_ ) * * self . post_inc_start( 1 ) ) ?;
24772484 accum = f( accum, & $( $mut_ ) * * self . post_inc_start( 1 ) ) ?;
@@ -2562,7 +2569,7 @@ macro_rules! iterator {
25622569 // manual unrolling is needed when there are conditional exits from the loop
25632570 let mut accum = init;
25642571 unsafe {
2565- while len!( T , self ) >= 4 {
2572+ while len!( self ) >= 4 {
25662573 accum = f( accum, & $( $mut_ ) * * self . pre_dec_end( 1 ) ) ?;
25672574 accum = f( accum, & $( $mut_ ) * * self . pre_dec_end( 1 ) ) ?;
25682575 accum = f( accum, & $( $mut_ ) * * self . pre_dec_end( 1 ) ) ?;
@@ -2769,7 +2776,7 @@ impl<'a, T> IterMut<'a, T> {
27692776 /// ```
27702777 #[ stable( feature = "iter_to_slice" , since = "1.4.0" ) ]
27712778 pub fn into_slice ( self ) -> & ' a mut [ T ] {
2772- unsafe { from_raw_parts_mut ( self . ptr , len ! ( T , self ) ) }
2779+ unsafe { from_raw_parts_mut ( self . ptr , len ! ( self ) ) }
27732780 }
27742781}
27752782
0 commit comments