Skip to content

Commit dc9e09d

Browse files
committed
Turn CStr into a DST
As decided in process of developing the CStr RFC [1], this is the way to go with CStr as an unsized type. The length of the internal slice is bogus; it only provides safe access to the first byte for the implementation of .is_empty(). [1] rust-lang/rfcs#592
1 parent fb2c506 commit dc9e09d

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

src/c_str.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,9 @@ pub struct CStrBuf {
284284
///
285285
/// `CStr` is only used by reference, e.g. as a parameter in a safe function
286286
/// proxying its FFI counterpart.
287-
#[repr(C)]
287+
#[repr(packed)]
288288
pub struct CStr {
289-
lead: libc::c_char,
290-
marker: marker::NoCopy
289+
chars: [libc::c_char]
291290
}
292291

293292
fn bytes_into_c_str(s: &[u8]) -> CStrBuf {
@@ -502,7 +501,8 @@ impl CStr {
502501
/// annotation may be used.
503502
#[inline]
504503
pub unsafe fn from_ptr<'a>(raw: *const libc::c_char) -> &'a CStr {
505-
mem::transmute(&*(raw as *const CStr))
504+
let inner = slice::from_raw_parts(raw, 1);
505+
mem::transmute(inner)
506506
}
507507

508508
/// Create a `CStr` reference out of a static byte array.
@@ -544,7 +544,7 @@ impl CStr {
544544
/// during the lifetime of the `CStr` value.
545545
#[inline]
546546
pub fn as_ptr(&self) -> *const libc::c_char {
547-
&self.lead as *const libc::c_char
547+
self.chars.as_ptr()
548548
}
549549

550550
/// Scans the string to get a byte slice of its contents.
@@ -579,7 +579,7 @@ impl CStr {
579579

580580
/// Returns true if the wrapped string is empty.
581581
#[inline]
582-
pub fn is_empty(&self) -> bool { self.lead == 0 }
582+
pub fn is_empty(&self) -> bool { self.chars[0] == 0 }
583583
}
584584

585585
impl fmt::Debug for CStr {

0 commit comments

Comments
 (0)