@@ -2226,9 +2226,9 @@ where
2226
2226
return SpecFromNested :: from_iter ( iterator) ;
2227
2227
}
2228
2228
2229
- let ( src_buf, src_end) = {
2229
+ let ( src_buf, src_end, cap ) = {
2230
2230
let inner = unsafe { iterator. as_inner ( ) . as_into_iter ( ) } ;
2231
- ( inner. buf . as_ptr ( ) , inner. end )
2231
+ ( inner. buf . as_ptr ( ) , inner. end , inner . cap )
2232
2232
} ;
2233
2233
let dst = src_buf;
2234
2234
@@ -2278,23 +2278,15 @@ where
2278
2278
debug_assert_eq ! ( src_buf, src. buf. as_ptr( ) ) ;
2279
2279
debug_assert ! ( dst as * const _ <= src. ptr, "InPlaceIterable contract violation" ) ;
2280
2280
2281
- if mem:: needs_drop :: < T > ( ) {
2282
- // drop tail if iterator was only partially exhausted
2283
- unsafe {
2284
- ptr:: drop_in_place ( src. as_mut_slice ( ) ) ;
2285
- }
2286
- }
2281
+ // drop any remaining values at the tail of the source
2282
+ src. drop_in_place ( ) ;
2283
+ // but prevent drop of the allocation itself once IntoIter goes out of scope
2284
+ src. forget_in_place ( ) ;
2287
2285
2288
2286
let vec = unsafe {
2289
2287
let len = dst. offset_from ( src_buf) as usize ;
2290
- Vec :: from_raw_parts ( src . buf . as_ptr ( ) , len, src . cap )
2288
+ Vec :: from_raw_parts ( src_buf , len, cap)
2291
2289
} ;
2292
- // prevent drop of the underlying storage by turning the IntoIter into
2293
- // the equivalent of Vec::new().into_iter()
2294
- src. cap = 0 ;
2295
- src. buf = unsafe { NonNull :: new_unchecked ( RawVec :: NEW . ptr ( ) ) } ;
2296
- src. ptr = src. buf . as_ptr ( ) ;
2297
- src. end = src. buf . as_ptr ( ) ;
2298
2290
2299
2291
vec
2300
2292
}
@@ -2839,6 +2831,24 @@ impl<T> IntoIter<T> {
2839
2831
fn as_raw_mut_slice ( & mut self ) -> * mut [ T ] {
2840
2832
ptr:: slice_from_raw_parts_mut ( self . ptr as * mut T , self . len ( ) )
2841
2833
}
2834
+
2835
+ fn drop_in_place ( & mut self ) {
2836
+ if mem:: needs_drop :: < T > ( ) {
2837
+ unsafe {
2838
+ ptr:: drop_in_place ( self . as_mut_slice ( ) ) ;
2839
+ }
2840
+ }
2841
+ self . ptr = self . end ;
2842
+ }
2843
+
2844
+ /// Relinquishes the backing allocation, equivalent to
2845
+ /// `ptr::write(&mut self, Vec::new().into_iter())`
2846
+ fn forget_in_place ( & mut self ) {
2847
+ self . cap = 0 ;
2848
+ self . buf = unsafe { NonNull :: new_unchecked ( RawVec :: NEW . ptr ( ) ) } ;
2849
+ self . ptr = self . buf . as_ptr ( ) ;
2850
+ self . end = self . buf . as_ptr ( ) ;
2851
+ }
2842
2852
}
2843
2853
2844
2854
#[ stable( feature = "vec_intoiter_as_ref" , since = "1.46.0" ) ]
0 commit comments