Rollup merge of #128495 - joboet:more_memcmp, r=scottmcm · patricklam/verify-rust-std@b93e3ab (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,41 @@ impl<A: Ord> SliceOrd for A {
`
182
183
`}
`
183
184
`}
`
184
185
``
185
``
`` -
// 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 {
`
``
186
`+
/// Marks that a type should be treated as an unsigned byte for comparisons.
`
``
187
`+
///
`
``
188
`+
/// # Safety
`
``
189
`` +
/// * The type must be readable as an u8, meaning it has to have the same
``
``
190
`` +
/// layout as u8 and always be initialized.
``
``
191
`` +
/// * For every x and y of this type, Ord(x, y) must return the same
``
``
192
`` +
/// value as Ord::cmp(transmute::<_, u8>(x), transmute::<_, u8>(y)).
``
``
193
`+
#[rustc_specialization_trait]
`
``
194
`+
unsafe trait UnsignedBytewiseOrd {}
`
``
195
+
``
196
`+
unsafe impl UnsignedBytewiseOrd for bool {}
`
``
197
`+
unsafe impl UnsignedBytewiseOrd for u8 {}
`
``
198
`+
unsafe impl UnsignedBytewiseOrd for NonZero {}
`
``
199
`+
unsafe impl UnsignedBytewiseOrd for Option<NonZero> {}
`
``
200
`+
unsafe impl UnsignedBytewiseOrd for ascii::Char {}
`
``
201
+
``
202
`` +
// compare_bytes compares a sequence of unsigned bytes lexicographically, so
``
``
203
`` +
// use it if the requirements for UnsignedBytewiseOrd are fulfilled.
``
``
204
`+
impl<A: Ord + UnsignedBytewiseOrd> SliceOrd for A {
`
188
205
`#[inline]
`
189
206
`fn compare(left: &[Self], right: &[Self]) -> Ordering {
`
190
``
`-
// Since the length of a slice is always less than or equal to isize::MAX, this never underflows.
`
``
207
`+
// Since the length of a slice is always less than or equal to
`
``
208
`+
// isize::MAX, this never underflows.
`
191
209
`let diff = left.len() as isize - right.len() as isize;
`
192
``
`-
// This comparison gets optimized away (on x86_64 and ARM) because the subtraction updates flags.
`
``
210
`+
// This comparison gets optimized away (on x86_64 and ARM) because the
`
``
211
`+
// subtraction updates flags.
`
193
212
`let len = if left.len() < right.len() { left.len() } else { right.len() };
`
194
``
`` -
// 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 };
`
``
213
`+
let left = left.as_ptr().cast();
`
``
214
`+
let right = right.as_ptr().cast();
`
``
215
`` +
// SAFETY: left and right are references and are thus guaranteed to
``
``
216
`` +
// be valid. UnsignedBytewiseOrd is only implemented for types that
``
``
217
`+
// are valid u8s and can be compared the same way. We use the minimum
`
``
218
`+
// of both lengths which guarantees that both regions are valid for
`
``
219
`+
// reads in that interval.
`
``
220
`+
let mut order = unsafe { compare_bytes(left, right, len) as isize };
`
198
221
`if order == 0 {
`
199
222
` order = diff;
`
200
223
`}
`