Skip to content

Commit 09d15e9

Browse files
committed
Add parameter for CString, OsString, and PathBuf
1 parent abe1e0d commit 09d15e9

File tree

5 files changed

+96
-18
lines changed

5 files changed

+96
-18
lines changed

src/libstd/ffi/c_str.rs

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
use crate::alloc::{AllocRef, Global};
12
use crate::ascii;
23
use crate::borrow::{Borrow, Cow};
34
use crate::cmp::Ordering;
45
use crate::error::Error;
56
use crate::fmt::{self, Write};
7+
use crate::hash;
68
use crate::io;
79
use crate::mem;
810
use crate::memchr;
@@ -114,13 +116,55 @@ use crate::sys;
114116
/// of `CString` instances can lead to invalid memory accesses, memory leaks,
115117
/// and other memory errors.
116118
117-
#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
118119
#[stable(feature = "rust1", since = "1.0.0")]
119-
pub struct CString {
120+
pub struct CString<A: AllocRef = Global> {
120121
// Invariant 1: the slice ends with a zero byte and has a length of at least one.
121122
// Invariant 2: the slice contains only one zero byte.
122123
// Improper usage of unsafe function can break Invariant 2, but not Invariant 1.
123-
inner: Box<[u8]>,
124+
inner: Box<[u8], A>,
125+
}
126+
127+
#[stable(feature = "rust1", since = "1.0.0")]
128+
impl PartialEq for CString {
129+
#[inline]
130+
fn eq(&self, other: &Self) -> bool {
131+
self.inner.eq(&other.inner)
132+
}
133+
}
134+
135+
#[stable(feature = "rust1", since = "1.0.0")]
136+
impl Eq for CString {}
137+
138+
#[stable(feature = "rust1", since = "1.0.0")]
139+
impl PartialOrd for CString {
140+
#[inline]
141+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
142+
self.inner.partial_cmp(&other.inner)
143+
}
144+
}
145+
146+
#[stable(feature = "rust1", since = "1.0.0")]
147+
impl Ord for CString {
148+
#[inline]
149+
fn cmp(&self, other: &Self) -> Ordering {
150+
self.inner.cmp(&other.inner)
151+
}
152+
}
153+
154+
#[stable(feature = "rust1", since = "1.0.0")]
155+
impl hash::Hash for CString {
156+
#[inline]
157+
fn hash<H: hash::Hasher>(&self, state: &mut H) {
158+
self.inner.hash(state)
159+
}
160+
}
161+
162+
#[stable(feature = "rust1", since = "1.0.0")]
163+
impl Clone for CString {
164+
#[inline]
165+
fn clone(&self) -> Self {
166+
Self { inner: self.inner.clone() }
167+
}
124168
}
125169

