@@ -2787,14 +2787,16 @@ impl<T> [T] {
27872787 where
27882788 F : FnMut ( & ' a T ) -> Ordering ,
27892789 {
2790+ if self . len ( ) == 0 {
2791+ return Err ( 0 ) ;
2792+ }
27902793 // INVARIANTS:
2791- // - 0 <= left <= left + size = right <= self.len()
2794+ // - 0 <= left <= left + size <= self.len()
27922795 // - f returns Less for everything in self[..left]
2793- // - f returns Greater for everything in self[right ..]
2796+ // - f returns Greater for everything in self[left + size ..]
27942797 let mut size = self . len ( ) ;
27952798 let mut left = 0 ;
2796- let mut right = size;
2797- while left < right {
2799+ while size > 1 {
27982800 let mid = left + size / 2 ;
27992801
28002802 // SAFETY: the while condition means `size` is strictly positive, so
@@ -2807,21 +2809,21 @@ impl<T> [T] {
28072809 // fewer branches and instructions than if/else or matching on
28082810 // cmp::Ordering.
28092811 // This is x86 asm for u8: https://rust.godbolt.org/z/698eYffTx.
2810- left = if cmp == Less { mid + 1 } else { left } ;
2811- right = if cmp == Greater { mid } else { right } ;
2812+
2813+ left = if cmp == Less { mid } else { left } ;
2814+ size = if cmp == Greater { size / 2 } else { size - size / 2 } ;
28122815 if cmp == Equal {
28132816 // SAFETY: same as the `get_unchecked` above
28142817 unsafe { hint:: assert_unchecked ( mid < self . len ( ) ) } ;
28152818 return Ok ( mid) ;
28162819 }
2817-
2818- size = right - left;
28192820 }
2820-
2821- // SAFETY: directly true from the overall invariant.
2822- // Note that this is `<=`, unlike the assume in the `Ok` path.
2823- unsafe { hint:: assert_unchecked ( left <= self . len ( ) ) } ;
2824- Err ( left)
2821+ // SAFETY: allowed per the invariants
2822+ let cmp = f ( unsafe { self . get_unchecked ( left) } ) ;
2823+ let res_idx = if cmp == Less { left + 1 } else { left } ;
2824+ // SAFETY: invariants guarantee that this is in bounds
2825+ unsafe { hint:: assert_unchecked ( res_idx <= self . len ( ) ) } ;
2826+ if cmp == Equal { Ok ( res_idx) } else { Err ( res_idx) }
28252827 }
28262828
28272829 /// Binary searches this slice with a key extraction function.
0 commit comments