File tree 2 files changed +71
-8
lines changed
2 files changed +71
-8
lines changed Original file line number Diff line number Diff line change @@ -2643,14 +2643,41 @@ impl ToString for i8 {
2643
2643
}
2644
2644
}
2645
2645
2646
- #[ doc( hidden) ]
2647
- #[ cfg( not( no_global_oom_handling) ) ]
2648
- #[ stable( feature = "str_to_string_specialization" , since = "1.9.0" ) ]
2649
- impl ToString for str {
2650
- #[ inline]
2651
- fn to_string ( & self ) -> String {
2652
- String :: from ( self )
2653
- }
2646
+ // Generic/generated code can sometimes have multiple, nested references
2647
+ // for strings, including `&&&str`s that would never be written
2648
+ // by hand. This macro generates twelve layers of nested `&`-impl
2649
+ // for primitive strings.
2650
+ macro_rules! to_string_str {
2651
+ { type ; x $( $x: ident) * } => {
2652
+ & to_string_str! { type ; $( $x) * }
2653
+ } ;
2654
+ { type ; } => { str } ;
2655
+ { impl ; x $( $x: ident) * } => {
2656
+ to_string_str! { $( $x) * }
2657
+ } ;
2658
+ { impl ; } => { } ;
2659
+ { $self: expr ; x $( $x: ident) * } => {
2660
+ * ( to_string_str! { $self ; $( $x) * } )
2661
+ } ;
2662
+ { $self: expr ; } => { $self } ;
2663
+ { $( $x: ident) * } => {
2664
+ #[ doc( hidden) ]
2665
+ #[ cfg( not( no_global_oom_handling) ) ]
2666
+ #[ stable( feature = "str_to_string_specialization" , since = "1.9.0" ) ]
2667
+ impl ToString for to_string_str!( type ; $( $x) * ) {
2668
+ #[ inline]
2669
+ fn to_string( & self ) -> String {
2670
+ String :: from( to_string_str!( self ; $( $x) * ) )
2671
+ }
2672
+ }
2673
+ to_string_str! { impl ; $( $x) * }
2674
+ } ;
2675
+ }
2676
+
2677
+ to_string_str ! {
2678
+ x x x x
2679
+ x x x x
2680
+ x x x x
2654
2681
}
2655
2682
2656
2683
#[ doc( hidden) ]
Original file line number Diff line number Diff line change
1
+ //@ compile-flags: -C opt-level=3 -Z merge-functions=disabled
2
+ #![ crate_type = "lib" ]
3
+
4
+ //! Make sure str::to_string is specialized not to use fmt machinery.
5
+
6
+ // CHECK-LABEL: define {{(dso_local )?}}void @one_ref
7
+ #[ no_mangle]
8
+ pub fn one_ref ( input : & str ) -> String {
9
+ // CHECK-NOT: {{(call|invoke).*}}fmt
10
+ input. to_string ( )
11
+ }
12
+
13
+ // CHECK-LABEL: define {{(dso_local )?}}void @two_ref
14
+ #[ no_mangle]
15
+ pub fn two_ref ( input : & & str ) -> String {
16
+ // CHECK-NOT: {{(call|invoke).*}}fmt
17
+ input. to_string ( )
18
+ }
19
+
20
+ // CHECK-LABEL: define {{(dso_local )?}}void @thirteen_ref
21
+ #[ no_mangle]
22
+ pub fn thirteen_ref ( input : & & & & & & & & & & & & & str ) -> String {
23
+ // CHECK-NOT: {{(call|invoke).*}}fmt
24
+ input. to_string ( )
25
+ }
26
+
27
+ // This is a known performance cliff because of the macro-generated
28
+ // specialized impl. If this test suddenly starts failing,
29
+ // consider removing the `to_string_str!` macro in `alloc/str/string.rs`.
30
+ //
31
+ // CHECK-LABEL: define {{(dso_local )?}}void @fourteen_ref
32
+ #[ no_mangle]
33
+ pub fn fourteen_ref ( input : & & & & & & & & & & & & & & str ) -> String {
34
+ // CHECK: {{(call|invoke).*}}fmt
35
+ input. to_string ( )
36
+ }
You can’t perform that action at this time.
0 commit comments