From 1b587a6e76200fdd8364ef910246efa11c973e7b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 6 Aug 2024 14:33:14 -0700 Subject: alloc: add ToString specialization for `&&str` Fixes #128690 --- library/alloc/src/string.rs | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) (limited to 'library/alloc/src/string.rs') diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 124230812df..d943901e9ec 100644 --- a/library/alloc/src/string.rs +++ b/library/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)] -- cgit 1.4.1-3-g733a5 From 3312f5d65244b4ccb035be7b4c61541afc211914 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 7 Aug 2024 09:06:49 -0700 Subject: alloc: make `to_string_str!` a bit less complex --- library/alloc/src/string.rs | 57 ++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 22 deletions(-) (limited to 'library/alloc/src/string.rs') diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index d943901e9ec..e628be1546f 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -2647,37 +2647,50 @@ impl ToString for i8 { // 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)* } +#[cfg(not(no_global_oom_handling))] +macro_rules! to_string_str_wrap_in_ref { + {x $($x:ident)*} => { + &to_string_str_wrap_in_ref! { $($x)* } }; - {impl ;} => { }; + {} => { str }; +} +#[cfg(not(no_global_oom_handling))] +macro_rules! to_string_expr_wrap_in_deref { {$self:expr ; x $($x:ident)*} => { - *(to_string_str! { $self ; $($x)* }) + *(to_string_expr_wrap_in_deref! { $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)*)) +} +#[cfg(not(no_global_oom_handling))] +macro_rules! to_string_str { + {$($($x:ident)*),+} => { + $( + #[doc(hidden)] + #[stable(feature = "str_to_string_specialization", since = "1.9.0")] + impl ToString for to_string_str_wrap_in_ref!($($x)*) { + #[inline] + fn to_string(&self) -> String { + String::from(to_string_expr_wrap_in_deref!(self ; $($x)*)) + } } - } - to_string_str! { impl ; $($x)* } + )+ }; } +#[cfg(not(no_global_oom_handling))] to_string_str! { - x x x x - x x x x - x x x x + x x x x x x x x x x x x, + x x x x x x x x x x x, + x x x x x x x x x x, + x x x x x x x x x, + x x x x x x x x, + x x x x x x x, + x x x x x x, + x x x x x, + x x x x, + x x x, + x x, + x, } #[doc(hidden)] -- cgit 1.4.1-3-g733a5