From f727b3622bf69f44500e708f387160d5afbb39db Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Fri, 18 Apr 2025 10:15:11 -0400 Subject: [PATCH 1/5] Invert `::deref` and `CString::as_c_str` This is consistent with the style of `ByteString`. --- library/alloc/src/ffi/c_str.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index f6743c6571095..7e863f13f434d 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -574,7 +574,7 @@ impl CString { #[stable(feature = "as_c_str", since = "1.20.0")] #[rustc_diagnostic_item = "cstring_as_c_str"] pub fn as_c_str(&self) -> &CStr { - &*self + unsafe { CStr::from_bytes_with_nul_unchecked(self.as_bytes_with_nul()) } } /// Converts this `CString` into a boxed [`CStr`]. @@ -705,14 +705,14 @@ impl ops::Deref for CString { #[inline] fn deref(&self) -> &CStr { - unsafe { CStr::from_bytes_with_nul_unchecked(self.as_bytes_with_nul()) } + self.as_c_str() } } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for CString { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) + fmt::Debug::fmt(self.as_c_str(), f) } } From 9058bab9a9e88b90596019f686cce1f21ac19ef8 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Fri, 18 Apr 2025 10:30:38 -0400 Subject: [PATCH 2/5] Move `` test to coretests --- library/alloctests/tests/c_str2.rs | 6 ------ library/coretests/tests/ffi/cstr.rs | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/alloctests/tests/c_str2.rs b/library/alloctests/tests/c_str2.rs index 0f4c27fa12322..fe7686bd1c592 100644 --- a/library/alloctests/tests/c_str2.rs +++ b/library/alloctests/tests/c_str2.rs @@ -33,12 +33,6 @@ fn build_with_zero2() { assert!(CString::new(vec![0]).is_err()); } -#[test] -fn formatted() { - let s = CString::new(&b"abc\x01\x02\n\xE2\x80\xA6\xFF"[..]).unwrap(); - assert_eq!(format!("{s:?}"), r#""abc\x01\x02\n\xe2\x80\xa6\xff""#); -} - #[test] fn borrowed() { unsafe { diff --git a/library/coretests/tests/ffi/cstr.rs b/library/coretests/tests/ffi/cstr.rs index 9bf4c21a9ab97..0d85b22c585a1 100644 --- a/library/coretests/tests/ffi/cstr.rs +++ b/library/coretests/tests/ffi/cstr.rs @@ -13,3 +13,9 @@ fn compares_as_u8s() { assert_eq!(Ord::cmp(a, b), Ord::cmp(a_bytes, b_bytes)); assert_eq!(PartialOrd::partial_cmp(a, b), PartialOrd::partial_cmp(a_bytes, b_bytes)); } + +#[test] +fn debug() { + let s = c"abc\x01\x02\n\xE2\x80\xA6\xFF"; + assert_eq!(format!("{s:?}"), r#""abc\x01\x02\n\xe2\x80\xa6\xff""#); +} From 87072c1d2ec0b5efbcc23eea838357fc629bcf99 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Fri, 18 Apr 2025 11:20:14 -0400 Subject: [PATCH 3/5] Remove errant doc comment lines --- library/core/src/bstr/mod.rs | 1 - library/core/src/ffi/c_str.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/library/core/src/bstr/mod.rs b/library/core/src/bstr/mod.rs index c8d0c701ba8b7..07d4fd911d3a2 100644 --- a/library/core/src/bstr/mod.rs +++ b/library/core/src/bstr/mod.rs @@ -37,7 +37,6 @@ use crate::ops::{Deref, DerefMut, DerefPure}; /// /// The `Display` implementation behaves as if the `ByteStr` were first lossily converted to a /// `str`, with invalid UTF-8 presented as the Unicode replacement character: � -/// #[unstable(feature = "bstr", issue = "134915")] #[repr(transparent)] #[doc(alias = "BStr")] diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 080c0cef53304..85e87445a1b43 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -150,7 +150,6 @@ impl Error for FromBytesWithNulError { /// within the slice. /// /// This error is created by the [`CStr::from_bytes_until_nul`] method. -/// #[derive(Clone, PartialEq, Eq, Debug)] #[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")] pub struct FromBytesUntilNulError(()); From bc6f788118c2e3e0755323885b73acd7998a1e98 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Fri, 18 Apr 2025 11:25:46 -0400 Subject: [PATCH 4/5] Add missing period --- library/core/src/bstr/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/bstr/mod.rs b/library/core/src/bstr/mod.rs index 07d4fd911d3a2..66e57dc8813a6 100644 --- a/library/core/src/bstr/mod.rs +++ b/library/core/src/bstr/mod.rs @@ -36,7 +36,7 @@ use crate::ops::{Deref, DerefMut, DerefPure}; /// presented as hex escape sequences. /// /// The `Display` implementation behaves as if the `ByteStr` were first lossily converted to a -/// `str`, with invalid UTF-8 presented as the Unicode replacement character: � +/// `str`, with invalid UTF-8 presented as the Unicode replacement character: �. #[unstable(feature = "bstr", issue = "134915")] #[repr(transparent)] #[doc(alias = "BStr")] From 89009268306e286eaf9db01855c826e7d09768a8 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Thu, 17 Apr 2025 19:43:56 -0400 Subject: [PATCH 5/5] `impl Display for CStr{,ing}` Delegate to `::fmt`. Link: https://github.com/rust-lang/libs-team/issues/550 Link: https://github.com/rust-lang/rust/issues/139984. --- library/alloc/src/ffi/c_str.rs | 9 +++++++++ library/core/src/ffi/c_str.rs | 9 +++++++++ library/coretests/tests/ffi/cstr.rs | 6 ++++++ 3 files changed, 24 insertions(+) diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index 7e863f13f434d..e8735365cd50e 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -716,6 +716,15 @@ impl fmt::Debug for CString { } } +/// Delegates to the [`CStr`] implementation of [`fmt::Display`], +/// showing invalid UTF-8 as the Unicode replacement character. +#[stable(feature = "cstr_display", since = "CURRENT_RUSTC_VERSION")] +impl fmt::Display for CString { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self.as_c_str(), f) + } +} + #[stable(feature = "cstring_into", since = "1.7.0")] impl From for Vec { /// Converts a [`CString`] into a [Vec]<[u8]>. diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 85e87445a1b43..85c48ccdb89ac 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -168,6 +168,15 @@ impl fmt::Debug for CStr { } } +/// Behaves as if `self` were first lossily converted to a `str`, with +/// invalid UTF-8 presented as the Unicode replacement character: �. +#[stable(feature = "cstr_display", since = "CURRENT_RUSTC_VERSION")] +impl fmt::Display for CStr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(crate::bstr::ByteStr::from_bytes(self.to_bytes()), f) + } +} + #[stable(feature = "cstr_default", since = "1.10.0")] impl Default for &CStr { #[inline] diff --git a/library/coretests/tests/ffi/cstr.rs b/library/coretests/tests/ffi/cstr.rs index 0d85b22c585a1..b9f3d65dc02cd 100644 --- a/library/coretests/tests/ffi/cstr.rs +++ b/library/coretests/tests/ffi/cstr.rs @@ -19,3 +19,9 @@ fn debug() { let s = c"abc\x01\x02\n\xE2\x80\xA6\xFF"; assert_eq!(format!("{s:?}"), r#""abc\x01\x02\n\xe2\x80\xa6\xff""#); } + +#[test] +fn display() { + let s = c"\xf0\x28\x8c\xbc"; + assert_eq!(format!("{s}"), "�(��"); +}