]> git.lizzy.rs Git - rust.git/blobdiff - library/alloc/tests/boxed.rs
Rollup merge of #103876 - oli-obk:tait_implications, r=lcnr
[rust.git] / library / alloc / tests / boxed.rs
index 9e5123be989900f2809ca93a2471ed57509d1be4..af49826ff30a364f4a8d308a13521475e62ea5c5 100644 (file)
@@ -102,8 +102,18 @@ unsafe fn grow(
 
         let new_ptr = self.allocate(new_layout)?;
         if new_layout.size() > 0 {
-            new_ptr.as_mut_ptr().copy_from_nonoverlapping(ptr.as_ptr(), old_layout.size());
-            self.deallocate(ptr, old_layout);
+            // Safety: `new_ptr` is valid for writes and `ptr` for reads of
+            // `old_layout.size()`, because `new_layout.size() >=
+            // old_layout.size()` (which is an invariant that must be upheld by
+            // callers).
+            unsafe {
+                new_ptr.as_mut_ptr().copy_from_nonoverlapping(ptr.as_ptr(), old_layout.size());
+            }
+            // Safety: `ptr` is never used again is also an invariant which must
+            // be upheld by callers.
+            unsafe {
+                self.deallocate(ptr, old_layout);
+            }
         }
         Ok(new_ptr)
     }
@@ -114,12 +124,21 @@ unsafe fn grow_zeroed(
         old_layout: Layout,
         new_layout: Layout,
     ) -> Result<NonNull<[u8]>, AllocError> {
-        let new_ptr = self.grow(ptr, old_layout, new_layout)?;
+        // Safety: Invariants of `grow_zeroed` and `grow` are the same, and must
+        // be enforced by callers.
+        let new_ptr = unsafe { self.grow(ptr, old_layout, new_layout)? };
         if new_layout.size() > 0 {
             let old_size = old_layout.size();
             let new_size = new_layout.size();
             let raw_ptr = new_ptr.as_mut_ptr();
-            raw_ptr.add(old_size).write_bytes(0, new_size - old_size);
+            // Safety:
+            // - `grow` returned Ok, so the returned pointer must be valid for
+            //   `new_size` bytes
+            // - `new_size` must be larger than `old_size`, which is an
+            //   invariant which must be upheld by callers.
+            unsafe {
+                raw_ptr.add(old_size).write_bytes(0, new_size - old_size);
+            }
         }
         Ok(new_ptr)
     }
@@ -137,8 +156,18 @@ unsafe fn shrink(
 
         let new_ptr = self.allocate(new_layout)?;
         if new_layout.size() > 0 {
-            new_ptr.as_mut_ptr().copy_from_nonoverlapping(ptr.as_ptr(), new_layout.size());
-            self.deallocate(ptr, old_layout);
+            // Safety: `new_ptr` and `ptr` are valid for reads/writes of
+            // `new_layout.size()` because of the invariants of shrink, which
+            // include `new_layout.size()` being smaller than (or equal to)
+            // `old_layout.size()`.
+            unsafe {
+                new_ptr.as_mut_ptr().copy_from_nonoverlapping(ptr.as_ptr(), new_layout.size());
+            }
+            // Safety: `ptr` is never used again is also an invariant which must
+            // be upheld by callers.
+            unsafe {
+                self.deallocate(ptr, old_layout);
+            }
         }
         Ok(new_ptr)
     }