@@ -2121,9 +2121,9 @@ where
2121
2121
return SpecFromNested :: from_iter ( iterator) ;
2122
2122
}
2123
2123
2124
- let ( src_buf, src_end) = {
2124
+ let ( src_buf, src_end, cap ) = {
2125
2125
let inner = unsafe { iterator. as_inner ( ) . as_into_iter ( ) } ;
2126
- ( inner. buf . as_ptr ( ) , inner. end )
2126
+ ( inner. buf . as_ptr ( ) , inner. end , inner . cap )
2127
2127
} ;
2128
2128
let dst = src_buf;
2129
2129
@@ -2173,23 +2173,15 @@ where
2173
2173
debug_assert_eq ! ( src_buf, src. buf. as_ptr( ) ) ;
2174
2174
debug_assert ! ( dst as * const _ <= src. ptr, "InPlaceIterable contract violation" ) ;
2175
2175
2176
- if mem:: needs_drop :: < T > ( ) {
2177
- // drop tail if iterator was only partially exhausted
2178
- unsafe {
2179
- ptr:: drop_in_place ( src. as_mut_slice ( ) ) ;
2180
- }
2181
- }
2176
+ // drop any remaining values at the tail of the source
2177
+ src. drop_in_place ( ) ;
2178
+ // but prevent drop of the allocation itself once IntoIter goes out of scope
2179
+ src. forget_in_place ( ) ;
2182
2180
2183
2181
let vec = unsafe {
2184
2182
let len = dst. offset_from ( src_buf) as usize ;
2185
- Vec :: from_raw_parts ( src . buf . as_ptr ( ) , len, src . cap )
2183
+ Vec :: from_raw_parts ( src_buf , len, cap)
2186
2184
} ;
2187
- // prevent drop of the underlying storage by turning the IntoIter into
2188
- // the equivalent of Vec::new().into_iter()
2189
- src. cap = 0 ;
2190
- src. buf = unsafe { NonNull :: new_unchecked ( RawVec :: NEW . ptr ( ) ) } ;
2191
- src. ptr = src. buf . as_ptr ( ) ;
2192
- src. end = src. buf . as_ptr ( ) ;
2193
2185
2194
2186
vec
2195
2187
}
@@ -2705,6 +2697,24 @@ impl<T> IntoIter<T> {
2705
2697
pub fn as_mut_slice ( & mut self ) -> & mut [ T ] {
2706
2698
unsafe { slice:: from_raw_parts_mut ( self . ptr as * mut T , self . len ( ) ) }
2707
2699
}
2700
+
2701
+ fn drop_in_place ( & mut self ) {
2702
+ if mem:: needs_drop :: < T > ( ) {
2703
+ unsafe {
2704
+ ptr:: drop_in_place ( self . as_mut_slice ( ) ) ;
2705
+ }
2706
+ }
2707
+ self . ptr = self . end ;
2708
+ }
2709
+
2710
+ /// Relinquishes the backing allocation, equivalent to
2711
+ /// `ptr::write(&mut self, Vec::new().into_iter())`
2712
+ fn forget_in_place ( & mut self ) {
2713
+ self . cap = 0 ;
2714
+ self . buf = unsafe { NonNull :: new_unchecked ( RawVec :: NEW . ptr ( ) ) } ;
2715
+ self . ptr = self . buf . as_ptr ( ) ;
2716
+ self . end = self . buf . as_ptr ( ) ;
2717
+ }
2708
2718
}
2709
2719
2710
2720
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
0 commit comments