@@ -138,7 +138,7 @@ use core::iter::{InPlaceIterable, SourceIter, TrustedRandomAccessNoCoerce};
138138use core:: mem:: { self , ManuallyDrop } ;
139139use core:: ptr:: { self } ;
140140
141- use super :: { InPlaceDrop , SpecFromIter , SpecFromIterNested , Vec } ;
141+ use super :: { InPlaceDrop , InPlaceDstBufDrop , SpecFromIter , SpecFromIterNested , Vec } ;
142142
143143/// Specialization marker for collecting an iterator pipeline into a Vec while reusing the
144144/// source allocation, i.e. executing the pipeline in place.
@@ -193,12 +193,16 @@ where
193193
194194 // Drop any remaining values at the tail of the source but prevent drop of the allocation
195195 // itself once IntoIter goes out of scope.
196- // If the drop panics then we also leak any elements collected into dst_buf.
196+ // If the drop panics then we also try to drop the destination buffer and its elements.
197+ // This is safe because `forget_allocation_drop_remaining` forgets the allocation *before*
198+ // trying to drop the remaining elements.
197199 //
198200 // Note: This access to the source wouldn't be allowed by the TrustedRandomIteratorNoCoerce
199201 // contract (used by SpecInPlaceCollect below). But see the "O(1) collect" section in the
200202 // module documenttation why this is ok anyway.
203+ let dst_guard = InPlaceDstBufDrop { ptr : dst_buf, len, cap } ;
201204 src. forget_allocation_drop_remaining ( ) ;
205+ mem:: forget ( dst_guard) ;
202206
203207 let vec = unsafe { Vec :: from_raw_parts ( dst_buf, len, cap) } ;
204208
0 commit comments