parent
83e9b93c90
commit
1b587a6e76
@ -2643,14 +2643,41 @@ fn to_string(&self) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[stable(feature = "str_to_string_specialization", since = "1.9.0")]
|
||||
impl ToString for str {
|
||||
#[inline]
|
||||
fn to_string(&self) -> String {
|
||||
String::from(self)
|
||||
}
|
||||
// Generic/generated code can sometimes have multiple, nested references
|
||||
// for strings, including `&&&str`s that would never be written
|
||||
// by hand. This macro generates twelve layers of nested `&`-impl
|
||||
// for primitive strings.
|
||||
macro_rules! to_string_str {
|
||||
{type ; x $($x:ident)*} => {
|
||||
&to_string_str! { type ; $($x)* }
|
||||
};
|
||||
{type ;} => { str };
|
||||
{impl ; x $($x:ident)*} => {
|
||||
to_string_str! { $($x)* }
|
||||
};
|
||||
{impl ;} => { };
|
||||
{$self:expr ; x $($x:ident)*} => {
|
||||
*(to_string_str! { $self ; $($x)* })
|
||||
};
|
||||
{$self:expr ;} => { $self };
|
||||
{$($x:ident)*} => {
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[stable(feature = "str_to_string_specialization", since = "1.9.0")]
|
||||
impl ToString for to_string_str!(type ; $($x)*) {
|
||||
#[inline]
|
||||
fn to_string(&self) -> String {
|
||||
String::from(to_string_str!(self ; $($x)*))
|
||||
}
|
||||
}
|
||||
to_string_str! { impl ; $($x)* }
|
||||
};
|
||||
}
|
||||
|
||||
to_string_str! {
|
||||
x x x x
|
||||
x x x x
|
||||
x x x x
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
36
tests/codegen/issues/str-to-string-128690.rs
Normal file
36
tests/codegen/issues/str-to-string-128690.rs
Normal file
@ -0,0 +1,36 @@
|
||||
//@ compile-flags: -C opt-level=3 -Z merge-functions=disabled
|
||||
#![crate_type = "lib"]
|
||||
|
||||
//! Make sure str::to_string is specialized not to use fmt machinery.
|
||||
|
||||
// CHECK-LABEL: define {{(dso_local )?}}void @one_ref
|
||||
#[no_mangle]
|
||||
pub fn one_ref(input: &str) -> String {
|
||||
// CHECK-NOT: {{(call|invoke).*}}fmt
|
||||
input.to_string()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define {{(dso_local )?}}void @two_ref
|
||||
#[no_mangle]
|
||||
pub fn two_ref(input: &&str) -> String {
|
||||
// CHECK-NOT: {{(call|invoke).*}}fmt
|
||||
input.to_string()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define {{(dso_local )?}}void @thirteen_ref
|
||||
#[no_mangle]
|
||||
pub fn thirteen_ref(input: &&&&&&&&&&&&&str) -> String {
|
||||
// CHECK-NOT: {{(call|invoke).*}}fmt
|
||||
input.to_string()
|
||||
}
|
||||
|
||||
// This is a known performance cliff because of the macro-generated
|
||||
// specialized impl. If this test suddenly starts failing,
|
||||
// consider removing the `to_string_str!` macro in `alloc/str/string.rs`.
|
||||
//
|
||||
// CHECK-LABEL: define {{(dso_local )?}}void @fourteen_ref
|
||||
#[no_mangle]
|
||||
pub fn fourteen_ref(input: &&&&&&&&&&&&&&str) -> String {
|
||||
// CHECK: {{(call|invoke).*}}fmt
|
||||
input.to_string()
|
||||
}
|
Loading…
Reference in New Issue
Block a user