Skip to content

Commit

Permalink
Add ToCStr impl for &Path and ~str
Browse files Browse the repository at this point in the history
This is a stopgap until DST (rust-lang#12938) lands.

Until DST lands, we cannot decompose &str into & and str, so we cannot
usefully take ToCStr arguments by reference (without forcing an
additional & around &str). So we are instead temporarily adding an
instance for &Path and ~str, so that we can take ToCStr as owned. When
DST lands, the &Path instance should be removed, the string instances
should be revisted, and arguments bound by ToCStr should be passed by
reference.

FIXMEs have been added accordingly.
  • Loading branch information
aturon committed May 7, 2014
1 parent 24f6f26 commit 4e32b52
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 3 deletions.
29 changes: 29 additions & 0 deletions src/libstd/c_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,13 @@ pub trait ToCStr {
}
}

// FIXME (#12938): Until DST lands, we cannot decompose &str into & and str, so
// we cannot usefully take ToCStr arguments by reference (without forcing an
// additional & around &str). So we are instead temporarily adding an instance
// for ~str, so that we can take ToCStr as owned. When DST lands, the string
// instances should be revisted, and arguments bound by ToCStr should be passed
// by reference.

impl<'a> ToCStr for &'a str {
#[inline]
fn to_c_str(&self) -> CString {
Expand All @@ -315,6 +322,28 @@ impl<'a> ToCStr for &'a str {
}
}

impl ToCStr for ~str {
#[inline]
fn to_c_str(&self) -> CString {
self.as_bytes().to_c_str()
}

#[inline]
unsafe fn to_c_str_unchecked(&self) -> CString {
self.as_bytes().to_c_str_unchecked()
}

#[inline]
fn with_c_str<T>(&self, f: |*libc::c_char| -> T) -> T {
self.as_bytes().with_c_str(f)
}

#[inline]
unsafe fn with_c_str_unchecked<T>(&self, f: |*libc::c_char| -> T) -> T {
self.as_bytes().with_c_str_unchecked(f)
}
}

// The length of the stack allocated buffer for `vec.with_c_str()`
static BUF_LEN: uint = 128;

Expand Down
21 changes: 20 additions & 1 deletion src/libstd/path/posix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,18 @@ impl FromStr for Path {
}
}

// FIXME (#12938): Until DST lands, we cannot decompose &str into & and str, so
// we cannot usefully take ToCStr arguments by reference (without forcing an
// additional & around &str). So we are instead temporarily adding an instance
// for &Path, so that we can take ToCStr as owned. When DST lands, the &Path
// instance should be removed, and arguments bound by ToCStr should be passed by
// reference.

impl ToCStr for Path {
#[inline]
fn to_c_str(&self) -> CString {
// The Path impl guarantees no internal NUL
unsafe { self.as_vec().to_c_str_unchecked() }
unsafe { self.to_c_str_unchecked() }
}

#[inline]
Expand All @@ -92,6 +99,18 @@ impl ToCStr for Path {
}
}

impl<'a> ToCStr for &'a Path {
#[inline]
fn to_c_str(&self) -> CString {
(*self).to_c_str()
}

#[inline]
unsafe fn to_c_str_unchecked(&self) -> CString {
(*self).to_c_str_unchecked()
}
}

impl<S: Writer> ::hash::Hash<S> for Path {
#[inline]
fn hash(&self, state: &mut S) {
Expand Down
23 changes: 21 additions & 2 deletions src/libstd/path/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,18 @@ impl FromStr for Path {
}
}

// FIXME (#12938): Until DST lands, we cannot decompose &str into & and str, so
// we cannot usefully take ToCStr arguments by reference (without forcing an
// additional & around &str). So we are instead temporarily adding an instance
// for &Path, so that we can take ToCStr as owned. When DST lands, the &Path
// instance should be removed, and arguments bound by ToCStr should be passed by
// reference.

impl ToCStr for Path {
#[inline]
fn to_c_str(&self) -> CString {
// The Path impl guarantees no embedded NULs
unsafe { self.as_vec().to_c_str_unchecked() }
// The Path impl guarantees no internal NUL
unsafe { self.to_c_str_unchecked() }
}

#[inline]
Expand All @@ -116,6 +123,18 @@ impl ToCStr for Path {
}
}

impl<'a> ToCStr for &'a Path {
#[inline]
fn to_c_str(&self) -> CString {
(*self).to_c_str()
}

#[inline]
unsafe fn to_c_str_unchecked(&self) -> CString {
(*self).to_c_str_unchecked()
}
}

impl<S: Writer> ::hash::Hash<S> for Path {
#[inline]
fn hash(&self, state: &mut S) {
Expand Down

0 comments on commit 4e32b52

Please sign in to comment.