@@ -2174,8 +2174,10 @@ impl<T> InPlaceDrop<T> {
21742174impl < T > Drop for InPlaceDrop < T > {
21752175 #[ inline]
21762176 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+ }
21792181 }
21802182 }
21812183}
@@ -2206,26 +2208,14 @@ impl<T> SpecFrom<T, IntoIter<T>> for Vec<T> {
22062208 }
22072209}
22082210
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-
22232211fn write_in_place_with_drop < T > (
22242212 src_end : * const T ,
22252213) -> impl FnMut ( InPlaceDrop < T > , T ) -> Result < InPlaceDrop < T > , !> {
22262214 move |mut sink, item| {
22272215 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
22292219 debug_assert ! ( sink. dst as * const _ <= src_end, "InPlaceIterable contract violation" ) ;
22302220 ptr:: write ( sink. dst , item) ;
22312221 sink. dst = sink. dst . add ( 1 ) ;
@@ -2263,23 +2253,16 @@ where
22632253 ( inner. buf . as_ptr ( ) , inner. buf . as_ptr ( ) as * mut T , inner. end as * const T , inner. cap )
22642254 } ;
22652255
2266- // use try-fold
2256+ // use try-fold since
22672257 // - it vectorizes better for some iterator adapters
22682258 // - 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 ;
22832266
22842267 let src = unsafe { iterator. as_inner ( ) . as_into_iter ( ) } ;
22852268 // check if SourceIter and InPlaceIterable contracts were upheld.
0 commit comments