core: use compare_bytes
for more slice element types · patricklam/verify-rust-std@b927541 (original) (raw)
`@@ -3,7 +3,8 @@
`
3
3
`use super::{from_raw_parts, memchr};
`
4
4
`use crate::cmp::{self, BytewiseEq, Ordering};
`
5
5
`use crate::intrinsics::compare_bytes;
`
6
``
`-
use crate::mem;
`
``
6
`+
use crate::num::NonZero;
`
``
7
`+
use crate::{ascii, mem};
`
7
8
``
8
9
`#[stable(feature = "rust1", since = "1.0.0")]
`
9
10
`impl<T, U> PartialEq<[U]> for [T]
`
`@@ -182,19 +183,31 @@ impl<A: Ord> SliceOrd for A {
`
182
183
`}
`
183
184
`}
`
184
185
``
``
186
`+
// The type should be treated as an unsigned byte for comparisons.
`
``
187
`+
#[rustc_specialization_trait]
`
``
188
`+
unsafe trait UnsignedByte {}
`
``
189
+
``
190
`+
unsafe impl UnsignedByte for bool {}
`
``
191
`+
unsafe impl UnsignedByte for u8 {}
`
``
192
`+
unsafe impl UnsignedByte for NonZero {}
`
``
193
`+
unsafe impl UnsignedByte for Option<NonZero> {}
`
``
194
`+
unsafe impl UnsignedByte for ascii::Char {}
`
``
195
+
185
196
`` // compare_bytes
compares a sequence of unsigned bytes lexicographically.
``
186
``
`-
// this matches the order we want for [u8], but no others (not even [i8]).
`
187
``
`-
impl SliceOrd for u8 {
`
``
197
`+
impl<A: Ord + UnsignedByte> SliceOrd for A {
`
188
198
`#[inline]
`
189
199
`fn compare(left: &[Self], right: &[Self]) -> Ordering {
`
190
200
`// Since the length of a slice is always less than or equal to isize::MAX, this never underflows.
`
191
201
`let diff = left.len() as isize - right.len() as isize;
`
192
202
`// This comparison gets optimized away (on x86_64 and ARM) because the subtraction updates flags.
`
193
203
`let len = if left.len() < right.len() { left.len() } else { right.len() };
`
``
204
`+
let left = left.as_ptr().cast();
`
``
205
`+
let right = right.as_ptr().cast();
`
194
206
`` // SAFETY: left
and right
are references and are thus guaranteed to be valid.
``
195
``
`-
// We use the minimum of both lengths which guarantees that both regions are
`
196
``
`-
// valid for reads in that interval.
`
197
``
`-
let mut order = unsafe { compare_bytes(left.as_ptr(), right.as_ptr(), len) as isize };
`
``
207
`` +
// UnsignedByte
is only implemented for types that are valid u8s. We use the
``
``
208
`+
// minimum of both lengths which guarantees that both regions are valid for reads
`
``
209
`+
// in that interval.
`
``
210
`+
let mut order = unsafe { compare_bytes(left, right, len) as isize };
`
198
211
`if order == 0 {
`
199
212
` order = diff;
`
200
213
`}
`