@@ -2199,19 +2199,11 @@ impl<T> SpecFromIter<T, IntoIter<T>> for Vec<T> {
2199
2199
// But it is a conservative choice.
2200
2200
let has_advanced = iterator. buf . as_ptr ( ) as * const _ != iterator. ptr ;
2201
2201
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 ( ) ;
2209
2203
}
2210
2204
2211
2205
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) ;
2215
2207
vec
2216
2208
}
2217
2209
}
@@ -2391,11 +2383,12 @@ where
2391
2383
}
2392
2384
2393
2385
impl < 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 ;
2397
2390
}
2398
- iterator. ptr = iterator . end ;
2391
+ iterator. move_to ( self ) ;
2399
2392
}
2400
2393
}
2401
2394
@@ -2928,6 +2921,23 @@ impl<T> IntoIter<T> {
2928
2921
self . ptr = self . buf . as_ptr ( ) ;
2929
2922
self . end = self . buf . as_ptr ( ) ;
2930
2923
}
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
+ }
2931
2941
}
2932
2942
2933
2943
#[ stable( feature = "vec_intoiter_as_ref" , since = "1.46.0" ) ]
0 commit comments