@@ -2787,15 +2787,28 @@ impl<T> [T] {
2787
2787
where
2788
2788
F : FnMut ( & ' a T ) -> Ordering ,
2789
2789
{
2790
+ if T :: IS_ZST {
2791
+ let res = if self . len ( ) == 0 {
2792
+ Err ( 0 )
2793
+ } else {
2794
+ match f ( & self [ 0 ] ) {
2795
+ Less => Err ( self . len ( ) ) ,
2796
+ Equal => Ok ( 0 ) ,
2797
+ Greater => Err ( 0 ) ,
2798
+ }
2799
+ } ;
2800
+ return res;
2801
+ }
2790
2802
// INVARIANTS:
2791
- // - 0 <= left <= left + size = right <= self.len()
2803
+ // - 0 <= left <= right <= self.len()
2792
2804
// - f returns Less for everything in self[..left]
2793
2805
// - f returns Greater for everything in self[right..]
2794
- let mut size = self . len ( ) ;
2806
+ let mut right = self . len ( ) ;
2795
2807
let mut left = 0 ;
2796
- let mut right = size;
2797
2808
while left < right {
2798
- let mid = left + size / 2 ;
2809
+ // This is an okay way to compute the mean because left and right are
2810
+ // <= isize::MAX so the addition won't overflow
2811
+ let mid = ( left + right) / 2 ;
2799
2812
2800
2813
// SAFETY: the while condition means `size` is strictly positive, so
2801
2814
// `size/2 < size`. Thus `left + size/2 < left + size`, which
@@ -2807,19 +2820,16 @@ impl<T> [T] {
2807
2820
// fewer branches and instructions than if/else or matching on
2808
2821
// cmp::Ordering.
2809
2822
// This is x86 asm for u8: https://rust.godbolt.org/z/698eYffTx.
2823
+
2810
2824
left = if cmp == Less { mid + 1 } else { left } ;
2811
2825
right = if cmp == Greater { mid } else { right } ;
2812
2826
if cmp == Equal {
2813
2827
// SAFETY: same as the `get_unchecked` above
2814
2828
unsafe { hint:: assert_unchecked ( mid < self . len ( ) ) } ;
2815
2829
return Ok ( mid) ;
2816
2830
}
2817
-
2818
- size = right - left;
2819
2831
}
2820
-
2821
- // SAFETY: directly true from the overall invariant.
2822
- // Note that this is `<=`, unlike the assume in the `Ok` path.
2832
+ // SAFETY: yolo
2823
2833
unsafe { hint:: assert_unchecked ( left <= self . len ( ) ) } ;
2824
2834
Err ( left)
2825
2835
}
0 commit comments