parent
83e9b93c90
commit
1b587a6e76
@ -2643,14 +2643,41 @@ fn to_string(&self) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
// Generic/generated code can sometimes have multiple, nested references
|
||||||
#[cfg(not(no_global_oom_handling))]
|
// for strings, including `&&&str`s that would never be written
|
||||||
#[stable(feature = "str_to_string_specialization", since = "1.9.0")]
|
// by hand. This macro generates twelve layers of nested `&`-impl
|
||||||
impl ToString for str {
|
// for primitive strings.
|
||||||
#[inline]
|
macro_rules! to_string_str {
|
||||||
fn to_string(&self) -> String {
|
{type ; x $($x:ident)*} => {
|
||||||
String::from(self)
|
&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)]
|
#[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