about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-10-20 14:07:46 +0000
committerbors <bors@rust-lang.org>2019-10-20 14:07:46 +0000
commit89e645ace853d86e8c0002247482eac9073c90fd (patch)
tree7b52eb4ca8e821ef521a8ae45a82746f7e85edc8 /src/libstd
parent857a55b8f0a692cb2304ab7c062d9cc74122e516 (diff)
parentba42fc27fd8cd089fc101c9724c2c4326ada9a4b (diff)
downloadrust-89e645ace853d86e8c0002247482eac9073c90fd.tar.gz
rust-89e645ace853d86e8c0002247482eac9073c90fd.zip
Auto merge of #65622 - Centril:rollup-l8orba7, r=Centril
Rollup of 6 pull requests

Successful merges:

 - #64996 (Inline `ptr::null(_mut)` even in debug builds)
 - #65551 (Avoid realloc in `CString::new`)
 - #65593 (add test for calling non-const fn)
 - #65595 (move `parse_cfgspecs` to `rustc_interface`)
 - #65600 (Remove unneeded `ref` from docs)
 - #65602 (Fix plural mistake in emitter.rs)

Failed merges:

r? @ghost
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/ffi/c_str.rs26
-rw-r--r--src/libstd/lib.rs1
2 files changed, 26 insertions, 1 deletions
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 483f2ba52ec..6dcda986310 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -327,7 +327,31 @@ impl CString {
     /// [`NulError`]: struct.NulError.html
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, NulError> {
-        Self::_new(t.into())
+        trait SpecIntoVec {
+            fn into_vec(self) -> Vec<u8>;
+        }
+        impl<T: Into<Vec<u8>>> SpecIntoVec for T {
+            default fn into_vec(self) -> Vec<u8> {
+                self.into()
+            }
+        }
+        // Specialization for avoiding reallocation.
+        impl SpecIntoVec for &'_ [u8] {
+            fn into_vec(self) -> Vec<u8> {
+                let mut v = Vec::with_capacity(self.len() + 1);
+                v.extend(self);
+                v
+            }
+        }
+        impl SpecIntoVec for &'_ str {
+            fn into_vec(self) -> Vec<u8> {
+                let mut v = Vec::with_capacity(self.len() + 1);
+                v.extend(self.as_bytes());
+                v
+            }
+        }
+
+        Self::_new(SpecIntoVec::into_vec(t))
     }
 
     fn _new(bytes: Vec<u8>) -> Result<CString, NulError> {
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index af6cb656444..50a1226cc1d 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -297,6 +297,7 @@
 #![feature(slice_concat_ext)]
 #![feature(slice_internals)]
 #![feature(slice_patterns)]
+#![feature(specialization)]
 #![feature(staged_api)]
 #![feature(std_internals)]
 #![feature(stdsimd)]