@@ -1105,6 +1105,21 @@ impl String {
11051105 self . vec . extend_from_slice ( string. as_bytes ( ) )
11061106 }
11071107
1108+ #[ inline]
1109+ fn push_str_slice ( & mut self , slice : & [ & str ] ) {
1110+ let additional = slice. iter ( ) . map ( |x| x. len ( ) ) . sum ( ) ;
1111+ self . reserve ( additional) ;
1112+ let ( ptr, len, cap) = core:: mem:: take ( self ) . into_raw_parts ( ) ;
1113+ unsafe {
1114+ let mut dst = ptr. add ( len) ;
1115+ for new in slice {
1116+ core:: ptr:: copy_nonoverlapping ( new. as_ptr ( ) , dst, new. len ( ) ) ;
1117+ dst = dst. add ( new. len ( ) ) ;
1118+ }
1119+ * self = String :: from_raw_parts ( ptr, len + additional, cap) ;
1120+ }
1121+ }
1122+
11081123 /// Copies elements from `src` range to the end of the string.
11091124 ///
11101125 /// # Panics
@@ -2502,7 +2517,7 @@ impl<'a> Extend<&'a char> for String {
25022517#[ stable( feature = "rust1" , since = "1.0.0" ) ]
25032518impl < ' a > Extend < & ' a str > for String {
25042519 fn extend < I : IntoIterator < Item = & ' a str > > ( & mut self , iter : I ) {
2505- iter . into_iter ( ) . for_each ( move |s| self . push_str ( s ) ) ;
2520+ < I as SpecExtendStr > :: spec_extend_into ( iter , self )
25062521 }
25072522
25082523 #[ inline]
@@ -2511,6 +2526,32 @@ impl<'a> Extend<&'a str> for String {
25112526 }
25122527}
25132528
2529+ #[ cfg( not( no_global_oom_handling) ) ]
2530+ trait SpecExtendStr {
2531+ fn spec_extend_into ( self , s : & mut String ) ;
2532+ }
2533+
2534+ #[ cfg( not( no_global_oom_handling) ) ]
2535+ impl < ' a , T : IntoIterator < Item = & ' a str > > SpecExtendStr for T {
2536+ default fn spec_extend_into ( self , target : & mut String ) {
2537+ self . into_iter ( ) . for_each ( move |s| target. push_str ( s) ) ;
2538+ }
2539+ }
2540+
2541+ #[ cfg( not( no_global_oom_handling) ) ]
2542+ impl SpecExtendStr for [ & str ] {
2543+ fn spec_extend_into ( self , target : & mut String ) {
2544+ target. push_str_slice ( & self ) ;
2545+ }
2546+ }
2547+
2548+ #[ cfg( not( no_global_oom_handling) ) ]
2549+ impl < const N : usize > SpecExtendStr for [ & str ; N ] {
2550+ fn spec_extend_into ( self , target : & mut String ) {
2551+ target. push_str_slice ( & self [ ..] ) ;
2552+ }
2553+ }
2554+
25142555#[ cfg( not( no_global_oom_handling) ) ]
25152556#[ stable( feature = "box_str2" , since = "1.45.0" ) ]
25162557impl < A : Allocator > Extend < Box < str , A > > for String {
0 commit comments