Skip to content

Commit ccefbe8

Browse files
committed
impl Send + Sync and override count for the CStr::bytes iterator
1 parent 9c3bc80 commit ccefbe8

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

library/core/src/ffi/c_str.rs

+21-7
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,11 @@ impl AsRef<CStr> for CStr {
735735
}
736736
}
737737

738+
extern "C" {
739+
/// Provided by libc or compiler_builtins.
740+
fn strlen(s: *const c_char) -> usize;
741+
}
742+
738743
/// Calculate the length of a nul-terminated string. Defers to C's `strlen` when possible.
739744
///
740745
/// # Safety
@@ -756,11 +761,6 @@ const unsafe fn const_strlen(ptr: *const c_char) -> usize {
756761

757762
#[inline]
758763
fn strlen_rt(s: *const c_char) -> usize {
759-
extern "C" {
760-
/// Provided by libc or compiler_builtins.
761-
fn strlen(s: *const c_char) -> usize;
762-
}
763-
764764
// SAFETY: Outer caller has provided a pointer to a valid C string.
765765
unsafe { strlen(s) }
766766
}
@@ -780,8 +780,15 @@ const unsafe fn const_strlen(ptr: *const c_char) -> usize {
780780
pub struct Bytes<'a> {
781781
// since we know the string is nul-terminated, we only need one pointer
782782
ptr: NonNull<u8>,
783-
phantom: PhantomData<&'a u8>,
783+
phantom: PhantomData<&'a [c_char]>,
784784
}
785+
786+
#[unstable(feature = "cstr_bytes", issue = "112115")]
787+
unsafe impl Send for Bytes<'_> {}
788+
789+
#[unstable(feature = "cstr_bytes", issue = "112115")]
790+
unsafe impl Sync for Bytes<'_> {}
791+
785792
impl<'a> Bytes<'a> {
786793
#[inline]
787794
fn new(s: &'a CStr) -> Self {
@@ -814,7 +821,7 @@ impl Iterator for Bytes<'_> {
814821
if ret == 0 {
815822
None
816823
} else {
817-
self.ptr = self.ptr.offset(1);
824+
self.ptr = self.ptr.add(1);
818825
Some(ret)
819826
}
820827
}
@@ -824,7 +831,14 @@ impl Iterator for Bytes<'_> {
824831
fn size_hint(&self) -> (usize, Option<usize>) {
825832
if self.is_empty() { (0, Some(0)) } else { (1, None) }
826833
}
834+
835+
#[inline]
836+
fn count(self) -> usize {
837+
// SAFETY: We always hold a valid pointer to a C string
838+
unsafe { strlen(self.ptr.as_ptr().cast()) }
839+
}
827840
}
828841

829842
#[unstable(feature = "cstr_bytes", issue = "112115")]
830843
impl FusedIterator for Bytes<'_> {}
844+

0 commit comments

Comments
 (0)