Skip to content

Commit 4e32b52

Browse files
committed
Add ToCStr impl for &Path and ~str
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.
1 parent 24f6f26 commit 4e32b52

File tree

3 files changed

+70
-3
lines changed

3 files changed

+70
-3
lines changed

src/libstd/c_str.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,13 @@ pub trait ToCStr {
293293
}
294294
}
295295

296+
// FIXME (#12938): Until DST lands, we cannot decompose &str into & and str, so
297+
// we cannot usefully take ToCStr arguments by reference (without forcing an
298+
// additional & around &str). So we are instead temporarily adding an instance
299+
// for ~str, so that we can take ToCStr as owned. When DST lands, the string
300+
// instances should be revisted, and arguments bound by ToCStr should be passed
301+
// by reference.
302+
296303
impl<'a> ToCStr for &'a str {
297304
#[inline]
298305
fn to_c_str(&self) -> CString {
@@ -315,6 +322,28 @@ impl<'a> ToCStr for &'a str {
315322
}
316323
}
317324

325+
impl ToCStr for ~str {
326+
#[inline]
327+
fn to_c_str(&self) -> CString {
328+
self.as_bytes().to_c_str()
329+
}
330+
331+
#[inline]
332+
unsafe fn to_c_str_unchecked(&self) -> CString {
333+
self.as_bytes().to_c_str_unchecked()
334+
}
335+
336+
#[inline]
337+
fn with_c_str<T>(&self, f: |*libc::c_char| -> T) -> T {
338+
self.as_bytes().with_c_str(f)
339+
}
340+
341+
#[inline]
342+
unsafe fn with_c_str_unchecked<T>(&self, f: |*libc::c_char| -> T) -> T {
343+
self.as_bytes().with_c_str_unchecked(f)
344+
}
345+
}
346+
318347
// The length of the stack allocated buffer for `vec.with_c_str()`
319348
static BUF_LEN: uint = 128;
320349

src/libstd/path/posix.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,18 @@ impl FromStr for Path {
7979
}
8080
}
8181

82+
// FIXME (#12938): Until DST lands, we cannot decompose &str into & and str, so
83+
// we cannot usefully take ToCStr arguments by reference (without forcing an
84+
// additional & around &str). So we are instead temporarily adding an instance
85+
// for &Path, so that we can take ToCStr as owned. When DST lands, the &Path
86+
// instance should be removed, and arguments bound by ToCStr should be passed by
87+
// reference.
88+
8289
impl ToCStr for Path {
8390
#[inline]
8491
fn to_c_str(&self) -> CString {
8592
// The Path impl guarantees no internal NUL
86-
unsafe { self.as_vec().to_c_str_unchecked() }
93+
unsafe { self.to_c_str_unchecked() }
8794
}
8895

8996
#[inline]
@@ -92,6 +99,18 @@ impl ToCStr for Path {
9299
}
93100
}
94101

102+
impl<'a> ToCStr for &'a Path {
103+
#[inline]
104+
fn to_c_str(&self) -> CString {
105+
(*self).to_c_str()
106+
}
107+
108+
#[inline]
109+
unsafe fn to_c_str_unchecked(&self) -> CString {
110+
(*self).to_c_str_unchecked()
111+
}
112+
}
113+
95114
impl<S: Writer> ::hash::Hash<S> for Path {
96115
#[inline]
97116
fn hash(&self, state: &mut S) {

src/libstd/path/windows.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,18 @@ impl FromStr for Path {
103103
}
104104
}
105105

106+
// FIXME (#12938): Until DST lands, we cannot decompose &str into & and str, so
107+
// we cannot usefully take ToCStr arguments by reference (without forcing an
108+
// additional & around &str). So we are instead temporarily adding an instance
109+
// for &Path, so that we can take ToCStr as owned. When DST lands, the &Path
110+
// instance should be removed, and arguments bound by ToCStr should be passed by
111+
// reference.
112+
106113
impl ToCStr for Path {
107114
#[inline]
108115
fn to_c_str(&self) -> CString {
109-
// The Path impl guarantees no embedded NULs
110-
unsafe { self.as_vec().to_c_str_unchecked() }
116+
// The Path impl guarantees no internal NUL
117+
unsafe { self.to_c_str_unchecked() }
111118
}
112119

113120
#[inline]
@@ -116,6 +123,18 @@ impl ToCStr for Path {
116123
}
117124
}
118125

126+
impl<'a> ToCStr for &'a Path {
127+
#[inline]
128+
fn to_c_str(&self) -> CString {
129+
(*self).to_c_str()
130+
}
131+
132+
#[inline]
133+
unsafe fn to_c_str_unchecked(&self) -> CString {
134+
(*self).to_c_str_unchecked()
135+
}
136+
}
137+
119138
impl<S: Writer> ::hash::Hash<S> for Path {
120139
#[inline]
121140
fn hash(&self, state: &mut S) {

0 commit comments

Comments
 (0)