@@ -138,7 +138,7 @@ use core::iter::{InPlaceIterable, SourceIter, TrustedRandomAccessNoCoerce};
138
138
use core:: mem:: { self , ManuallyDrop } ;
139
139
use core:: ptr:: { self } ;
140
140
141
- use super :: { InPlaceDrop , SpecFromIter , SpecFromIterNested , Vec } ;
141
+ use super :: { InPlaceDrop , InPlaceDstBufDrop , SpecFromIter , SpecFromIterNested , Vec } ;
142
142
143
143
/// Specialization marker for collecting an iterator pipeline into a Vec while reusing the
144
144
/// source allocation, i.e. executing the pipeline in place.
@@ -193,12 +193,16 @@ where
193
193
194
194
// Drop any remaining values at the tail of the source but prevent drop of the allocation
195
195
// 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.
197
199
//
198
200
// Note: This access to the source wouldn't be allowed by the TrustedRandomIteratorNoCoerce
199
201
// contract (used by SpecInPlaceCollect below). But see the "O(1) collect" section in the
200
202
// module documenttation why this is ok anyway.
203
+ let dst_guard = InPlaceDstBufDrop { ptr : dst_buf, len, cap } ;
201
204
src. forget_allocation_drop_remaining ( ) ;
205
+ mem:: forget ( dst_guard) ;
202
206
203
207
let vec = unsafe { Vec :: from_raw_parts ( dst_buf, len, cap) } ;
204
208
0 commit comments