replace box_new in Box::new with write_via_move

requires lowering write_via_move during MIR building to make it just like an assignment
This commit is contained in:
Ralf Jung 2025-10-25 13:17:59 +02:00
parent 139651428d
commit 93d45480aa
12 changed files with 159 additions and 114 deletions

View file

@ -480,11 +480,15 @@ unsafe impl const Allocator for Global {
}
/// The allocator for `Box`.
///
/// # Safety
///
/// `size` and `align` must satisfy the conditions in [`Layout::from_size_align`].
#[cfg(not(no_global_oom_handling))]
#[lang = "exchange_malloc"]
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
pub(crate) unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
let layout = unsafe { Layout::from_size_align_unchecked(size, align) };
match Global.allocate(layout) {
Ok(ptr) => ptr.as_mut_ptr(),

View file

@ -206,7 +206,7 @@ use core::task::{Context, Poll};
#[cfg(not(no_global_oom_handling))]
use crate::alloc::handle_alloc_error;
use crate::alloc::{AllocError, Allocator, Global, Layout};
use crate::alloc::{AllocError, Allocator, Global, Layout, exchange_malloc};
use crate::raw_vec::RawVec;
#[cfg(not(no_global_oom_handling))]
use crate::str::from_boxed_utf8_unchecked;
@ -262,7 +262,15 @@ impl<T> Box<T> {
#[rustc_diagnostic_item = "box_new"]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn new(x: T) -> Self {
return box_new(x);
// SAFETY: the size and align of a valid type `T` are always valid for `Layout`.
let ptr = unsafe {
exchange_malloc(<T as SizedTypeProperties>::SIZE, <T as SizedTypeProperties>::ALIGN)
} as *mut T;
// Nothing below can panic so we do not have to worry about deallocating `ptr`.
// SAFETY: we just allocated the box to store `x`.
unsafe { core::intrinsics::write_via_move(ptr, x) };
// SAFETY: we just initialized `b`.
unsafe { mem::transmute(ptr) }
}
/// Constructs a new box with uninitialized contents.