Skip to content

Commit d078403

Browse files
committed
Specialize OsString::push for strings
Avoid trying to join surrogates at boundaries when concatenating a WTF-8 OsString and a UTF-8 string. Unfortunately, a specialization for `T: AsRef<str>` conflicts with `T: AsRef<OsStr>`, so stamp out string types with a macro.
1 parent cb08599 commit d078403

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

library/std/src/ffi/os_str.rs

+24-1
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,30 @@ impl OsString {
257257
#[inline]
258258
#[rustc_confusables("append", "put")]
259259
pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
260-
self.inner.push_slice(&s.as_ref().inner)
260+
trait SpecPushTo {
261+
fn spec_push_to(&self, buf: &mut OsString);
262+
}
263+
264+
impl<T: AsRef<OsStr>> SpecPushTo for T {
265+
#[inline]
266+
default fn spec_push_to(&self, buf: &mut OsString) {
267+
buf.inner.push_slice(&self.as_ref().inner);
268+
}
269+
}
270+
271+
macro spec_str($T:ty) {
272+
impl SpecPushTo for $T {
273+
#[inline]
274+
fn spec_push_to(&self, buf: &mut OsString) {
275+
buf.inner.push_str(self);
276+
}
277+
}
278+
}
279+
spec_str!(str);
280+
spec_str!(String);
281+
spec_str!(Cow<'_, str>);
282+
283+
s.spec_push_to(self)
261284
}
262285

263286
/// Creates a new `OsString` with at least the given capacity.

library/std/src/sys/os_str/bytes.rs

+5
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ impl Buf {
139139
self.inner.extend_from_slice(&s.inner)
140140
}
141141

142+
#[inline]
143+
pub fn push_str(&mut self, s: &str) {
144+
self.inner.extend_from_slice(s.as_bytes());
145+
}
146+
142147
#[inline]
143148
pub fn reserve(&mut self, additional: usize) {
144149
self.inner.reserve(additional)

library/std/src/sys/os_str/wtf8.rs

+5
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ impl Buf {
116116
self.inner.push_wtf8(&s.inner)
117117
}
118118

119+
#[inline]
120+
pub fn push_str(&mut self, s: &str) {
121+
self.inner.push_str(s);
122+
}
123+
119124
#[inline]
120125
pub fn reserve(&mut self, additional: usize) {
121126
self.inner.reserve(additional)

0 commit comments

Comments
 (0)