about summary refs log tree commit diff
path: root/library/alloc/src/string.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/alloc/src/string.rs')
-rw-r--r--library/alloc/src/string.rs43
1 files changed, 35 insertions, 8 deletions
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)]