From 2f27236745fab41c73450cdb31cdf9d0db502dda Mon Sep 17 00:00:00 2001
From: Jed Brown <jed@jedbrown.org>
Date: Thu, 13 Feb 2025 09:13:33 -0700
Subject: [PATCH] alloc boxed: docs: use MaybeUninit::write instead of
 as_mut_ptr

In the deferred initialization pattern, the docs were needlessly going
through as_mut_ptr().write() to initialize, which is unnecessary use of
a pointer, needs to be inside an unsafe block, and may weaken alias
analysis.
---
 library/alloc/src/boxed.rs | 128 +++++++++++++------------------------
 1 file changed, 44 insertions(+), 84 deletions(-)

diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 8b38e6fc259af..60e46dc7a09cf 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -280,13 +280,9 @@ impl<T> Box<T> {
     ///
     /// ```
     /// let mut five = Box::<u32>::new_uninit();
-    ///
-    /// let five = unsafe {
-    ///     // Deferred initialization:
-    ///     five.as_mut_ptr().write(5);
-    ///
-    ///     five.assume_init()
-    /// };
+    /// // Deferred initialization:
+    /// five.write(5);
+    /// let five = unsafe { five.assume_init() };
     ///
     /// assert_eq!(*five, 5)
     /// ```
@@ -367,13 +363,9 @@ impl<T> Box<T> {
     /// #![feature(allocator_api)]
     ///
     /// let mut five = Box::<u32>::try_new_uninit()?;
-    ///
-    /// let five = unsafe {
-    ///     // Deferred initialization:
-    ///     five.as_mut_ptr().write(5);
-    ///
-    ///     five.assume_init()
-    /// };
+    /// // Deferred initialization:
+    /// five.write(5);
+    /// let five = unsafe { five.assume_init() };
     ///
     /// assert_eq!(*five, 5);
     /// # Ok::<(), std::alloc::AllocError>(())
@@ -435,10 +427,8 @@ impl<T, A: Allocator> Box<T, A> {
         A: Allocator,
     {
         let mut boxed = Self::new_uninit_in(alloc);
-        unsafe {
-            boxed.as_mut_ptr().write(x);
-            boxed.assume_init()
-        }
+        boxed.write(x);
+        unsafe { boxed.assume_init() }
     }
 
     /// Allocates memory in the given allocator then places `x` into it,
@@ -463,10 +453,8 @@ impl<T, A: Allocator> Box<T, A> {
         A: Allocator,
     {
         let mut boxed = Self::try_new_uninit_in(alloc)?;
-        unsafe {
-            boxed.as_mut_ptr().write(x);
-            Ok(boxed.assume_init())
-        }
+        boxed.write(x);
+        unsafe { Ok(boxed.assume_init()) }
     }
 
     /// Constructs a new box with uninitialized contents in the provided allocator.
@@ -479,13 +467,9 @@ impl<T, A: Allocator> Box<T, A> {
     /// use std::alloc::System;
     ///
     /// let mut five = Box::<u32, _>::new_uninit_in(System);
-    ///
-    /// let five = unsafe {
-    ///     // Deferred initialization:
-    ///     five.as_mut_ptr().write(5);
-    ///
-    ///     five.assume_init()
-    /// };
+    /// // Deferred initialization:
+    /// five.write(5);
+    /// let five = unsafe { five.assume_init() };
     ///
     /// assert_eq!(*five, 5)
     /// ```
@@ -517,13 +501,9 @@ impl<T, A: Allocator> Box<T, A> {
     /// use std::alloc::System;
     ///
     /// let mut five = Box::<u32, _>::try_new_uninit_in(System)?;
-    ///
-    /// let five = unsafe {
-    ///     // Deferred initialization:
-    ///     five.as_mut_ptr().write(5);
-    ///
-    ///     five.assume_init()
-    /// };
+    /// // Deferred initialization:
+    /// five.write(5);
+    /// let five = unsafe { five.assume_init() };
     ///
     /// assert_eq!(*five, 5);
     /// # Ok::<(), std::alloc::AllocError>(())
@@ -669,15 +649,11 @@ impl<T> Box<[T]> {
     ///
     /// ```
     /// let mut values = Box::<[u32]>::new_uninit_slice(3);
-    ///
-    /// let values = unsafe {
-    ///     // Deferred initialization:
-    ///     values[0].as_mut_ptr().write(1);
-    ///     values[1].as_mut_ptr().write(2);
-    ///     values[2].as_mut_ptr().write(3);
-    ///
-    ///     values.assume_init()
-    /// };
+    /// // Deferred initialization:
+    /// values[0].write(1);
+    /// values[1].write(2);
+    /// values[2].write(3);
+    /// let values = unsafe {values.assume_init() };
     ///
     /// assert_eq!(*values, [1, 2, 3])
     /// ```
@@ -722,13 +698,11 @@ impl<T> Box<[T]> {
     /// #![feature(allocator_api)]
     ///
     /// let mut values = Box::<[u32]>::try_new_uninit_slice(3)?;
-    /// let values = unsafe {
-    ///     // Deferred initialization:
-    ///     values[0].as_mut_ptr().write(1);
-    ///     values[1].as_mut_ptr().write(2);
-    ///     values[2].as_mut_ptr().write(3);
-    ///     values.assume_init()
-    /// };
+    /// // Deferred initialization:
+    /// values[0].write(1);
+    /// values[1].write(2);
+    /// values[2].write(3);
+    /// let values = unsafe { values.assume_init() };
     ///
     /// assert_eq!(*values, [1, 2, 3]);
     /// # Ok::<(), std::alloc::AllocError>(())
@@ -814,15 +788,11 @@ impl<T, A: Allocator> Box<[T], A> {
     /// use std::alloc::System;
     ///
     /// let mut values = Box::<[u32], _>::new_uninit_slice_in(3, System);
-    ///
-    /// let values = unsafe {
-    ///     // Deferred initialization:
-    ///     values[0].as_mut_ptr().write(1);
-    ///     values[1].as_mut_ptr().write(2);
-    ///     values[2].as_mut_ptr().write(3);
-    ///
-    ///     values.assume_init()
-    /// };
+    /// // Deferred initialization:
+    /// values[0].write(1);
+    /// values[1].write(2);
+    /// values[2].write(3);
+    /// let values = unsafe { values.assume_init() };
     ///
     /// assert_eq!(*values, [1, 2, 3])
     /// ```
@@ -873,13 +843,11 @@ impl<T, A: Allocator> Box<[T], A> {
     /// use std::alloc::System;
     ///
     /// let mut values = Box::<[u32], _>::try_new_uninit_slice_in(3, System)?;
-    /// let values = unsafe {
-    ///     // Deferred initialization:
-    ///     values[0].as_mut_ptr().write(1);
-    ///     values[1].as_mut_ptr().write(2);
-    ///     values[2].as_mut_ptr().write(3);
-    ///     values.assume_init()
-    /// };
+    /// // Deferred initialization:
+    /// values[0].write(1);
+    /// values[1].write(2);
+    /// values[2].write(3);
+    /// let values = unsafe { values.assume_init() };
     ///
     /// assert_eq!(*values, [1, 2, 3]);
     /// # Ok::<(), std::alloc::AllocError>(())
@@ -959,13 +927,9 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
     ///
     /// ```
     /// let mut five = Box::<u32>::new_uninit();
-    ///
-    /// let five: Box<u32> = unsafe {
-    ///     // Deferred initialization:
-    ///     five.as_mut_ptr().write(5);
-    ///
-    ///     five.assume_init()
-    /// };
+    /// // Deferred initialization:
+    /// five.write(5);
+    /// let five: Box<u32> = unsafe { five.assume_init() };
     ///
     /// assert_eq!(*five, 5)
     /// ```
@@ -1030,15 +994,11 @@ impl<T, A: Allocator> Box<[mem::MaybeUninit<T>], A> {
     ///
     /// ```
     /// let mut values = Box::<[u32]>::new_uninit_slice(3);
-    ///
-    /// let values = unsafe {
-    ///     // Deferred initialization:
-    ///     values[0].as_mut_ptr().write(1);
-    ///     values[1].as_mut_ptr().write(2);
-    ///     values[2].as_mut_ptr().write(3);
-    ///
-    ///     values.assume_init()
-    /// };
+    /// // Deferred initialization:
+    /// values[0].write(1);
+    /// values[1].write(2);
+    /// values[2].write(3);
+    /// let values = unsafe { values.assume_init() };
     ///
     /// assert_eq!(*values, [1, 2, 3])
     /// ```