Skip to content

Commit 87e6297

Browse files
authored
Unrolled build for rust-lang#128137
Rollup merge of rust-lang#128137 - GrigorenkoPV:cstr-derive, r=dtolnay CStr: derive PartialEq, Eq; add test for Ord While working on rust-lang#128046, I've spotted a peculiarity: `CStr` has `PartialEq, Eq, PartialOrd, Ord` implemented manually and not derived. While we can't derive `PartialOrd, Ord` (due to inner `[c_char]` being `[i8]` or `[u8]` on different platforms), we *can* derive `PartialEq, Eq` (I think), allowing as to remove `#[allow(clippy::derived_hash_with_manual_eq)]` as well. (I really hope `c_char: Eq` on all platforms)
2 parents eb10639 + cf9816c commit 87e6297

File tree

4 files changed

+21
-11
lines changed

4 files changed

+21
-11
lines changed

library/core/src/ffi/c_str.rs

+4-11
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ use crate::str;
9494
/// ```
9595
///
9696
/// [str]: prim@str "str"
97-
#[derive(Hash)]
97+
#[derive(PartialEq, Eq, Hash)]
9898
#[stable(feature = "core_c_str", since = "1.64.0")]
9999
#[rustc_has_incoherent_inherent_impls]
100100
#[lang = "CStr"]
@@ -104,7 +104,6 @@ use crate::str;
104104
// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
105105
// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
106106
#[repr(transparent)]
107-
#[allow(clippy::derived_hash_with_manual_eq)]
108107
pub struct CStr {
109108
// FIXME: this should not be represented with a DST slice but rather with
110109
// just a raw `c_char` along with some form of marker to make
@@ -678,15 +677,9 @@ impl CStr {
678677
}
679678
}
680679

681-
#[stable(feature = "rust1", since = "1.0.0")]
682-
impl PartialEq for CStr {
683-
#[inline]
684-
fn eq(&self, other: &CStr) -> bool {
685-
self.to_bytes().eq(other.to_bytes())
686-
}
687-
}
688-
#[stable(feature = "rust1", since = "1.0.0")]
689-
impl Eq for CStr {}
680+
// `.to_bytes()` representations are compared instead of the inner `[c_char]`s,
681+
// because `c_char` is `i8` (not `u8`) on some platforms.
682+
// That is why this is implemented manually and not derived.
690683
#[stable(feature = "rust1", since = "1.0.0")]
691684
impl PartialOrd for CStr {
692685
#[inline]

library/core/tests/ffi.rs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mod cstr;

library/core/tests/ffi/cstr.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use core::ffi::CStr;
2+
3+
#[test]
4+
fn compares_as_u8s() {
5+
let a: &CStr = c"Hello!"; // Starts with ascii
6+
let a_bytes: &[u8] = a.to_bytes();
7+
assert!((..0b1000_0000).contains(&a_bytes[0]));
8+
9+
let b: &CStr = c"こんにちは!"; // Starts with non ascii
10+
let b_bytes: &[u8] = b.to_bytes();
11+
assert!((0b1000_0000..).contains(&b_bytes[0]));
12+
13+
assert_eq!(Ord::cmp(a, b), Ord::cmp(a_bytes, b_bytes));
14+
assert_eq!(PartialOrd::partial_cmp(a, b), PartialOrd::partial_cmp(a_bytes, b_bytes));
15+
}

library/core/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ mod clone;
132132
mod cmp;
133133
mod const_ptr;
134134
mod convert;
135+
mod ffi;
135136
mod fmt;
136137
mod future;
137138
mod hash;

0 commit comments

Comments
 (0)