diff options
| -rw-r--r-- | library/alloc/src/vec/in_place_collect.rs | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/library/alloc/src/vec/in_place_collect.rs b/library/alloc/src/vec/in_place_collect.rs index d174074902a..20ecc50c4b6 100644 --- a/library/alloc/src/vec/in_place_collect.rs +++ b/library/alloc/src/vec/in_place_collect.rs @@ -225,16 +225,18 @@ where } // The ownership of the allocation and the new `T` values is temporarily moved into `dst_guard`. - // This is safe because `forget_allocation_drop_remaining` immediately forgets the allocation + // This is safe because + // * `forget_allocation_drop_remaining` immediately forgets the allocation // before any panic can occur in order to avoid any double free, and then proceeds to drop // any remaining values at the tail of the source. + // * the shrink either panics without invalidating the allocation, aborts or + // succeeds. In the last case we disarm the guard. // // Note: This access to the source wouldn't be allowed by the TrustedRandomIteratorNoCoerce // contract (used by SpecInPlaceCollect below). But see the "O(1) collect" section in the // module documentation why this is ok anyway. let dst_guard = InPlaceDstBufDrop { ptr: dst_buf, len, cap: dst_cap }; src.forget_allocation_drop_remaining(); - mem::forget(dst_guard); // Adjust the allocation size if the source had a capacity in bytes that wasn't a multiple // of the destination type size. @@ -256,6 +258,8 @@ where } } + mem::forget(dst_guard); + let vec = unsafe { Vec::from_raw_parts(dst_buf, len, dst_cap) }; vec |
