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

`}

`