about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThe 8472 <git@infinite-source.de>2023-05-29 13:04:26 +0200
committerThe 8472 <git@infinite-source.de>2023-09-03 19:59:47 +0200
commit072b51cbb5b4ee39ae433b5f92a5952054e6caf3 (patch)
tree1928ec651000aecedab037303baecc4d04070bcb
parentc98070d522d8d12e61219f268ac377aceda30e92 (diff)
downloadrust-072b51cbb5b4ee39ae433b5f92a5952054e6caf3.tar.gz
rust-072b51cbb5b4ee39ae433b5f92a5952054e6caf3.zip
unchecked layout calculations when shrinking during in-place collect
Reduces the amount of emitted IR. RawVec has similar optimizations
-rw-r--r--library/alloc/src/vec/in_place_collect.rs14
1 files changed, 12 insertions, 2 deletions
diff --git a/library/alloc/src/vec/in_place_collect.rs b/library/alloc/src/vec/in_place_collect.rs
index 1f03f0d19ec..e4f96fd7640 100644
--- a/library/alloc/src/vec/in_place_collect.rs
+++ b/library/alloc/src/vec/in_place_collect.rs
@@ -267,10 +267,20 @@ where
         {
             let alloc = Global;
             unsafe {
-                let new_layout = Layout::array::<T>(dst_cap).unwrap();
+                // The old allocation exists, therefore it must have a valid layout.
+                let src_align = mem::align_of::<I::Src>();
+                let src_size = mem::size_of::<I::Src>().unchecked_mul(src_cap);
+                let old_layout = Layout::from_size_align_unchecked(src_size, src_align);
+
+                // The must be equal or smaller for in-place iteration to be possible
+                // therefore the new layout must be ≤ the old one and therefore valid.
+                let dst_align = mem::align_of::<T>();
+                let dst_size = mem::size_of::<T>().unchecked_mul(dst_cap);
+                let new_layout = Layout::from_size_align_unchecked(dst_size, dst_align);
+
                 let result = alloc.shrink(
                     NonNull::new_unchecked(dst_buf as *mut u8),
-                    Layout::array::<I::Src>(src_cap).unwrap(),
+                    old_layout,
                     new_layout,
                 );
                 let Ok(reallocated) = result else { handle_alloc_error(new_layout) };