diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index 7437b1e3c8a32..b3be3d09f17da 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -53,9 +53,7 @@ fn prepare_lto(cgcx: &CodegenContext, let symbol_filter = &|&(ref name, level): &(String, SymbolExportLevel)| { if level.is_below_threshold(export_threshold) { - let mut bytes = Vec::with_capacity(name.len() + 1); - bytes.extend(name.bytes()); - Some(CString::new(bytes).unwrap()) + Some(CString::new(name.as_str()).unwrap()) } else { None } diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 483f2ba52eca6..6dcda98631014 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: T) -> Result { - Self::_new(t.into()) + trait SpecIntoVec { + fn into_vec(self) -> Vec; + } + impl>> SpecIntoVec for T { + default fn into_vec(self) -> Vec { + self.into() + } + } + // Specialization for avoiding reallocation. + impl SpecIntoVec for &'_ [u8] { + fn into_vec(self) -> Vec { + let mut v = Vec::with_capacity(self.len() + 1); + v.extend(self); + v + } + } + impl SpecIntoVec for &'_ str { + fn into_vec(self) -> Vec { + 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) -> Result { diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index af6cb656444d4..50a1226cc1d07 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)]