Skip to content

Commit 1f308f1

Browse files
committed
Auto merge of rust-lang#137268 - bjoernager:c-string-eq-c-str, r=<try>
Allow comparisons between `CStr`, `CString`, and `Cow<CStr>`. Closes: rust-lang#137265 This PR adds the trait implementations proposed in the [ACP](rust-lang/libs-team#517) under the `c_string_eq_c_str` feature gate: ```rust // core::ffi impl PartialEq<&Self> for CStr; impl PartialEq<CString> for CStr; impl PartialEq<Cow<'_, Self>> for CStr; // alloc::ffi impl PartialEq<CStr> for CString; impl PartialEq<&CStr> for CString; impl PartialEq<Cow<'_, CStr>> for CString; // alloc::borrow impl PartialEq<CStr> for Cow<'_, CStr>; impl PartialEq<&CStr> for Cow<'_, CStr>; impl PartialEq<CString> for Cow<'_, CStr>; ``` As I understand it, stable traits cannot be unstably implemented for stable types, and we would thereby be forced to skip the FCP and directly stabilise these implementations (as is done in this PR). (`@joshtriplett` mentioned that Crater may have to be run).
2 parents d2eadb7 + 817b093 commit 1f308f1

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed

library/alloc/src/ffi/c_str.rs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,46 @@ impl From<&CStr> for CString {
10971097
}
10981098
}
10991099

1100+
#[stable(feature = "c_string_eq_c_str", since = "CURRENT_RUSTC_VERSION")]
1101+
impl PartialEq<CStr> for CString {
1102+
#[inline]
1103+
fn eq(&self, other: &CStr) -> bool {
1104+
**self == *other
1105+
}
1106+
1107+
#[inline]
1108+
fn ne(&self, other: &CStr) -> bool {
1109+
**self != *other
1110+
}
1111+
}
1112+
1113+
#[stable(feature = "c_string_eq_c_str", since = "CURRENT_RUSTC_VERSION")]
1114+
impl PartialEq<&CStr> for CString {
1115+
#[inline]
1116+
fn eq(&self, other: &&CStr) -> bool {
1117+
**self == **other
1118+
}
1119+
1120+
#[inline]
1121+
fn ne(&self, other: &&CStr) -> bool {
1122+
**self != **other
1123+
}
1124+
}
1125+
1126+
#[cfg(not(no_global_oom_handling))]
1127+
#[stable(feature = "c_string_eq_c_str", since = "CURRENT_RUSTC_VERSION")]
1128+
impl PartialEq<Cow<'_, CStr>> for CString {
1129+
#[inline]
1130+
fn eq(&self, other: &Cow<'_, CStr>) -> bool {
1131+
**self == **other
1132+
}
1133+
1134+
#[inline]
1135+
fn ne(&self, other: &Cow<'_, CStr>) -> bool {
1136+
**self != **other
1137+
}
1138+
}
1139+
11001140
#[stable(feature = "cstring_asref", since = "1.7.0")]
11011141
impl ops::Index<ops::RangeFull> for CString {
11021142
type Output = CStr;
@@ -1179,6 +1219,75 @@ impl CStr {
11791219
}
11801220
}
11811221

1222+
#[stable(feature = "c_string_eq_c_str", since = "CURRENT_RUSTC_VERSION")]
1223+
impl PartialEq<CString> for CStr {
1224+
#[inline]
1225+
fn eq(&self, other: &CString) -> bool {
1226+
*self == **other
1227+
}
1228+
1229+
#[inline]
1230+
fn ne(&self, other: &CString) -> bool {
1231+
*self != **other
1232+
}
1233+
}
1234+
1235+
#[cfg(not(no_global_oom_handling))]
1236+
#[stable(feature = "c_string_eq_c_str", since = "CURRENT_RUSTC_VERSION")]
1237+
impl PartialEq<Cow<'_, Self>> for CStr {
1238+
#[inline]
1239+
fn eq(&self, other: &Cow<'_, Self>) -> bool {
1240+
*self == **other
1241+
}
1242+
1243+
#[inline]
1244+
fn ne(&self, other: &Cow<'_, Self>) -> bool {
1245+
*self != **other
1246+
}
1247+
}
1248+
1249+
#[cfg(not(no_global_oom_handling))]
1250+
#[stable(feature = "c_string_eq_c_str", since = "CURRENT_RUSTC_VERSION")]
1251+
impl PartialEq<CStr> for Cow<'_, CStr> {
1252+
#[inline]
1253+
fn eq(&self, other: &CStr) -> bool {
1254+
**self == *other
1255+
}
1256+
1257+
#[inline]
1258+
fn ne(&self, other: &CStr) -> bool {
1259+
**self != *other
1260+
}
1261+
}
1262+
1263+
#[cfg(not(no_global_oom_handling))]
1264+
#[stable(feature = "c_string_eq_c_str", since = "CURRENT_RUSTC_VERSION")]
1265+
impl PartialEq<&CStr> for Cow<'_, CStr> {
1266+
#[inline]
1267+
fn eq(&self, other: &&CStr) -> bool {
1268+
**self == **other
1269+
}
1270+
1271+
#[inline]
1272+
fn ne(&self, other: &&CStr) -> bool {
1273+
**self != **other
1274+
}
1275+
}
1276+
1277+
#[cfg(not(no_global_oom_handling))]
1278+
#[stable(feature = "c_string_eq_c_str", since = "CURRENT_RUSTC_VERSION")]
1279+
impl PartialEq<CString> for Cow<'_, CStr> {
1280+
#[inline]
1281+
fn eq(&self, other: &CString) -> bool {
1282+
**self == **other
1283+
}
1284+
1285+
#[inline]
1286+
fn ne(&self, other: &CString) -> bool {
1287+
**self != **other
1288+
}
1289+
}
1290+
11821291
#[stable(feature = "rust1", since = "1.0.0")]
11831292
impl core::error::Error for NulError {
11841293
#[allow(deprecated)]

library/core/src/ffi/c_str.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,19 @@ impl CStr {
661661
}
662662
}
663663

664+
#[stable(feature = "c_string_eq_c_str", since = "CURRENT_RUSTC_VERSION")]
665+
impl PartialEq<&Self> for CStr {
666+
#[inline]
667+
fn eq(&self, other: &&Self) -> bool {
668+
*self == **other
669+
}
670+
671+
#[inline]
672+
fn ne(&self, other: &&Self) -> bool {
673+
*self != **other
674+
}
675+
}
676+
664677
// `.to_bytes()` representations are compared instead of the inner `[c_char]`s,
665678
// because `c_char` is `i8` (not `u8`) on some platforms.
666679
// That is why this is implemented manually and not derived.
@@ -671,6 +684,7 @@ impl PartialOrd for CStr {
671684
self.to_bytes().partial_cmp(&other.to_bytes())
672685
}
673686
}
687+
674688
#[stable(feature = "rust1", since = "1.0.0")]
675689
impl Ord for CStr {
676690
#[inline]

0 commit comments

Comments
 (0)