@@ -2788,13 +2788,12 @@ impl<T> [T] {
2788
2788
F : FnMut ( & ' a T ) -> Ordering ,
2789
2789
{
2790
2790
// INVARIANTS:
2791
- // - 0 <= left <= left + size = right <= self.len()
2791
+ // - 0 <= left <= left + size <= self.len()
2792
2792
// - f returns Less for everything in self[..left]
2793
- // - f returns Greater for everything in self[right ..]
2793
+ // - f returns Greater for everything in self[left + size ..]
2794
2794
let mut size = self . len ( ) ;
2795
2795
let mut left = 0 ;
2796
- let mut right = size;
2797
- while left < right {
2796
+ while size > 1 {
2798
2797
let mid = left + size / 2 ;
2799
2798
2800
2799
// SAFETY: the while condition means `size` is strictly positive, so
@@ -2807,21 +2806,24 @@ impl<T> [T] {
2807
2806
// fewer branches and instructions than if/else or matching on
2808
2807
// cmp::Ordering.
2809
2808
// 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 } ;
2809
+
2810
+ left = if cmp == Less { mid } else { left } ;
2811
+ size = if cmp == Greater { size / 2 } else { size - size / 2 } ;
2812
2812
if cmp == Equal {
2813
2813
// SAFETY: same as the `get_unchecked` above
2814
2814
unsafe { hint:: assert_unchecked ( mid < self . len ( ) ) } ;
2815
2815
return Ok ( mid) ;
2816
2816
}
2817
-
2818
- size = right - left;
2819
2817
}
2820
2818
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)
2819
+ if size == 0 {
2820
+ Err ( left)
2821
+ } else {
2822
+ // SAFETY: allowed per the invariants
2823
+ let cmp = f ( unsafe { self . get_unchecked ( left) } ) ;
2824
+ let res_idx = if cmp == Less { left + 1 } else { left } ;
2825
+ if cmp == Equal { Ok ( res_idx) } else { Err ( res_idx) }
2826
+ }
2825
2827
}
2826
2828
2827
2829
/// Binary searches this slice with a key extraction function.
0 commit comments