From bc13c6ca57adbb3e879994e6c6bea95cf51a472b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 6 Aug 2024 14:33:14 -0700 Subject: [PATCH] alloc: add ToString specialization for `&&str` Fixes #128690 --- alloc/src/string.rs | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/alloc/src/string.rs b/alloc/src/string.rs index 124230812df56..d943901e9ecf9 100644 --- a/alloc/src/string.rs +++ b/alloc/src/string.rs @@ -2643,14 +2643,41 @@ impl ToString for i8 { } } -#[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)]