@@ -445,11 +445,11 @@ impl Regex {
445445 if limit > 0 && i >= limit {
446446 break
447447 }
448- new . extend ( & text[ last_match..s] ) ;
449- new . extend ( & * rep) ;
448+ extend_from_slice ( & mut new , & text[ last_match..s] ) ;
449+ extend_from_slice ( & mut new , & * rep) ;
450450 last_match = e;
451451 }
452- new . extend ( & text[ last_match..] ) ;
452+ extend_from_slice ( & mut new , & text[ last_match..] ) ;
453453 return new;
454454 }
455455
@@ -463,11 +463,11 @@ impl Regex {
463463 }
464464 // unwrap on 0 is OK because captures only reports matches
465465 let ( s, e) = cap. pos ( 0 ) . unwrap ( ) ;
466- new . extend ( & text[ last_match..s] ) ;
466+ extend_from_slice ( & mut new , & text[ last_match..s] ) ;
467467 rep. replace_append ( & cap, & mut new) ;
468468 last_match = e;
469469 }
470- new . extend ( & text[ last_match..] ) ;
470+ extend_from_slice ( & mut new , & text[ last_match..] ) ;
471471 new
472472 }
473473
@@ -928,7 +928,7 @@ impl<'a> Replacer for &'a [u8] {
928928
929929impl < F > Replacer for F where F : FnMut ( & Captures ) -> Vec < u8 > {
930930 fn replace_append ( & mut self , caps : & Captures , dst : & mut Vec < u8 > ) {
931- dst. extend ( ( * self ) ( caps) )
931+ extend_from_slice ( dst, & ( * self ) ( caps) ) ;
932932 }
933933}
934934
@@ -944,10 +944,26 @@ pub struct NoExpand<'r>(pub &'r [u8]);
944944
945945impl < ' a > Replacer for NoExpand < ' a > {
946946 fn replace_append ( & mut self , _: & Captures , dst : & mut Vec < u8 > ) {
947- dst . extend ( self . 0 )
947+ extend_from_slice ( dst , self . 0 ) ;
948948 }
949949
950950 fn no_expansion < ' r > ( & ' r mut self ) -> Option < Cow < ' r , [ u8 ] > > {
951951 Some ( Cow :: Borrowed ( self . 0 ) )
952952 }
953953}
954+
955+ /// This hopefully has the same performance characteristics as
956+ /// Vec::extend_from_slice (which was introduced in Rust 1.6), but works on
957+ /// Rust 1.3.
958+ ///
959+ /// N.B. Remove this once we do a semver bump. At that point, we'll bump
960+ /// required Rust version to at least 1.6.
961+ fn extend_from_slice ( dst : & mut Vec < u8 > , src : & [ u8 ] ) {
962+ dst. reserve ( src. len ( ) ) ;
963+ let dst_len = dst. len ( ) ;
964+ unsafe { dst. set_len ( dst_len + src. len ( ) ) ; }
965+ let mut dst = & mut dst[ dst_len..dst_len + src. len ( ) ] ;
966+ for i in 0 ..src. len ( ) {
967+ dst[ i] = src[ i] ;
968+ }
969+ }
0 commit comments