@@ -2199,19 +2199,11 @@ impl<T> SpecFromIter<T, IntoIter<T>> for Vec<T> {
21992199 // But it is a conservative choice.
22002200 let has_advanced = iterator. buf . as_ptr ( ) as * const _ != iterator. ptr ;
22012201 if !has_advanced || iterator. len ( ) >= iterator. cap / 2 {
2202- unsafe {
2203- let it = ManuallyDrop :: new ( iterator) ;
2204- if has_advanced {
2205- ptr:: copy ( it. ptr , it. buf . as_ptr ( ) , it. len ( ) ) ;
2206- }
2207- return Vec :: from_raw_parts ( it. buf . as_ptr ( ) , it. len ( ) , it. cap ) ;
2208- }
2202+ return iterator. into_vec ( ) ;
22092203 }
22102204
22112205 let mut vec = Vec :: new ( ) ;
2212- // must delegate to spec_extend() since extend() itself delegates
2213- // to spec_from for empty Vecs
2214- vec. spec_extend ( iterator) ;
2206+ iterator. move_to ( & mut vec) ;
22152207 vec
22162208 }
22172209}
@@ -2391,11 +2383,12 @@ where
23912383}
23922384
23932385impl < T > SpecExtend < T , IntoIter < T > > for Vec < T > {
2394- fn spec_extend ( & mut self , mut iterator : IntoIter < T > ) {
2395- unsafe {
2396- self . append_elements ( iterator. as_slice ( ) as _ ) ;
2386+ fn spec_extend ( & mut self , iterator : IntoIter < T > ) {
2387+ if mem:: size_of :: < T > ( ) > 0 && self . len == 0 && self . capacity ( ) < iterator. len ( ) {
2388+ * self = iterator. into_vec ( ) ;
2389+ return ;
23972390 }
2398- iterator. ptr = iterator . end ;
2391+ iterator. move_to ( self ) ;
23992392 }
24002393}
24012394
@@ -2928,6 +2921,23 @@ impl<T> IntoIter<T> {
29282921 self . ptr = self . buf . as_ptr ( ) ;
29292922 self . end = self . buf . as_ptr ( ) ;
29302923 }
2924+
2925+ /// Shifts the remaining elements to the front and then converts the whole allocation to a Vec
2926+ fn into_vec ( self ) -> Vec < T > {
2927+ if self . ptr != self . buf . as_ptr ( ) as * const _ {
2928+ unsafe { ptr:: copy ( self . ptr , self . buf . as_ptr ( ) , self . len ( ) ) }
2929+ }
2930+
2931+ let iter = ManuallyDrop :: new ( self ) ;
2932+ unsafe { Vec :: from_raw_parts ( iter. buf . as_ptr ( ) , iter. len ( ) , iter. cap ) }
2933+ }
2934+
2935+ fn move_to ( mut self , dest : & mut Vec < T > ) {
2936+ unsafe {
2937+ dest. append_elements ( self . as_slice ( ) as _ ) ;
2938+ }
2939+ self . ptr = self . end ;
2940+ }
29312941}
29322942
29332943#[ stable( feature = "vec_intoiter_as_ref" , since = "1.46.0" ) ]
0 commit comments