Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 8 pull requests #129841

Merged
merged 20 commits into from
Sep 1, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
88fda58
core: use `compare_bytes` for more slice element types
joboet Aug 1, 2024
32d6d0e
bless miri tests
joboet Aug 1, 2024
341511a
refactor: standardize duplicate processes in parser
Konippi Aug 4, 2024
8301dd4
core: make documentation clearer, rename slice comparison specializat…
joboet Aug 12, 2024
1a2ec26
Make option-like-enum.rs UB-free and portable
saethlin Aug 27, 2024
ea6df5c
Update stacker to 0.1.17
sunshowers Aug 26, 2024
fff063e
add crashtests for several old unfixed ICEs
cyrgani Aug 30, 2024
5d04472
Implement `elided_named_lifetimes` lint
GrigorenkoPV Aug 15, 2024
f7b0b22
Fix `elided_named_lifetimes` in code
GrigorenkoPV Aug 17, 2024
a9b959a
elided_named_lifetimes: bless & add tests
GrigorenkoPV Aug 31, 2024
d4e708f
Remove stray dot in `std::char::from_u32_unchecked` documentation
eduardosm Aug 31, 2024
f68f665
Create opaque definitions in resolver.
cjgillot Aug 24, 2024
a073004
Rollup merge of #128495 - joboet:more_memcmp, r=scottmcm
matthiaskrgr Sep 1, 2024
da65b90
Rollup merge of #128641 - Konippi:standardize-duplicate-processes-in-…
matthiaskrgr Sep 1, 2024
1063c0d
Rollup merge of #129207 - GrigorenkoPV:elided-is-named, r=cjgillot
matthiaskrgr Sep 1, 2024
07d5c25
Rollup merge of #129493 - cjgillot:early-opaque-def, r=petrochenkov
matthiaskrgr Sep 1, 2024
62b8fdb
Rollup merge of #129619 - sunshowers:update-stacker, r=Mark-Simulacrum
matthiaskrgr Sep 1, 2024
d24336b
Rollup merge of #129672 - saethlin:enum-debuginfo-tests, r=Mark-Simul…
matthiaskrgr Sep 1, 2024
f040e68
Rollup merge of #129780 - cyrgani:master, r=compiler-errors
matthiaskrgr Sep 1, 2024
2261ffa
Rollup merge of #129832 - eduardosm:stray-dot, r=jhpratt
matthiaskrgr Sep 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 33 additions & 10 deletions library/core/src/slice/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
use super::{from_raw_parts, memchr};
use crate::cmp::{self, BytewiseEq, Ordering};
use crate::intrinsics::compare_bytes;
use crate::mem;
use crate::num::NonZero;
use crate::{ascii, mem};

#[stable(feature = "rust1", since = "1.0.0")]
impl<T, U> PartialEq<[U]> for [T]
Expand Down Expand Up @@ -182,19 +183,41 @@ impl<A: Ord> SliceOrd for A {
}
}

// `compare_bytes` compares a sequence of unsigned bytes lexicographically.
// this matches the order we want for [u8], but no others (not even [i8]).
impl SliceOrd for u8 {
/// Marks that a type should be treated as an unsigned byte for comparisons.
///
/// # Safety
/// * The type must be readable as an `u8`, meaning it has to have the same
/// layout as `u8` and always be initialized.
/// * For every `x` and `y` of this type, `Ord(x, y)` must return the same
/// value as `Ord::cmp(transmute::<_, u8>(x), transmute::<_, u8>(y))`.
#[rustc_specialization_trait]
unsafe trait UnsignedBytewiseOrd {}

unsafe impl UnsignedBytewiseOrd for bool {}
unsafe impl UnsignedBytewiseOrd for u8 {}
unsafe impl UnsignedBytewiseOrd for NonZero<u8> {}
unsafe impl UnsignedBytewiseOrd for Option<NonZero<u8>> {}
unsafe impl UnsignedBytewiseOrd for ascii::Char {}

// `compare_bytes` compares a sequence of unsigned bytes lexicographically, so
// use it if the requirements for `UnsignedBytewiseOrd` are fulfilled.
impl<A: Ord + UnsignedBytewiseOrd> SliceOrd for A {
#[inline]
fn compare(left: &[Self], right: &[Self]) -> Ordering {
// Since the length of a slice is always less than or equal to isize::MAX, this never underflows.
// Since the length of a slice is always less than or equal to
// isize::MAX, this never underflows.
let diff = left.len() as isize - right.len() as isize;
// This comparison gets optimized away (on x86_64 and ARM) because the subtraction updates flags.
// This comparison gets optimized away (on x86_64 and ARM) because the
// subtraction updates flags.
let len = if left.len() < right.len() { left.len() } else { right.len() };
// SAFETY: `left` and `right` are references and are thus guaranteed to be valid.
// We use the minimum of both lengths which guarantees that both regions are
// valid for reads in that interval.
let mut order = unsafe { compare_bytes(left.as_ptr(), right.as_ptr(), len) as isize };
let left = left.as_ptr().cast();
let right = right.as_ptr().cast();
// SAFETY: `left` and `right` are references and are thus guaranteed to
// be valid. `UnsignedBytewiseOrd` is only implemented for types that
// are valid u8s and can be compared the same way. We use the minimum
// of both lengths which guarantees that both regions are valid for
// reads in that interval.
let mut order = unsafe { compare_bytes(left, right, len) as isize };
if order == 0 {
order = diff;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error: Undefined Behavior: reading memory at ALLOC[0x0..0x10], but memory is uninitialized at [0x4..0x10], and this operation requires initialized memory
--> RUSTLIB/core/src/slice/cmp.rs:LL:CC
|
LL | let mut order = unsafe { compare_bytes(left.as_ptr(), right.as_ptr(), len) as isize };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading memory at ALLOC[0x0..0x10], but memory is uninitialized at [0x4..0x10], and this operation requires initialized memory
LL | let mut order = unsafe { compare_bytes(left, right, len) as isize };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading memory at ALLOC[0x0..0x10], but memory is uninitialized at [0x4..0x10], and this operation requires initialized memory
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error: Undefined Behavior: reading memory at ALLOC[0x0..0x8], but memory is uninitialized at [0x4..0x8], and this operation requires initialized memory
--> RUSTLIB/core/src/slice/cmp.rs:LL:CC
|
LL | let mut order = unsafe { compare_bytes(left.as_ptr(), right.as_ptr(), len) as isize };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading memory at ALLOC[0x0..0x8], but memory is uninitialized at [0x4..0x8], and this operation requires initialized memory
LL | let mut order = unsafe { compare_bytes(left, right, len) as isize };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading memory at ALLOC[0x0..0x8], but memory is uninitialized at [0x4..0x8], and this operation requires initialized memory
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
Expand Down