Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 7 additions & 17 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,15 +237,14 @@ pub struct Box<
>(Unique<T>, A);

/// Monomorphic function for allocating an uninit `Box`.
///
/// # Safety
///
/// size and align need to be safe for `Layout::from_size_align_unchecked`.
#[inline]
// The is a separate function to avoid doing it in every generic version, but it
// looks small to the mir inliner (particularly in panic=abort) so leave it to
// the backend to decide whether pulling it in everywhere is worth doing.
#[rustc_no_mir_inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
#[cfg(not(no_global_oom_handling))]
unsafe fn box_new_uninit(size: usize, align: usize) -> *mut u8 {
let layout = unsafe { Layout::from_size_align_unchecked(size, align) };
fn box_new_uninit(layout: Layout) -> *mut u8 {
match Global.allocate(layout) {
Ok(ptr) => ptr.as_mut_ptr(),
Err(_) => handle_alloc_error(layout),
Expand Down Expand Up @@ -284,10 +283,7 @@ impl<T> Box<T> {
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn new(x: T) -> Self {
// This is `Box::new_uninit` but inlined to avoid build time regressions.
// SAFETY: The size and align of a valid type `T` are always valid for `Layout`.
let ptr = unsafe {
box_new_uninit(<T as SizedTypeProperties>::SIZE, <T as SizedTypeProperties>::ALIGN)
} as *mut T;
let ptr = box_new_uninit(<T as SizedTypeProperties>::LAYOUT) 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) };
Expand Down Expand Up @@ -317,14 +313,8 @@ impl<T> Box<T> {
// `Box::new`).

// SAFETY:
// - The size and align of a valid type `T` are always valid for `Layout`.
// - If `allocate` succeeds, the returned pointer exactly matches what `Box` needs.
unsafe {
mem::transmute(box_new_uninit(
<T as SizedTypeProperties>::SIZE,
<T as SizedTypeProperties>::ALIGN,
))
}
unsafe { mem::transmute(box_new_uninit(<T as SizedTypeProperties>::LAYOUT)) }
}

/// Constructs a new `Box` with uninitialized contents, with the memory
Expand Down
3 changes: 1 addition & 2 deletions tests/codegen-units/item-collection/opaque-return-impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ pub fn foo2() -> Box<dyn TestTrait2> {
//~ MONO_ITEM fn foo2
//~ MONO_ITEM fn std::alloc::Global::alloc_impl_runtime
//~ MONO_ITEM fn std::boxed::Box::<TestStruct2>::new
//~ MONO_ITEM fn std::alloc::Layout::from_size_align_unchecked::precondition_check
//~ MONO_ITEM fn std::ptr::Alignment::new_unchecked::precondition_check
//~ MONO_ITEM fn std::boxed::box_new_uninit
//~ MONO_ITEM fn std::ptr::NonNull::<T>::new_unchecked::precondition_check

struct Counter {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
let mut _10: std::boxed::Box<()>;
let mut _11: *const ();
let mut _14: usize;
let mut _15: usize;
let mut _24: usize;
scope 1 {
debug vp_ctx => _1;
let _5: *const ();
Expand All @@ -26,12 +24,12 @@
scope 4 {
debug _x => _8;
}
scope 20 (inlined foo) {
let mut _25: *const [()];
scope 9 (inlined foo) {
let mut _15: *const [()];
}
}
scope 18 (inlined slice_from_raw_parts::<()>) {
scope 19 (inlined std::ptr::from_raw_parts::<[()], ()>) {
scope 7 (inlined slice_from_raw_parts::<()>) {
scope 8 (inlined std::ptr::from_raw_parts::<[()], ()>) {
}
}
}
Expand All @@ -41,36 +39,6 @@
let mut _13: *mut u8;
scope 6 {
}
scope 7 (inlined boxed::box_new_uninit) {
let _16: std::alloc::Layout;
let mut _17: std::result::Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError>;
let mut _18: isize;
let mut _20: !;
scope 8 {
let _19: std::ptr::NonNull<[u8]>;
scope 9 {
scope 13 (inlined NonNull::<[u8]>::as_mut_ptr) {
scope 14 (inlined NonNull::<[u8]>::as_non_null_ptr) {
scope 15 (inlined NonNull::<[u8]>::cast::<u8>) {
let mut _23: *mut [u8];
scope 16 (inlined NonNull::<[u8]>::as_ptr) {
}
}
}
scope 17 (inlined NonNull::<u8>::as_ptr) {
}
}
}
scope 11 (inlined <std::alloc::Global as Allocator>::allocate) {
scope 12 (inlined std::alloc::Global::alloc_impl) {
}
}
}
scope 10 (inlined #[track_caller] Layout::from_size_align_unchecked) {
let _21: ();
let mut _22: std::ptr::Alignment;
}
}
}

bb0: {
Expand All @@ -82,18 +50,7 @@
+ _4 = const ();
StorageLive(_12);
StorageLive(_13);
StorageLive(_14);
- _14 = const <() as std::mem::SizedTypeProperties>::SIZE;
+ _14 = const 0_usize;
StorageLive(_15);
- _15 = const <() as std::mem::SizedTypeProperties>::ALIGN;
+ _15 = const 1_usize;
StorageLive(_16);
StorageLive(_18);
StorageLive(_19);
StorageLive(_20);
StorageLive(_21);
switchInt(UbChecks) -> [0: bb6, otherwise: bb5];
_13 = boxed::box_new_uninit(const <() as std::mem::SizedTypeProperties>::LAYOUT) -> [return: bb2, unwind unreachable];
}

bb1: {
Expand All @@ -103,33 +60,8 @@
}

bb2: {
unreachable;
}

bb3: {
- _20 = handle_alloc_error(move _16) -> unwind unreachable;
+ _20 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> unwind unreachable;
}

bb4: {
_19 = copy ((_17 as Ok).0: std::ptr::NonNull<[u8]>);
- StorageLive(_23);
+ nop;
_23 = copy _19 as *mut [u8] (Transmute);
_13 = copy _23 as *mut u8 (PtrToPtr);
- StorageDead(_23);
+ nop;
StorageDead(_17);
StorageDead(_21);
StorageDead(_20);
StorageDead(_19);
StorageDead(_18);
StorageDead(_16);
StorageDead(_15);
StorageDead(_14);
- _12 = copy _13 as *mut () (PtrToPtr);
_12 = copy _13 as *mut () (PtrToPtr);
- (*_12) = move _4;
+ _12 = copy _23 as *mut () (PtrToPtr);
+ (*_12) = const ();
_3 = copy _13 as std::boxed::Box<()> (Transmute);
StorageDead(_13);
Expand All @@ -147,21 +79,21 @@
+ nop;
StorageLive(_7);
_7 = copy _5;
StorageLive(_24);
_24 = const 1_usize;
- _6 = *const [()] from (copy _7, copy _24);
StorageLive(_14);
_14 = const 1_usize;
- _6 = *const [()] from (copy _7, copy _14);
+ _6 = *const [()] from (copy _5, const 1_usize);
StorageDead(_24);
StorageDead(_14);
StorageDead(_7);
StorageLive(_8);
StorageLive(_9);
_9 = copy _6;
StorageLive(_25);
- _25 = copy _9;
StorageLive(_15);
- _15 = copy _9;
- _8 = copy _9 as *mut () (PtrToPtr);
+ _25 = copy _6;
+ _15 = copy _6;
+ _8 = copy _5 as *mut () (PtrToPtr);
StorageDead(_25);
StorageDead(_15);
StorageDead(_9);
_0 = const ();
StorageDead(_8);
Expand All @@ -171,31 +103,5 @@
+ nop;
drop(_3) -> [return: bb1, unwind unreachable];
}

bb5: {
- _21 = Layout::from_size_align_unchecked::precondition_check(copy _14, copy _15) -> [return: bb6, unwind unreachable];
+ _21 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable];
}

bb6: {
StorageLive(_22);
- _22 = copy _15 as std::ptr::Alignment (Transmute);
- _16 = Layout { size: copy _14, align: move _22 };
+ _22 = const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }};
+ _16 = const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }};
StorageDead(_22);
StorageLive(_17);
- _17 = std::alloc::Global::alloc_impl_runtime(copy _16, const false) -> [return: bb7, unwind unreachable];
+ _17 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}, const false) -> [return: bb7, unwind unreachable];
}

bb7: {
_18 = discriminant(_17);
switchInt(move _18) -> [0: bb4, 1: bb3, otherwise: bb2];
}
+ }
+
+ ALLOC0 (size: 8, align: 4) {
+ 01 00 00 00 00 00 00 00 │ ........
}

Loading
Loading