@@ -2121,9 +2121,9 @@ where
21212121 return SpecFromNested :: from_iter ( iterator) ;
21222122 }
21232123
2124- let ( src_buf, src_end) = {
2124+ let ( src_buf, src_end, cap ) = {
21252125 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 )
21272127 } ;
21282128 let dst = src_buf;
21292129
@@ -2173,23 +2173,15 @@ where
21732173 debug_assert_eq ! ( src_buf, src. buf. as_ptr( ) ) ;
21742174 debug_assert ! ( dst as * const _ <= src. ptr, "InPlaceIterable contract violation" ) ;
21752175
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 ( ) ;
21822180
21832181 let vec = unsafe {
21842182 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)
21862184 } ;
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 ( ) ;
21932185
21942186 vec
21952187 }
@@ -2705,6 +2697,24 @@ impl<T> IntoIter<T> {
27052697 pub fn as_mut_slice ( & mut self ) -> & mut [ T ] {
27062698 unsafe { slice:: from_raw_parts_mut ( self . ptr as * mut T , self . len ( ) ) }
27072699 }
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+ }
27082718}
27092719
27102720#[ stable( feature = "rust1" , since = "1.0.0" ) ]
0 commit comments