7272//! This is handled by the [`InPlaceDrop`] guard for sink items (`U`) and by 
7373//! [`vec::IntoIter::forget_allocation_drop_remaining()`] for remaining source items (`T`). 
7474//! 
75- //! If dropping any remaining source item (`T`) panics then [`InPlaceDstBufDrop `] will handle dropping 
75+ //! If dropping any remaining source item (`T`) panics then [`InPlaceDstDataSrcBufDrop `] will handle dropping 
7676//! the already collected sink items (`U`) and freeing the allocation. 
7777//! 
7878//! [`vec::IntoIter::forget_allocation_drop_remaining()`]: super::IntoIter::forget_allocation_drop_remaining() 
@@ -158,17 +158,20 @@ use crate::alloc::{handle_alloc_error, Global};
158158use  core:: alloc:: Allocator ; 
159159use  core:: alloc:: Layout ; 
160160use  core:: iter:: { InPlaceIterable ,  SourceIter ,  TrustedRandomAccessNoCoerce } ; 
161+ use  core:: marker:: PhantomData ; 
161162use  core:: mem:: { self ,  ManuallyDrop ,  SizedTypeProperties } ; 
162163use  core:: num:: NonZeroUsize ; 
163164use  core:: ptr:: { self ,  NonNull } ; 
164165
165- use  super :: { InPlaceDrop ,  InPlaceDstBufDrop ,  SpecFromIter ,  SpecFromIterNested ,  Vec } ; 
166+ use  super :: { InPlaceDrop ,  InPlaceDstDataSrcBufDrop ,  SpecFromIter ,  SpecFromIterNested ,  Vec } ; 
166167
167168const  fn  in_place_collectible < DEST ,  SRC > ( 
168169    step_merge :  Option < NonZeroUsize > , 
169170    step_expand :  Option < NonZeroUsize > , 
170171)  -> bool  { 
171-     if  const  {  SRC :: IS_ZST  || DEST :: IS_ZST  || mem:: align_of :: < SRC > ( )  < mem:: align_of :: < DEST > ( )  }  { 
172+     // Require matching alignments because an alignment-changing realloc is inefficient on many 
173+     // system allocators and better implementations would require the unstable Allocator trait. 
174+     if  const  {  SRC :: IS_ZST  || DEST :: IS_ZST  || mem:: align_of :: < SRC > ( )  != mem:: align_of :: < DEST > ( )  }  { 
172175        return  false ; 
173176    } 
174177
@@ -188,7 +191,8 @@ const fn in_place_collectible<DEST, SRC>(
188191
189192const  fn  needs_realloc < SRC ,  DEST > ( src_cap :  usize ,  dst_cap :  usize )  -> bool  { 
190193    if  const  {  mem:: align_of :: < SRC > ( )  != mem:: align_of :: < DEST > ( )  }  { 
191-         return  src_cap > 0 ; 
194+         // FIXME: use unreachable! once that works in const 
195+         panic ! ( "in_place_collectible() prevents this" ) ; 
192196    } 
193197
194198    // If src type size is an integer multiple of the destination type size then 
@@ -262,7 +266,7 @@ where
262266            ) ; 
263267        } 
264268
265-         // The ownership of the allocation and the new `T` values is temporarily moved into `dst_guard`. 
269+         // The ownership of the source  allocation and the new `T` values is temporarily moved into `dst_guard`. 
266270        // This is safe because 
267271        // * `forget_allocation_drop_remaining` immediately forgets the allocation 
268272        // before any panic can occur in order to avoid any double free, and then proceeds to drop 
@@ -273,11 +277,12 @@ where
273277        // Note: This access to the source wouldn't be allowed by the TrustedRandomIteratorNoCoerce 
274278        // contract (used by SpecInPlaceCollect below). But see the "O(1) collect" section in the 
275279        // module documentation why this is ok anyway. 
276-         let  dst_guard = InPlaceDstBufDrop  {  ptr :  dst_buf,  len,  cap :  dst_cap } ; 
280+         let  dst_guard =
281+             InPlaceDstDataSrcBufDrop  {  ptr :  dst_buf,  len,  src_cap,  src :  PhantomData :: < I :: Src >  } ; 
277282        src. forget_allocation_drop_remaining ( ) ; 
278283
279-         // Adjust the allocation if the alignment didn't match or the  source had a capacity in bytes 
280-         // that wasn't a multiple  of the destination type size. 
284+         // Adjust the allocation if the source had a capacity in bytes that wasn't a multiple  
285+         // of the destination type size. 
281286        // Since the discrepancy should generally be small this should only result in some 
282287        // bookkeeping updates and no memmove. 
283288        if  needs_realloc :: < I :: Src ,  T > ( src_cap,  dst_cap)  { 
@@ -290,7 +295,7 @@ where
290295                let  src_size = mem:: size_of :: < I :: Src > ( ) . unchecked_mul ( src_cap) ; 
291296                let  old_layout = Layout :: from_size_align_unchecked ( src_size,  src_align) ; 
292297
293-                 // The must be equal or smaller for in-place iteration to be possible 
298+                 // The allocation  must be equal or smaller for in-place iteration to be possible 
294299                // therefore the new layout must be ≤ the old one and therefore valid. 
295300                let  dst_align = mem:: align_of :: < T > ( ) ; 
296301                let  dst_size = mem:: size_of :: < T > ( ) . unchecked_mul ( dst_cap) ; 
0 commit comments