Skip to content

Commit 16641f8

Browse files
committed
replace box_new in Box::new with write_via_move
1 parent ed34b6f commit 16641f8

File tree

4 files changed

+28
-11
lines changed

4 files changed

+28
-11
lines changed

library/alloc/src/alloc.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,11 +343,15 @@ unsafe impl Allocator for Global {
343343
}
344344

345345
/// The allocator for `Box`.
346+
///
347+
/// # Safety
348+
///
349+
/// `size` and `align` must satisfy the conditions in [`Layout::from_size_align`].
346350
#[cfg(not(no_global_oom_handling))]
347351
#[lang = "exchange_malloc"]
348352
#[inline]
349353
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
350-
unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
354+
pub(crate) unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
351355
let layout = unsafe { Layout::from_size_align_unchecked(size, align) };
352356
match Global.allocate(layout) {
353357
Ok(ptr) => ptr.as_mut_ptr(),

library/alloc/src/boxed.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ use core::task::{Context, Poll};
203203

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

265273
/// Constructs a new box with uninitialized contents.

tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@
213213
+ StorageLive(_42);
214214
+ _42 = Option::<()>::None;
215215
+ _35 = copy ((*_37).0: std::option::Option<()>);
216-
+ ((*_37).0: std::option::Option<()>) = copy _42;
216+
+ ((*_37).0: std::option::Option<()>) = move _42;
217217
+ StorageDead(_42);
218218
+ StorageLive(_43);
219219
+ _43 = discriminant(_35);
Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture
22
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
33
|
4-
= note: evaluation of `<[&usize; usize::MAX] as std::mem::SizedTypeProperties>::SIZE` failed here
4+
= note: evaluation of `<std::mem::MaybeUninit<[&usize; usize::MAX]> as std::mem::SizedTypeProperties>::SIZE` failed here
55

66
error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture
77
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
88
|
9-
= note: evaluation of `<[&usize; usize::MAX] as std::mem::SizedTypeProperties>::ALIGN` failed here
9+
= note: evaluation of `<std::mem::MaybeUninit<[&usize; usize::MAX]> as std::mem::SizedTypeProperties>::ALIGN` failed here
10+
11+
note: the above error was encountered while instantiating `fn Box::<[&usize; usize::MAX]>::new_uninit_in`
12+
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
1013

11-
note: the above error was encountered while instantiating `fn Box::<[&usize; usize::MAX]>::new`
12-
--> $DIR/issue-17913.rs:16:21
14+
error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture
15+
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
1316
|
14-
LL | let a: Box<_> = Box::new([&n; SIZE]);
15-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17+
= note: evaluation of `<[&usize; usize::MAX] as std::mem::SizedTypeProperties>::SIZE` failed here
18+
19+
note: the above error was encountered while instantiating `fn Box::<[&usize; usize::MAX]>::try_new_uninit_in`
20+
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
1621

17-
error: aborting due to 2 previous errors
22+
error: aborting due to 3 previous errors
1823

1924
For more information about this error, try `rustc --explain E0080`.

0 commit comments

Comments
 (0)