From 1b767bf623c48dc3e2a1e8c14c68ec2d2deea08b Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Mon, 16 Feb 2026 16:39:32 -0800 Subject: [PATCH 1/2] Just pass `Layout` directly to `box_new_uninit` We have a constant for it already (used in `RawVec` for basically the same polymorphization) so let's use it. Conveniently, it can even be safe that way! --- library/alloc/src/boxed.rs | 20 +-- .../item-collection/opaque-return-impls.rs | 2 - ...ng_operand.test.GVN.32bit.panic-abort.diff | 121 +++++++----------- ...ng_operand.test.GVN.64bit.panic-abort.diff | 121 +++++++----------- tests/ui/limits/issue-17913.32bit.stderr | 7 +- tests/ui/limits/issue-17913.64bit.stderr | 7 +- tests/ui/limits/issue-17913.rs | 1 - 7 files changed, 95 insertions(+), 184 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 221375baa2b6b..8b05464334914 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -237,15 +237,10 @@ pub struct Box< >(Unique, A); /// Monomorphic function for allocating an uninit `Box`. -/// -/// # Safety -/// -/// size and align need to be safe for `Layout::from_size_align_unchecked`. #[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), @@ -284,10 +279,7 @@ impl Box { #[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(::SIZE, ::ALIGN) - } as *mut T; + let ptr = box_new_uninit(::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) }; @@ -317,14 +309,8 @@ impl Box { // `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( - ::SIZE, - ::ALIGN, - )) - } + unsafe { mem::transmute(box_new_uninit(::LAYOUT)) } } /// Constructs a new `Box` with uninitialized contents, with the memory diff --git a/tests/codegen-units/item-collection/opaque-return-impls.rs b/tests/codegen-units/item-collection/opaque-return-impls.rs index a3f649a80e321..63ee9afe34ab9 100644 --- a/tests/codegen-units/item-collection/opaque-return-impls.rs +++ b/tests/codegen-units/item-collection/opaque-return-impls.rs @@ -45,8 +45,6 @@ pub fn foo2() -> Box { //~ MONO_ITEM fn foo2 //~ MONO_ITEM fn std::alloc::Global::alloc_impl_runtime //~ MONO_ITEM fn std::boxed::Box::::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::ptr::NonNull::::new_unchecked::precondition_check struct Counter { diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff index 7d722f7f5fdf0..ab222c968da16 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff @@ -11,9 +11,8 @@ let mut _9: *const [()]; let mut _10: std::boxed::Box<()>; let mut _11: *const (); - let mut _14: usize; - let mut _15: usize; - let mut _24: usize; + let mut _14: std::alloc::Layout; + let mut _20: usize; scope 1 { debug vp_ctx => _1; let _5: *const (); @@ -26,12 +25,12 @@ scope 4 { debug _x => _8; } - scope 20 (inlined foo) { - let mut _25: *const [()]; + scope 18 (inlined foo) { + let mut _21: *const [()]; } } - scope 18 (inlined slice_from_raw_parts::<()>) { - scope 19 (inlined std::ptr::from_raw_parts::<[()], ()>) { + scope 16 (inlined slice_from_raw_parts::<()>) { + scope 17 (inlined std::ptr::from_raw_parts::<[()], ()>) { } } } @@ -42,33 +41,26 @@ scope 6 { } scope 7 (inlined boxed::box_new_uninit) { - let _16: std::alloc::Layout; - let mut _17: std::result::Result, std::alloc::AllocError>; - let mut _18: isize; - let mut _20: !; + let mut _15: std::result::Result, std::alloc::AllocError>; + let mut _16: isize; + let _17: std::ptr::NonNull<[u8]>; + let mut _18: !; 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::) { - let mut _23: *mut [u8]; - scope 16 (inlined NonNull::<[u8]>::as_ptr) { - } + scope 11 (inlined NonNull::<[u8]>::as_mut_ptr) { + scope 12 (inlined NonNull::<[u8]>::as_non_null_ptr) { + scope 13 (inlined NonNull::<[u8]>::cast::) { + let mut _19: *mut [u8]; + scope 14 (inlined NonNull::<[u8]>::as_ptr) { } } - scope 17 (inlined NonNull::::as_ptr) { - } } - } - scope 11 (inlined ::allocate) { - scope 12 (inlined std::alloc::Global::alloc_impl) { + scope 15 (inlined NonNull::::as_ptr) { } } } - scope 10 (inlined #[track_caller] Layout::from_size_align_unchecked) { - let _21: (); - let mut _22: std::ptr::Alignment; + scope 9 (inlined ::allocate) { + scope 10 (inlined std::alloc::Global::alloc_impl) { + } } } } @@ -83,17 +75,14 @@ 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; +- _14 = const <() as std::mem::SizedTypeProperties>::LAYOUT; ++ _14 = const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}; StorageLive(_16); + StorageLive(_17); StorageLive(_18); - StorageLive(_19); - StorageLive(_20); - StorageLive(_21); - switchInt(UbChecks) -> [0: bb6, otherwise: bb5]; + StorageLive(_15); +- _15 = std::alloc::Global::alloc_impl_runtime(copy _14, const false) -> [return: bb5, unwind unreachable]; ++ _15 = 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: bb5, unwind unreachable]; } bb1: { @@ -107,29 +96,26 @@ } 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; +- _18 = handle_alloc_error(move _14) -> unwind unreachable; ++ _18 = 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); + _17 = copy ((_15 as Ok).0: std::ptr::NonNull<[u8]>); +- StorageLive(_19); + nop; - _23 = copy _19 as *mut [u8] (Transmute); - _13 = copy _23 as *mut u8 (PtrToPtr); -- StorageDead(_23); + _19 = copy _17 as *mut [u8] (Transmute); + _13 = copy _19 as *mut u8 (PtrToPtr); +- StorageDead(_19); + nop; - StorageDead(_17); - StorageDead(_21); - StorageDead(_20); - StorageDead(_19); + StorageDead(_15); StorageDead(_18); + StorageDead(_17); StorageDead(_16); - StorageDead(_15); StorageDead(_14); - _12 = copy _13 as *mut () (PtrToPtr); - (*_12) = move _4; -+ _12 = copy _23 as *mut () (PtrToPtr); ++ _12 = copy _19 as *mut () (PtrToPtr); + (*_12) = const (); _3 = copy _13 as std::boxed::Box<()> (Transmute); StorageDead(_13); @@ -147,21 +133,21 @@ + nop; StorageLive(_7); _7 = copy _5; - StorageLive(_24); - _24 = const 1_usize; -- _6 = *const [()] from (copy _7, copy _24); + StorageLive(_20); + _20 = const 1_usize; +- _6 = *const [()] from (copy _7, copy _20); + _6 = *const [()] from (copy _5, const 1_usize); - StorageDead(_24); + StorageDead(_20); StorageDead(_7); StorageLive(_8); StorageLive(_9); _9 = copy _6; - StorageLive(_25); -- _25 = copy _9; + StorageLive(_21); +- _21 = copy _9; - _8 = copy _9 as *mut () (PtrToPtr); -+ _25 = copy _6; ++ _21 = copy _6; + _8 = copy _5 as *mut () (PtrToPtr); - StorageDead(_25); + StorageDead(_21); StorageDead(_9); _0 = const (); StorageDead(_8); @@ -173,25 +159,8 @@ } 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]; + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb4, 1: bb3, otherwise: bb2]; } + } + diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff index d5134f7347828..923c7bfd1d99c 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff @@ -11,9 +11,8 @@ let mut _9: *const [()]; let mut _10: std::boxed::Box<()>; let mut _11: *const (); - let mut _14: usize; - let mut _15: usize; - let mut _24: usize; + let mut _14: std::alloc::Layout; + let mut _20: usize; scope 1 { debug vp_ctx => _1; let _5: *const (); @@ -26,12 +25,12 @@ scope 4 { debug _x => _8; } - scope 20 (inlined foo) { - let mut _25: *const [()]; + scope 18 (inlined foo) { + let mut _21: *const [()]; } } - scope 18 (inlined slice_from_raw_parts::<()>) { - scope 19 (inlined std::ptr::from_raw_parts::<[()], ()>) { + scope 16 (inlined slice_from_raw_parts::<()>) { + scope 17 (inlined std::ptr::from_raw_parts::<[()], ()>) { } } } @@ -42,33 +41,26 @@ scope 6 { } scope 7 (inlined boxed::box_new_uninit) { - let _16: std::alloc::Layout; - let mut _17: std::result::Result, std::alloc::AllocError>; - let mut _18: isize; - let mut _20: !; + let mut _15: std::result::Result, std::alloc::AllocError>; + let mut _16: isize; + let _17: std::ptr::NonNull<[u8]>; + let mut _18: !; 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::) { - let mut _23: *mut [u8]; - scope 16 (inlined NonNull::<[u8]>::as_ptr) { - } + scope 11 (inlined NonNull::<[u8]>::as_mut_ptr) { + scope 12 (inlined NonNull::<[u8]>::as_non_null_ptr) { + scope 13 (inlined NonNull::<[u8]>::cast::) { + let mut _19: *mut [u8]; + scope 14 (inlined NonNull::<[u8]>::as_ptr) { } } - scope 17 (inlined NonNull::::as_ptr) { - } } - } - scope 11 (inlined ::allocate) { - scope 12 (inlined std::alloc::Global::alloc_impl) { + scope 15 (inlined NonNull::::as_ptr) { } } } - scope 10 (inlined #[track_caller] Layout::from_size_align_unchecked) { - let _21: (); - let mut _22: std::ptr::Alignment; + scope 9 (inlined ::allocate) { + scope 10 (inlined std::alloc::Global::alloc_impl) { + } } } } @@ -83,17 +75,14 @@ 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; +- _14 = const <() as std::mem::SizedTypeProperties>::LAYOUT; ++ _14 = const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}; StorageLive(_16); + StorageLive(_17); StorageLive(_18); - StorageLive(_19); - StorageLive(_20); - StorageLive(_21); - switchInt(UbChecks) -> [0: bb6, otherwise: bb5]; + StorageLive(_15); +- _15 = std::alloc::Global::alloc_impl_runtime(copy _14, const false) -> [return: bb5, unwind unreachable]; ++ _15 = 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: bb5, unwind unreachable]; } bb1: { @@ -107,29 +96,26 @@ } 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; +- _18 = handle_alloc_error(move _14) -> unwind unreachable; ++ _18 = 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); + _17 = copy ((_15 as Ok).0: std::ptr::NonNull<[u8]>); +- StorageLive(_19); + nop; - _23 = copy _19 as *mut [u8] (Transmute); - _13 = copy _23 as *mut u8 (PtrToPtr); -- StorageDead(_23); + _19 = copy _17 as *mut [u8] (Transmute); + _13 = copy _19 as *mut u8 (PtrToPtr); +- StorageDead(_19); + nop; - StorageDead(_17); - StorageDead(_21); - StorageDead(_20); - StorageDead(_19); + StorageDead(_15); StorageDead(_18); + StorageDead(_17); StorageDead(_16); - StorageDead(_15); StorageDead(_14); - _12 = copy _13 as *mut () (PtrToPtr); - (*_12) = move _4; -+ _12 = copy _23 as *mut () (PtrToPtr); ++ _12 = copy _19 as *mut () (PtrToPtr); + (*_12) = const (); _3 = copy _13 as std::boxed::Box<()> (Transmute); StorageDead(_13); @@ -147,21 +133,21 @@ + nop; StorageLive(_7); _7 = copy _5; - StorageLive(_24); - _24 = const 1_usize; -- _6 = *const [()] from (copy _7, copy _24); + StorageLive(_20); + _20 = const 1_usize; +- _6 = *const [()] from (copy _7, copy _20); + _6 = *const [()] from (copy _5, const 1_usize); - StorageDead(_24); + StorageDead(_20); StorageDead(_7); StorageLive(_8); StorageLive(_9); _9 = copy _6; - StorageLive(_25); -- _25 = copy _9; + StorageLive(_21); +- _21 = copy _9; - _8 = copy _9 as *mut () (PtrToPtr); -+ _25 = copy _6; ++ _21 = copy _6; + _8 = copy _5 as *mut () (PtrToPtr); - StorageDead(_25); + StorageDead(_21); StorageDead(_9); _0 = const (); StorageDead(_8); @@ -173,25 +159,8 @@ } 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]; + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb4, 1: bb3, otherwise: bb2]; } + } + diff --git a/tests/ui/limits/issue-17913.32bit.stderr b/tests/ui/limits/issue-17913.32bit.stderr index 1311822d0d0c4..1e3e3a9f32295 100644 --- a/tests/ui/limits/issue-17913.32bit.stderr +++ b/tests/ui/limits/issue-17913.32bit.stderr @@ -3,17 +3,12 @@ error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the targ | = note: evaluation of `<[&usize; usize::MAX] as std::mem::SizedTypeProperties>::SIZE` failed here -error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL - | - = note: evaluation of `<[&usize; usize::MAX] as std::mem::SizedTypeProperties>::ALIGN` failed here - note: the above error was encountered while instantiating `fn Box::<[&usize; usize::MAX]>::new` --> $DIR/issue-17913.rs:16:21 | LL | let a: Box<_> = Box::new([&n; SIZE]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/limits/issue-17913.64bit.stderr b/tests/ui/limits/issue-17913.64bit.stderr index b0481ee99378c..5e92c70a764c4 100644 --- a/tests/ui/limits/issue-17913.64bit.stderr +++ b/tests/ui/limits/issue-17913.64bit.stderr @@ -3,17 +3,12 @@ error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the targ | = note: evaluation of `<[&usize; usize::MAX] as std::mem::SizedTypeProperties>::SIZE` failed here -error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL - | - = note: evaluation of `<[&usize; usize::MAX] as std::mem::SizedTypeProperties>::ALIGN` failed here - note: the above error was encountered while instantiating `fn Box::<[&usize; usize::MAX]>::new` --> $DIR/issue-17913.rs:9:21 | LL | let a: Box<_> = Box::new([&n; SIZE]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/limits/issue-17913.rs b/tests/ui/limits/issue-17913.rs index d804b64ab330e..9448358edba00 100644 --- a/tests/ui/limits/issue-17913.rs +++ b/tests/ui/limits/issue-17913.rs @@ -18,4 +18,3 @@ fn main() { } //~? ERROR are too big for the target architecture -//~? ERROR are too big for the target architecture From 4b03b97226391b745d3ee033c325b8976f14e397 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 17 Feb 2026 00:31:19 -0800 Subject: [PATCH 2/2] What if we discourage mir-inlining of `box_new_uninit`? --- library/alloc/src/boxed.rs | 4 + .../item-collection/opaque-return-impls.rs | 1 + ...ng_operand.test.GVN.32bit.panic-abort.diff | 93 +++---------------- ...ng_operand.test.GVN.64bit.panic-abort.diff | 93 +++---------------- 4 files changed, 35 insertions(+), 156 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 8b05464334914..ae16a8401552d 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -238,6 +238,10 @@ pub struct Box< /// Monomorphic function for allocating an uninit `Box`. #[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))] fn box_new_uninit(layout: Layout) -> *mut u8 { diff --git a/tests/codegen-units/item-collection/opaque-return-impls.rs b/tests/codegen-units/item-collection/opaque-return-impls.rs index 63ee9afe34ab9..1c32ddf6254b5 100644 --- a/tests/codegen-units/item-collection/opaque-return-impls.rs +++ b/tests/codegen-units/item-collection/opaque-return-impls.rs @@ -45,6 +45,7 @@ pub fn foo2() -> Box { //~ MONO_ITEM fn foo2 //~ MONO_ITEM fn std::alloc::Global::alloc_impl_runtime //~ MONO_ITEM fn std::boxed::Box::::new +//~ MONO_ITEM fn std::boxed::box_new_uninit //~ MONO_ITEM fn std::ptr::NonNull::::new_unchecked::precondition_check struct Counter { diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff index ab222c968da16..a83771f740a29 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff @@ -11,8 +11,7 @@ let mut _9: *const [()]; let mut _10: std::boxed::Box<()>; let mut _11: *const (); - let mut _14: std::alloc::Layout; - let mut _20: usize; + let mut _14: usize; scope 1 { debug vp_ctx => _1; let _5: *const (); @@ -25,12 +24,12 @@ scope 4 { debug _x => _8; } - scope 18 (inlined foo) { - let mut _21: *const [()]; + scope 9 (inlined foo) { + let mut _15: *const [()]; } } - scope 16 (inlined slice_from_raw_parts::<()>) { - scope 17 (inlined std::ptr::from_raw_parts::<[()], ()>) { + scope 7 (inlined slice_from_raw_parts::<()>) { + scope 8 (inlined std::ptr::from_raw_parts::<[()], ()>) { } } } @@ -40,29 +39,6 @@ let mut _13: *mut u8; scope 6 { } - scope 7 (inlined boxed::box_new_uninit) { - let mut _15: std::result::Result, std::alloc::AllocError>; - let mut _16: isize; - let _17: std::ptr::NonNull<[u8]>; - let mut _18: !; - scope 8 { - scope 11 (inlined NonNull::<[u8]>::as_mut_ptr) { - scope 12 (inlined NonNull::<[u8]>::as_non_null_ptr) { - scope 13 (inlined NonNull::<[u8]>::cast::) { - let mut _19: *mut [u8]; - scope 14 (inlined NonNull::<[u8]>::as_ptr) { - } - } - } - scope 15 (inlined NonNull::::as_ptr) { - } - } - } - scope 9 (inlined ::allocate) { - scope 10 (inlined std::alloc::Global::alloc_impl) { - } - } - } } bb0: { @@ -74,15 +50,7 @@ + _4 = const (); StorageLive(_12); StorageLive(_13); - StorageLive(_14); -- _14 = const <() as std::mem::SizedTypeProperties>::LAYOUT; -+ _14 = const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}; - StorageLive(_16); - StorageLive(_17); - StorageLive(_18); - StorageLive(_15); -- _15 = std::alloc::Global::alloc_impl_runtime(copy _14, const false) -> [return: bb5, unwind unreachable]; -+ _15 = 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: bb5, unwind unreachable]; + _13 = boxed::box_new_uninit(const <() as std::mem::SizedTypeProperties>::LAYOUT) -> [return: bb2, unwind unreachable]; } bb1: { @@ -92,30 +60,8 @@ } bb2: { - unreachable; - } - - bb3: { -- _18 = handle_alloc_error(move _14) -> unwind unreachable; -+ _18 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> unwind unreachable; - } - - bb4: { - _17 = copy ((_15 as Ok).0: std::ptr::NonNull<[u8]>); -- StorageLive(_19); -+ nop; - _19 = copy _17 as *mut [u8] (Transmute); - _13 = copy _19 as *mut u8 (PtrToPtr); -- StorageDead(_19); -+ nop; - StorageDead(_15); - StorageDead(_18); - StorageDead(_17); - StorageDead(_16); - StorageDead(_14); -- _12 = copy _13 as *mut () (PtrToPtr); + _12 = copy _13 as *mut () (PtrToPtr); - (*_12) = move _4; -+ _12 = copy _19 as *mut () (PtrToPtr); + (*_12) = const (); _3 = copy _13 as std::boxed::Box<()> (Transmute); StorageDead(_13); @@ -133,21 +79,21 @@ + nop; StorageLive(_7); _7 = copy _5; - StorageLive(_20); - _20 = const 1_usize; -- _6 = *const [()] from (copy _7, copy _20); + StorageLive(_14); + _14 = const 1_usize; +- _6 = *const [()] from (copy _7, copy _14); + _6 = *const [()] from (copy _5, const 1_usize); - StorageDead(_20); + StorageDead(_14); StorageDead(_7); StorageLive(_8); StorageLive(_9); _9 = copy _6; - StorageLive(_21); -- _21 = copy _9; + StorageLive(_15); +- _15 = copy _9; - _8 = copy _9 as *mut () (PtrToPtr); -+ _21 = copy _6; ++ _15 = copy _6; + _8 = copy _5 as *mut () (PtrToPtr); - StorageDead(_21); + StorageDead(_15); StorageDead(_9); _0 = const (); StorageDead(_8); @@ -157,14 +103,5 @@ + nop; drop(_3) -> [return: bb1, unwind unreachable]; } - - bb5: { - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb4, 1: bb3, otherwise: bb2]; - } -+ } -+ -+ ALLOC0 (size: 8, align: 4) { -+ 01 00 00 00 00 00 00 00 │ ........ } diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff index 923c7bfd1d99c..a83771f740a29 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff @@ -11,8 +11,7 @@ let mut _9: *const [()]; let mut _10: std::boxed::Box<()>; let mut _11: *const (); - let mut _14: std::alloc::Layout; - let mut _20: usize; + let mut _14: usize; scope 1 { debug vp_ctx => _1; let _5: *const (); @@ -25,12 +24,12 @@ scope 4 { debug _x => _8; } - scope 18 (inlined foo) { - let mut _21: *const [()]; + scope 9 (inlined foo) { + let mut _15: *const [()]; } } - scope 16 (inlined slice_from_raw_parts::<()>) { - scope 17 (inlined std::ptr::from_raw_parts::<[()], ()>) { + scope 7 (inlined slice_from_raw_parts::<()>) { + scope 8 (inlined std::ptr::from_raw_parts::<[()], ()>) { } } } @@ -40,29 +39,6 @@ let mut _13: *mut u8; scope 6 { } - scope 7 (inlined boxed::box_new_uninit) { - let mut _15: std::result::Result, std::alloc::AllocError>; - let mut _16: isize; - let _17: std::ptr::NonNull<[u8]>; - let mut _18: !; - scope 8 { - scope 11 (inlined NonNull::<[u8]>::as_mut_ptr) { - scope 12 (inlined NonNull::<[u8]>::as_non_null_ptr) { - scope 13 (inlined NonNull::<[u8]>::cast::) { - let mut _19: *mut [u8]; - scope 14 (inlined NonNull::<[u8]>::as_ptr) { - } - } - } - scope 15 (inlined NonNull::::as_ptr) { - } - } - } - scope 9 (inlined ::allocate) { - scope 10 (inlined std::alloc::Global::alloc_impl) { - } - } - } } bb0: { @@ -74,15 +50,7 @@ + _4 = const (); StorageLive(_12); StorageLive(_13); - StorageLive(_14); -- _14 = const <() as std::mem::SizedTypeProperties>::LAYOUT; -+ _14 = const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}; - StorageLive(_16); - StorageLive(_17); - StorageLive(_18); - StorageLive(_15); -- _15 = std::alloc::Global::alloc_impl_runtime(copy _14, const false) -> [return: bb5, unwind unreachable]; -+ _15 = 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: bb5, unwind unreachable]; + _13 = boxed::box_new_uninit(const <() as std::mem::SizedTypeProperties>::LAYOUT) -> [return: bb2, unwind unreachable]; } bb1: { @@ -92,30 +60,8 @@ } bb2: { - unreachable; - } - - bb3: { -- _18 = handle_alloc_error(move _14) -> unwind unreachable; -+ _18 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> unwind unreachable; - } - - bb4: { - _17 = copy ((_15 as Ok).0: std::ptr::NonNull<[u8]>); -- StorageLive(_19); -+ nop; - _19 = copy _17 as *mut [u8] (Transmute); - _13 = copy _19 as *mut u8 (PtrToPtr); -- StorageDead(_19); -+ nop; - StorageDead(_15); - StorageDead(_18); - StorageDead(_17); - StorageDead(_16); - StorageDead(_14); -- _12 = copy _13 as *mut () (PtrToPtr); + _12 = copy _13 as *mut () (PtrToPtr); - (*_12) = move _4; -+ _12 = copy _19 as *mut () (PtrToPtr); + (*_12) = const (); _3 = copy _13 as std::boxed::Box<()> (Transmute); StorageDead(_13); @@ -133,21 +79,21 @@ + nop; StorageLive(_7); _7 = copy _5; - StorageLive(_20); - _20 = const 1_usize; -- _6 = *const [()] from (copy _7, copy _20); + StorageLive(_14); + _14 = const 1_usize; +- _6 = *const [()] from (copy _7, copy _14); + _6 = *const [()] from (copy _5, const 1_usize); - StorageDead(_20); + StorageDead(_14); StorageDead(_7); StorageLive(_8); StorageLive(_9); _9 = copy _6; - StorageLive(_21); -- _21 = copy _9; + StorageLive(_15); +- _15 = copy _9; - _8 = copy _9 as *mut () (PtrToPtr); -+ _21 = copy _6; ++ _15 = copy _6; + _8 = copy _5 as *mut () (PtrToPtr); - StorageDead(_21); + StorageDead(_15); StorageDead(_9); _0 = const (); StorageDead(_8); @@ -157,14 +103,5 @@ + nop; drop(_3) -> [return: bb1, unwind unreachable]; } - - bb5: { - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb4, 1: bb3, otherwise: bb2]; - } -+ } -+ -+ ALLOC0 (size: 16, align: 8) { -+ 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ }