@@ -2174,8 +2174,10 @@ impl<T> InPlaceDrop<T> {
2174
2174
impl < T > Drop for InPlaceDrop < T > {
2175
2175
#[ inline]
2176
2176
fn drop ( & mut self ) {
2177
- unsafe {
2178
- ptr:: drop_in_place ( slice:: from_raw_parts_mut ( self . inner , self . len ( ) ) ) ;
2177
+ if mem:: needs_drop :: < T > ( ) {
2178
+ unsafe {
2179
+ ptr:: drop_in_place ( slice:: from_raw_parts_mut ( self . inner , self . len ( ) ) ) ;
2180
+ }
2179
2181
}
2180
2182
}
2181
2183
}
@@ -2206,26 +2208,14 @@ impl<T> SpecFrom<T, IntoIter<T>> for Vec<T> {
2206
2208
}
2207
2209
}
2208
2210
2209
- fn write_in_place < T > ( src_end : * const T ) -> impl FnMut ( * mut T , T ) -> Result < * mut T , !> {
2210
- move |mut dst, item| {
2211
- unsafe {
2212
- // the InPlaceIterable contract cannot be verified precisely here since
2213
- // try_fold has an exclusive reference to the source pointer
2214
- // all we can do is check if it's still in range
2215
- debug_assert ! ( dst as * const _ <= src_end, "InPlaceIterable contract violation" ) ;
2216
- ptr:: write ( dst, item) ;
2217
- dst = dst. add ( 1 ) ;
2218
- }
2219
- Ok ( dst)
2220
- }
2221
- }
2222
-
2223
2211
fn write_in_place_with_drop < T > (
2224
2212
src_end : * const T ,
2225
2213
) -> impl FnMut ( InPlaceDrop < T > , T ) -> Result < InPlaceDrop < T > , !> {
2226
2214
move |mut sink, item| {
2227
2215
unsafe {
2228
- // same caveat as above
2216
+ // the InPlaceIterable contract cannot be verified precisely here since
2217
+ // try_fold has an exclusive reference to the source pointer
2218
+ // all we can do is check if it's still in range
2229
2219
debug_assert ! ( sink. dst as * const _ <= src_end, "InPlaceIterable contract violation" ) ;
2230
2220
ptr:: write ( sink. dst , item) ;
2231
2221
sink. dst = sink. dst . add ( 1 ) ;
@@ -2263,23 +2253,16 @@ where
2263
2253
( inner. buf . as_ptr ( ) , inner. buf . as_ptr ( ) as * mut T , inner. end as * const T , inner. cap )
2264
2254
} ;
2265
2255
2266
- // use try-fold
2256
+ // use try-fold since
2267
2257
// - it vectorizes better for some iterator adapters
2268
2258
// - unlike most internal iteration methods methods it only takes a &mut self
2269
- // - lets us thread the write pointer through its innards and get it back in the end
2270
- let dst = if mem:: needs_drop :: < T > ( ) {
2271
- // special-case drop handling since it forces us to lug that extra field around which
2272
- // can inhibit optimizations
2273
- let sink = InPlaceDrop { inner : dst_buf, dst : dst_buf } ;
2274
- let sink = iterator
2275
- . try_fold :: < _ , _ , Result < _ , !> > ( sink, write_in_place_with_drop ( dst_end) )
2276
- . unwrap ( ) ;
2277
- // iteration succeeded, don't drop head
2278
- let sink = mem:: ManuallyDrop :: new ( sink) ;
2279
- sink. dst
2280
- } else {
2281
- iterator. try_fold :: < _ , _ , Result < _ , !> > ( dst_buf, write_in_place ( dst_end) ) . unwrap ( )
2282
- } ;
2259
+ // - it lets us thread the write pointer through its innards and get it back in the end
2260
+ let sink = InPlaceDrop { inner : dst_buf, dst : dst_buf } ;
2261
+ let sink = iterator
2262
+ . try_fold :: < _ , _ , Result < _ , !> > ( sink, write_in_place_with_drop ( dst_end) )
2263
+ . unwrap ( ) ;
2264
+ // iteration succeeded, don't drop head
2265
+ let dst = mem:: ManuallyDrop :: new ( sink) . dst ;
2283
2266
2284
2267
let src = unsafe { iterator. as_inner ( ) . as_into_iter ( ) } ;
2285
2268
// check if SourceIter and InPlaceIterable contracts were upheld.
0 commit comments