From 20c2d6ac1cd2be4cf8fc92fd850e236698680c8b Mon Sep 17 00:00:00 2001 From: Sky Date: Sun, 7 Jul 2024 00:18:35 -0400 Subject: [PATCH] `impl Send + Sync` and override `count` for the `CStr::bytes` iterator --- library/core/src/ffi/c_str.rs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index d2a408485d162..9cc114fe430a6 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -735,6 +735,11 @@ impl AsRef for CStr { } } +extern "C" { + /// Provided by libc or compiler_builtins. + fn strlen(s: *const c_char) -> usize; +} + /// Calculate the length of a nul-terminated string. Defers to C's `strlen` when possible. /// /// # Safety @@ -756,11 +761,6 @@ const unsafe fn const_strlen(ptr: *const c_char) -> usize { #[inline] fn strlen_rt(s: *const c_char) -> usize { - extern "C" { - /// Provided by libc or compiler_builtins. - fn strlen(s: *const c_char) -> usize; - } - // SAFETY: Outer caller has provided a pointer to a valid C string. unsafe { strlen(s) } } @@ -780,8 +780,15 @@ const unsafe fn const_strlen(ptr: *const c_char) -> usize { pub struct Bytes<'a> { // since we know the string is nul-terminated, we only need one pointer ptr: NonNull, - phantom: PhantomData<&'a u8>, + phantom: PhantomData<&'a [c_char]>, } + +#[unstable(feature = "cstr_bytes", issue = "112115")] +unsafe impl Send for Bytes<'_> {} + +#[unstable(feature = "cstr_bytes", issue = "112115")] +unsafe impl Sync for Bytes<'_> {} + impl<'a> Bytes<'a> { #[inline] fn new(s: &'a CStr) -> Self { @@ -814,7 +821,7 @@ impl Iterator for Bytes<'_> { if ret == 0 { None } else { - self.ptr = self.ptr.offset(1); + self.ptr = self.ptr.add(1); Some(ret) } } @@ -824,6 +831,12 @@ impl Iterator for Bytes<'_> { fn size_hint(&self) -> (usize, Option) { if self.is_empty() { (0, Some(0)) } else { (1, None) } } + + #[inline] + fn count(self) -> usize { + // SAFETY: We always hold a valid pointer to a C string + unsafe { strlen(self.ptr.as_ptr().cast()) } + } } #[unstable(feature = "cstr_bytes", issue = "112115")]