126170
/// Representation of a borrowed C string.
@@ -638,7 +682,7 @@ impl CString {
638682
// memory-unsafe code from working by accident. Inline
639683
// to prevent LLVM from optimizing it away in debug builds.
640684
#[stable(feature = "cstring_drop", since = "1.13.0")]
641-
impl Drop for CString {
685+
impl<A: AllocRef> Drop for CString<A> {
642686
#[inline]
643687
fn drop(&mut self) {
644688
unsafe {

src/libstd/ffi/os_str.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::alloc::{AllocRef, Global};
12
use crate::borrow::{Borrow, Cow};
23
use crate::cmp;
34
use crate::fmt;
@@ -75,10 +76,17 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
7576
/// [`push`]: #method.push
7677
/// [`as_os_str`]: #method.as_os_str
7778
/// [conversions]: index.html#conversions
78-
#[derive(Clone)]
7979
#[stable(feature = "rust1", since = "1.0.0")]
80-
pub struct OsString {
81-
inner: Buf,
80+
pub struct OsString<A: AllocRef = Global> {
81+
inner: Buf<A>,
82+
}
83+
84+
#[stable(feature = "rust1", since = "1.0.0")]
85+
impl Clone for OsString {
86+
#[inline]
87+
fn clone(&self) -> Self {
88+
Self { inner: self.inner.clone() }
89+
}
8290
}
8391

8492
/// Borrowed reference to an OS string (see [`OsString`]).
@@ -1155,14 +1163,14 @@ impl AsRef<OsStr> for String {
11551163
}
11561164
}
11571165

1158-
impl FromInner<Buf> for OsString {
1159-
fn from_inner(buf: Buf) -> OsString {
1160-
OsString { inner: buf }
1166+
impl<A: AllocRef> FromInner<Buf<A>> for OsString<A> {
1167+
fn from_inner(buf: Buf<A>) -> OsString<A> {
1168+
Self { inner: buf }
11611169
}
11621170
}
11631171

1164-
impl IntoInner<Buf> for OsString {
1165-
fn into_inner(self) -> Buf {
1172+
impl<A: AllocRef> IntoInner<Buf<A>> for OsString<A> {
1173+
fn into_inner(self) -> Buf<A> {
11661174
self.inner
11671175
}
11681176
}

src/libstd/path.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
7070
#![stable(feature = "rust1", since = "1.0.0")]
7171

72+
use crate::alloc::{AllocRef, Global};
7273
use crate::borrow::{Borrow, Cow};
7374
use crate::cmp;
7475
use crate::error::Error;
@@ -1079,16 +1080,23 @@ impl FusedIterator for Ancestors<'_> {}
10791080
/// ```
10801081
///
10811082
/// Which method works best depends on what kind of situation you're in.
1082-
#[derive(Clone)]
10831083
#[stable(feature = "rust1", since = "1.0.0")]
10841084
// FIXME:
10851085
// `PathBuf::as_mut_vec` current implementation relies
10861086
// on `PathBuf` being layout-compatible with `Vec<u8>`.
10871087
// When attribute privacy is implemented, `PathBuf` should be annotated as `#[repr(transparent)]`.
10881088
// Anyway, `PathBuf` representation and layout are considered implementation detail, are
10891089
// not documented and must not be relied upon.
1090-
pub struct PathBuf {
1091-
inner: OsString,
1090+
pub struct PathBuf<A: AllocRef = Global> {
1091+
inner: OsString<A>,
1092+
}
1093+
1094+
#[stable(feature = "rust1", since = "1.0.0")]
1095+
impl Clone for PathBuf {
1096+
#[inline]
1097+
fn clone(&self) -> Self {
1098+
Self { inner: self.inner.clone() }
1099+
}
10921100
}
10931101

10941102
impl PathBuf {

src/libstd/sys_common/os_str_bytes.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
//! The underlying OsString/OsStr implementation on Unix and many other
22
//! systems: just a `Vec<u8>`/`[u8]`.
33
4+
use crate::alloc::{AllocRef, Global};
45
use crate::borrow::Cow;
56
use crate::ffi::{OsStr, OsString};
67
use crate::fmt;
8+
use crate::hash;
79
use crate::mem;
810
use crate::rc::Rc;
911
use crate::str;
@@ -13,9 +15,22 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
1315

1416
use core::str::lossy::Utf8Lossy;
1517

16-
#[derive(Clone, Hash)]
17-
pub(crate) struct Buf {
18-
pub inner: Vec<u8>,
18+
pub(crate) struct Buf<A: AllocRef = Global> {
19+
pub inner: Vec<u8, A>,
20+
}
21+
22+
impl Clone for Buf {
23+
#[inline]
24+
fn clone(&self) -> Self {
25+
Self { inner: self.inner.clone() }
26+
}
27+
}
28+
29+
impl hash::Hash for Buf {
30+
#[inline]
31+
fn hash<H: hash::Hasher>(&self, state: &mut H) {
32+
self.inner.hash(state)
33+
}
1934
}
2035

2136
// FIXME:

src/test/ui/conversion-methods.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ LL | let _just_to_make_bliss: PathBuf = Path::new("/ern/her/own/surprise");
2020
| | expected struct `std::path::PathBuf`, found `&std::path::Path`
2121
| | help: try using a conversion method: `Path::new("/ern/her/own/surprise").to_path_buf()`
2222
| expected due to this
23+
|
24+
= note: expected struct `std::path::PathBuf`
25+
found reference `&std::path::Path`
2326

2427
error[E0308]: mismatched types
2528
--> $DIR/conversion-methods.rs:9:40

0 commit comments

Comments
 (0)