diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2025-06-24 15:39:37 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-24 15:39:37 +0200 |
| commit | 30550c048d0d15a91ecd678f265d331531d49f7b (patch) | |
| tree | fa03e3c3a59ef7001772f725160326b0643ce6cb | |
| parent | 36b21637e93b038453924d3c66821089e71d8baa (diff) | |
| parent | 817b0932fa66ee8fd6e695f9ec74804a6c360269 (diff) | |
| download | rust-30550c048d0d15a91ecd678f265d331531d49f7b.tar.gz rust-30550c048d0d15a91ecd678f265d331531d49f7b.zip | |
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](https://github.com/rust-lang/libs-team/issues/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).
| -rw-r--r-- | library/alloc/src/ffi/c_str.rs | 109 | ||||
| -rw-r--r-- | library/core/src/ffi/c_str.rs | 14 |
2 files changed, 123 insertions, 0 deletions
diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index 48849bf7536..93bdad75380 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -1099,6 +1099,46 @@ impl From<&CStr> for CString { } } +#[stable(feature = "c_string_eq_c_str", since = "CURRENT_RUSTC_VERSION")] +impl PartialEq<CStr> for CString { + #[inline] + fn eq(&self, other: &CStr) -> bool { + **self == *other + } + + #[inline] + fn ne(&self, other: &CStr) -> bool { + **self != *other + } +} + +#[stable(feature = "c_string_eq_c_str", since = "CURRENT_RUSTC_VERSION")] +impl PartialEq<&CStr> for CString { + #[inline] + fn eq(&self, other: &&CStr) -> bool { + **self == **other + } + + #[inline] + fn ne(&self, other: &&CStr) -> bool { + **self != **other + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "c_string_eq_c_str", since = "CURRENT_RUSTC_VERSION")] +impl PartialEq<Cow<'_, CStr>> for CString { + #[inline] + fn eq(&self, other: &Cow<'_, CStr>) -> bool { + **self == **other + } + + #[inline] + fn ne(&self, other: &Cow<'_, CStr>) -> bool { + **self != **other + } +} + #[stable(feature = "cstring_asref", since = "1.7.0")] impl ops::Index<ops::RangeFull> for CString { type Output = CStr; @@ -1181,6 +1221,75 @@ impl CStr { } } +#[stable(feature = "c_string_eq_c_str", since = "CURRENT_RUSTC_VERSION")] +impl PartialEq<CString> for CStr { + #[inline] + fn eq(&self, other: &CString) -> bool { + *self == **other + } + + #[inline] + fn ne(&self, other: &CString) -> bool { + *self != **other + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "c_string_eq_c_str", since = "CURRENT_RUSTC_VERSION")] +impl PartialEq<Cow<'_, Self>> for CStr { + #[inline] + fn eq(&self, other: &Cow<'_, Self>) -> bool { + *self == **other + } + + #[inline] + fn ne(&self, other: &Cow<'_, Self>) -> bool { + *self != **other + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "c_string_eq_c_str", since = "CURRENT_RUSTC_VERSION")] +impl PartialEq<CStr> for Cow<'_, CStr> { + #[inline] + fn eq(&self, other: &CStr) -> bool { + **self == *other + } + + #[inline] + fn ne(&self, other: &CStr) -> bool { + **self != *other + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "c_string_eq_c_str", since = "CURRENT_RUSTC_VERSION")] +impl PartialEq<&CStr> for Cow<'_, CStr> { + #[inline] + fn eq(&self, other: &&CStr) -> bool { + **self == **other + } + + #[inline] + fn ne(&self, other: &&CStr) -> bool { + **self != **other + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "c_string_eq_c_str", since = "CURRENT_RUSTC_VERSION")] +impl PartialEq<CString> for Cow<'_, CStr> { + #[inline] + fn eq(&self, other: &CString) -> bool { + **self == **other + } + + #[inline] + fn ne(&self, other: &CString) -> bool { + **self != **other + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl core::error::Error for NulError { #[allow(deprecated)] diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index f7a21072f53..1d2e13db218 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -660,6 +660,19 @@ impl CStr { } } +#[stable(feature = "c_string_eq_c_str", since = "CURRENT_RUSTC_VERSION")] +impl PartialEq<&Self> for CStr { + #[inline] + fn eq(&self, other: &&Self) -> bool { + *self == **other + } + + #[inline] + fn ne(&self, other: &&Self) -> bool { + *self != **other + } +} + // `.to_bytes()` representations are compared instead of the inner `[c_char]`s, // because `c_char` is `i8` (not `u8`) on some platforms. // That is why this is implemented manually and not derived. @@ -670,6 +683,7 @@ impl PartialOrd for CStr { self.to_bytes().partial_cmp(&other.to_bytes()) } } + #[stable(feature = "rust1", since = "1.0.0")] impl Ord for CStr { #[inline] |
