@@ -1097,6 +1097,21 @@ impl String {
10971097 self . vec . extend_from_slice ( string. as_bytes ( ) )
10981098 }
10991099
1100+ #[ inline]
1101+ fn push_str_slice ( & mut self , slice : & [ & str ] ) {
1102+ let additional = slice. iter ( ) . map ( |x| x. len ( ) ) . sum ( ) ;
1103+ self . reserve ( additional) ;
1104+ let ( ptr, len, cap) = core:: mem:: take ( self ) . into_raw_parts ( ) ;
1105+ unsafe {
1106+ let mut dst = ptr. add ( len) ;
1107+ for new in slice {
1108+ core:: ptr:: copy_nonoverlapping ( new. as_ptr ( ) , dst, new. len ( ) ) ;
1109+ dst = dst. add ( new. len ( ) ) ;
1110+ }
1111+ * self = String :: from_raw_parts ( ptr, len + additional, cap) ;
1112+ }
1113+ }
1114+
11001115 /// Copies elements from `src` range to the end of the string.
11011116 ///
11021117 /// # Panics
@@ -2489,7 +2504,7 @@ impl<'a> Extend<&'a char> for String {
24892504#[ stable( feature = "rust1" , since = "1.0.0" ) ]
24902505impl < ' a > Extend < & ' a str > for String {
24912506 fn extend < I : IntoIterator < Item = & ' a str > > ( & mut self , iter : I ) {
2492- iter . into_iter ( ) . for_each ( move |s| self . push_str ( s ) ) ;
2507+ < I as SpecExtendStr > :: spec_extend_into ( iter , self )
24932508 }
24942509
24952510 #[ inline]
@@ -2498,6 +2513,32 @@ impl<'a> Extend<&'a str> for String {
24982513 }
24992514}
25002515
2516+ #[ cfg( not( no_global_oom_handling) ) ]
2517+ trait SpecExtendStr {
2518+ fn spec_extend_into ( self , s : & mut String ) ;
2519+ }
2520+
2521+ #[ cfg( not( no_global_oom_handling) ) ]
2522+ impl < ' a , T : IntoIterator < Item = & ' a str > > SpecExtendStr for T {
2523+ default fn spec_extend_into ( self , target : & mut String ) {
2524+ self . into_iter ( ) . for_each ( move |s| target. push_str ( s) ) ;
2525+ }
2526+ }
2527+
2528+ #[ cfg( not( no_global_oom_handling) ) ]
2529+ impl SpecExtendStr for [ & str ] {
2530+ fn spec_extend_into ( self , target : & mut String ) {
2531+ target. push_str_slice ( & self ) ;
2532+ }
2533+ }
2534+
2535+ #[ cfg( not( no_global_oom_handling) ) ]
2536+ impl < const N : usize > SpecExtendStr for [ & str ; N ] {
2537+ fn spec_extend_into ( self , target : & mut String ) {
2538+ target. push_str_slice ( & self [ ..] ) ;
2539+ }
2540+ }
2541+
25012542#[ cfg( not( no_global_oom_handling) ) ]
25022543#[ stable( feature = "box_str2" , since = "1.45.0" ) ]
25032544impl < A : Allocator > Extend < Box < str , A > > for String {
0 commit comments