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

`}

`