@@ -3179,6 +3179,7 @@ macro_rules! is_empty {
31793179 $self. ptr. as_ptr( ) as * const T == $self. end
31803180 } ;
31813181}
3182+
31823183// To get rid of some bounds checks (see `position`), we compute the length in a somewhat
31833184// unexpected way. (Tested by `codegen/slice-position-bounds-check`.)
31843185macro_rules! len {
@@ -3347,40 +3348,127 @@ macro_rules! iterator {
33473348 self . next_back( )
33483349 }
33493350
3351+ // We override the default implementation, which uses `try_fold`,
3352+ // because this simple implementation generates less LLVM IR and is
3353+ // faster to compile.
3354+ #[ inline]
3355+ fn for_each<F >( mut self , mut f: F )
3356+ where
3357+ Self : Sized ,
3358+ F : FnMut ( Self :: Item ) ,
3359+ {
3360+ while let Some ( x) = self . next( ) {
3361+ f( x) ;
3362+ }
3363+ }
3364+
3365+ // We override the default implementation, which uses `try_fold`,
3366+ // because this simple implementation generates less LLVM IR and is
3367+ // faster to compile.
3368+ #[ inline]
3369+ fn all<F >( & mut self , mut f: F ) -> bool
3370+ where
3371+ Self : Sized ,
3372+ F : FnMut ( Self :: Item ) -> bool ,
3373+ {
3374+ while let Some ( x) = self . next( ) {
3375+ if !f( x) {
3376+ return false ;
3377+ }
3378+ }
3379+ true
3380+ }
3381+
3382+ // We override the default implementation, which uses `try_fold`,
3383+ // because this simple implementation generates less LLVM IR and is
3384+ // faster to compile.
3385+ #[ inline]
3386+ fn any<F >( & mut self , mut f: F ) -> bool
3387+ where
3388+ Self : Sized ,
3389+ F : FnMut ( Self :: Item ) -> bool ,
3390+ {
3391+ while let Some ( x) = self . next( ) {
3392+ if f( x) {
3393+ return true ;
3394+ }
3395+ }
3396+ false
3397+ }
3398+
3399+ // We override the default implementation, which uses `try_fold`,
3400+ // because this simple implementation generates less LLVM IR and is
3401+ // faster to compile.
3402+ #[ inline]
3403+ fn find<P >( & mut self , mut predicate: P ) -> Option <Self :: Item >
3404+ where
3405+ Self : Sized ,
3406+ P : FnMut ( & Self :: Item ) -> bool ,
3407+ {
3408+ while let Some ( x) = self . next( ) {
3409+ if predicate( & x) {
3410+ return Some ( x) ;
3411+ }
3412+ }
3413+ None
3414+ }
3415+
3416+ // We override the default implementation, which uses `try_fold`,
3417+ // because this simple implementation generates less LLVM IR and is
3418+ // faster to compile.
3419+ #[ inline]
3420+ fn find_map<B , F >( & mut self , mut f: F ) -> Option <B >
3421+ where
3422+ Self : Sized ,
3423+ F : FnMut ( Self :: Item ) -> Option <B >,
3424+ {
3425+ while let Some ( x) = self . next( ) {
3426+ if let Some ( y) = f( x) {
3427+ return Some ( y) ;
3428+ }
3429+ }
3430+ None
3431+ }
3432+
3433+ // We override the default implementation, which uses `try_fold`,
3434+ // because this simple implementation generates less LLVM IR and is
3435+ // faster to compile. Also, the `assume` avoids a bounds check.
33503436 #[ inline]
33513437 #[ rustc_inherit_overflow_checks]
33523438 fn position<P >( & mut self , mut predicate: P ) -> Option <usize > where
33533439 Self : Sized ,
33543440 P : FnMut ( Self :: Item ) -> bool ,
33553441 {
3356- // The addition might panic on overflow.
33573442 let n = len!( self ) ;
3358- self . try_fold( 0 , move |i, x| {
3359- if predicate( x) { Err ( i) }
3360- else { Ok ( i + 1 ) }
3361- } ) . err( )
3362- . map( |i| {
3443+ let mut i = 0 ;
3444+ while let Some ( x) = self . next( ) {
3445+ if predicate( x) {
33633446 unsafe { assume( i < n) } ;
3364- i
3365- } )
3447+ return Some ( i) ;
3448+ }
3449+ i += 1 ;
3450+ }
3451+ None
33663452 }
33673453
3454+ // We override the default implementation, which uses `try_fold`,
3455+ // because this simple implementation generates less LLVM IR and is
3456+ // faster to compile. Also, the `assume` avoids a bounds check.
33683457 #[ inline]
33693458 fn rposition<P >( & mut self , mut predicate: P ) -> Option <usize > where
33703459 P : FnMut ( Self :: Item ) -> bool ,
33713460 Self : Sized + ExactSizeIterator + DoubleEndedIterator
33723461 {
3373- // No need for an overflow check here, because `ExactSizeIterator`
33743462 let n = len!( self ) ;
3375- self . try_rfold( n, move |i, x| {
3376- let i = i - 1 ;
3377- if predicate( x) { Err ( i) }
3378- else { Ok ( i) }
3379- } ) . err( )
3380- . map( |i| {
3463+ let mut i = n;
3464+ while let Some ( x) = self . next_back( ) {
3465+ i -= 1 ;
3466+ if predicate( x) {
33813467 unsafe { assume( i < n) } ;
3382- i
3383- } )
3468+ return Some ( i) ;
3469+ }
3470+ }
3471+ None
33843472 }
33853473
33863474 $( $extra) *
0 commit comments