Skip to content

Commit 30550c0

Browse files
Rollup merge of #137268 - bjoernager:c-string-eq-c-str, r=Amanieu
Allow comparisons between `CStr`, `CString`, and `Cow<CStr>`. Closes: #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 36b2163 + 817b093 commit 30550c0

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
@@ -1099,6 +1099,46 @@ impl From<&CStr> for CString {
10991099
}
11001100
}
11011101

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

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

library/core/src/ffi/c_str.rs

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

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

0 commit comments

Comments
 (0)