Skip to content

Commit 04a78eb

Browse files
committed
Use a direct write to box contents.
1 parent dce4d7f commit 04a78eb

File tree

3 files changed

+181
-206
lines changed

3 files changed

+181
-206
lines changed

library/alloc/src/boxed.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,8 +402,17 @@ impl<T, A: Allocator> Box<T, A> {
402402
A: Allocator,
403403
{
404404
let mut boxed = Self::new_uninit_in(alloc);
405-
boxed.write(x);
406-
unsafe { boxed.assume_init() }
405+
unsafe {
406+
// SAFETY: `x` is valid for writing and has the same layout as `T`.
407+
//
408+
// We use `ptr::write` as `MaybeUninit::write` creates
409+
// extra stack copies of `T` in debug mode.
410+
//
411+
// See https://github.com/rust-lang/rust/issues/136043 for more context.
412+
ptr::write(&raw mut *boxed as *mut T, x);
413+
// SAFETY: `x` was just initialized above.
414+
boxed.assume_init()
415+
}
407416
}
408417

409418
/// Allocates memory in the given allocator then places `x` into it,

tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff

Lines changed: 85 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
let mut _10: std::boxed::Box<()>;
1313
let mut _11: *const ();
1414
let mut _12: std::alloc::Global;
15-
let mut _28: usize;
15+
let mut _27: usize;
1616
scope 1 {
1717
debug vp_ctx => _1;
1818
let _5: *const ();
@@ -25,71 +25,62 @@
2525
scope 4 {
2626
debug _x => _8;
2727
}
28-
scope 30 (inlined foo) {
29-
let mut _29: *const [()];
28+
scope 26 (inlined foo) {
29+
let mut _28: *const [()];
3030
}
3131
}
32-
scope 28 (inlined slice_from_raw_parts::<()>) {
33-
scope 29 (inlined std::ptr::from_raw_parts::<[()], ()>) {
32+
scope 24 (inlined slice_from_raw_parts::<()>) {
33+
scope 25 (inlined std::ptr::from_raw_parts::<[()], ()>) {
3434
}
3535
}
3636
}
3737
}
3838
scope 5 (inlined Box::<()>::new) {
3939
scope 6 (inlined Box::<()>::new_in) {
4040
let mut _13: std::boxed::Box<std::mem::MaybeUninit<()>>;
41-
let mut _14: *const std::mem::MaybeUninit<()>;
42-
let mut _26: std::alloc::Global;
43-
let mut _27: std::ptr::NonNull<std::mem::MaybeUninit<()>>;
41+
let mut _14: *mut ();
42+
let mut _15: *mut std::mem::MaybeUninit<()>;
43+
let mut _16: *const std::mem::MaybeUninit<()>;
44+
let mut _25: std::alloc::Global;
45+
let mut _26: std::ptr::NonNull<std::mem::MaybeUninit<()>>;
4446
scope 7 {
45-
scope 8 (inlined MaybeUninit::<()>::write) {
46-
let mut _15: std::mem::MaybeUninit<()>;
47-
scope 9 (inlined MaybeUninit::<()>::new) {
48-
let mut _16: std::mem::ManuallyDrop<()>;
49-
scope 10 (inlined ManuallyDrop::<()>::new) {
50-
}
51-
}
52-
scope 11 (inlined MaybeUninit::<()>::assume_init_mut) {
53-
let _17: ();
54-
scope 12 (inlined MaybeUninit::<()>::as_mut_ptr) {
55-
}
56-
}
47+
scope 8 (inlined #[track_caller] std::ptr::write::<()>) {
5748
}
58-
scope 13 (inlined Box::<MaybeUninit<()>>::assume_init) {
59-
let mut _18: *mut ();
60-
scope 14 {
61-
scope 23 (inlined Box::<()>::from_raw_in) {
62-
let mut _20: std::ptr::Unique<()>;
63-
scope 24 (inlined Unique::<()>::new_unchecked) {
64-
let mut _21: std::ptr::NonNull<()>;
65-
scope 25 (inlined #[track_caller] NonNull::<()>::new_unchecked) {
66-
let _22: ();
67-
let mut _23: *mut ();
68-
let mut _24: *const ();
69-
scope 26 (inlined core::ub_checks::check_language_ub) {
70-
let mut _25: bool;
71-
scope 27 (inlined core::ub_checks::check_language_ub::runtime) {
49+
scope 9 (inlined Box::<MaybeUninit<()>>::assume_init) {
50+
let mut _17: *mut ();
51+
scope 10 {
52+
scope 19 (inlined Box::<()>::from_raw_in) {
53+
let mut _19: std::ptr::Unique<()>;
54+
scope 20 (inlined Unique::<()>::new_unchecked) {
55+
let mut _20: std::ptr::NonNull<()>;
56+
scope 21 (inlined #[track_caller] NonNull::<()>::new_unchecked) {
57+
let _21: ();
58+
let mut _22: *mut ();
59+
let mut _23: *const ();
60+
scope 22 (inlined core::ub_checks::check_language_ub) {
61+
let mut _24: bool;
62+
scope 23 (inlined core::ub_checks::check_language_ub::runtime) {
7263
}
7364
}
7465
}
7566
}
7667
}
7768
}
78-
scope 15 (inlined Box::<MaybeUninit<()>>::into_raw_with_allocator) {
79-
scope 16 {
80-
let _19: *mut std::mem::MaybeUninit<()>;
81-
scope 17 {
82-
scope 18 {
69+
scope 11 (inlined Box::<MaybeUninit<()>>::into_raw_with_allocator) {
70+
scope 12 {
71+
let _18: *mut std::mem::MaybeUninit<()>;
72+
scope 13 {
73+
scope 14 {
8374
}
84-
scope 21 (inlined <ManuallyDrop<Box<MaybeUninit<()>>> as Deref>::deref) {
75+
scope 17 (inlined <ManuallyDrop<Box<MaybeUninit<()>>> as Deref>::deref) {
8576
}
86-
scope 22 (inlined #[track_caller] std::ptr::read::<std::alloc::Global>) {
77+
scope 18 (inlined #[track_caller] std::ptr::read::<std::alloc::Global>) {
8778
}
8879
}
89-
scope 20 (inlined <ManuallyDrop<Box<MaybeUninit<()>>> as DerefMut>::deref_mut) {
80+
scope 16 (inlined <ManuallyDrop<Box<MaybeUninit<()>>> as DerefMut>::deref_mut) {
9081
}
9182
}
92-
scope 19 (inlined ManuallyDrop::<Box<MaybeUninit<()>>>::new) {
83+
scope 15 (inlined ManuallyDrop::<Box<MaybeUninit<()>>>::new) {
9384
}
9485
}
9586
}
@@ -107,11 +98,10 @@
10798
+ _4 = const ();
10899
StorageLive(_12);
109100
_12 = const std::alloc::Global;
110-
StorageLive(_14);
111-
StorageLive(_17);
112-
StorageLive(_22);
101+
StorageLive(_16);
102+
StorageLive(_21);
103+
StorageLive(_25);
113104
StorageLive(_26);
114-
StorageLive(_27);
115105
StorageLive(_13);
116106
- _13 = Box::<()>::new_uninit_in(move _12) -> [return: bb2, unwind unreachable];
117107
+ _13 = Box::<()>::new_uninit_in(const std::alloc::Global) -> [return: bb2, unwind unreachable];
@@ -124,69 +114,62 @@
124114
}
125115

126116
bb2: {
127-
_14 = copy ((_13.0: std::ptr::Unique<std::mem::MaybeUninit<()>>).0: std::ptr::NonNull<std::mem::MaybeUninit<()>>) as *const std::mem::MaybeUninit<()> (Transmute);
117+
StorageLive(_14);
128118
StorageLive(_15);
129-
StorageLive(_16);
130-
- _16 = ManuallyDrop::<()> { value: copy _4 };
131-
- _15 = MaybeUninit::<()> { uninit: move _16 };
132-
+ _16 = const ManuallyDrop::<()> {{ value: () }};
133-
+ _15 = const MaybeUninit::<()> {{ uninit: (), value: ManuallyDrop::<()> {{ value: () }} }};
134-
StorageDead(_16);
135-
- (*_14) = move _15;
136-
+ (*_14) = const MaybeUninit::<()> {{ uninit: (), value: ManuallyDrop::<()> {{ value: () }} }};
119+
_16 = copy ((_13.0: std::ptr::Unique<std::mem::MaybeUninit<()>>).0: std::ptr::NonNull<std::mem::MaybeUninit<()>>) as *const std::mem::MaybeUninit<()> (Transmute);
120+
_15 = &raw mut (*_16);
121+
_14 = copy _15 as *mut () (PtrToPtr);
137122
StorageDead(_15);
138-
_17 = assert_inhabited::<()>() -> [return: bb3, unwind unreachable];
139-
}
140-
141-
bb3: {
142-
_27 = move ((_13.0: std::ptr::Unique<std::mem::MaybeUninit<()>>).0: std::ptr::NonNull<std::mem::MaybeUninit<()>>);
143-
- _26 = move (_13.1: std::alloc::Global);
144-
+ _26 = const std::alloc::Global;
145-
StorageLive(_19);
146-
_19 = &raw mut (*_14);
147-
- StorageLive(_18);
123+
- (*_14) = copy _4;
124+
+ (*_14) = const ();
125+
StorageDead(_14);
126+
_26 = move ((_13.0: std::ptr::Unique<std::mem::MaybeUninit<()>>).0: std::ptr::NonNull<std::mem::MaybeUninit<()>>);
127+
- _25 = move (_13.1: std::alloc::Global);
128+
+ _25 = const std::alloc::Global;
129+
StorageLive(_18);
130+
_18 = &raw mut (*_16);
131+
- StorageLive(_17);
148132
+ nop;
149-
_18 = copy _19 as *mut () (PtrToPtr);
133+
_17 = copy _18 as *mut () (PtrToPtr);
134+
StorageLive(_19);
150135
StorageLive(_20);
151-
StorageLive(_21);
136+
StorageLive(_23);
152137
StorageLive(_24);
153-
StorageLive(_25);
154-
_25 = UbChecks();
155-
switchInt(copy _25) -> [0: bb6, otherwise: bb4];
138+
_24 = UbChecks();
139+
switchInt(copy _24) -> [0: bb5, otherwise: bb3];
156140
}
157141

158-
bb4: {
159-
StorageLive(_23);
160-
- _23 = copy _19 as *mut () (PtrToPtr);
161-
- _22 = NonNull::<T>::new_unchecked::precondition_check(move _23) -> [return: bb5, unwind unreachable];
162-
+ _23 = copy _18;
163-
+ _22 = NonNull::<T>::new_unchecked::precondition_check(copy _18) -> [return: bb5, unwind unreachable];
142+
bb3: {
143+
StorageLive(_22);
144+
- _22 = copy _18 as *mut () (PtrToPtr);
145+
- _21 = NonNull::<T>::new_unchecked::precondition_check(move _22) -> [return: bb4, unwind unreachable];
146+
+ _22 = copy _17;
147+
+ _21 = NonNull::<T>::new_unchecked::precondition_check(copy _17) -> [return: bb4, unwind unreachable];
164148
}
165149

166-
bb5: {
167-
StorageDead(_23);
168-
goto -> bb6;
150+
bb4: {
151+
StorageDead(_22);
152+
goto -> bb5;
169153
}
170154

171-
bb6: {
172-
_24 = copy _19 as *const () (PtrToPtr);
173-
_21 = NonNull::<()> { pointer: copy _24 };
174-
StorageDead(_25);
155+
bb5: {
156+
_23 = copy _18 as *const () (PtrToPtr);
157+
_20 = NonNull::<()> { pointer: copy _23 };
175158
StorageDead(_24);
176-
_20 = Unique::<()> { pointer: move _21, _marker: const PhantomData::<()> };
177-
StorageDead(_21);
178-
- _3 = Box::<()>(move _20, copy _26);
179-
+ _3 = Box::<()>(move _20, const std::alloc::Global);
159+
StorageDead(_23);
160+
_19 = Unique::<()> { pointer: move _20, _marker: const PhantomData::<()> };
180161
StorageDead(_20);
181-
- StorageDead(_18);
182-
+ nop;
162+
- _3 = Box::<()>(move _19, copy _25);
163+
+ _3 = Box::<()>(move _19, const std::alloc::Global);
183164
StorageDead(_19);
165+
- StorageDead(_17);
166+
+ nop;
167+
StorageDead(_18);
184168
StorageDead(_13);
185-
StorageDead(_27);
186169
StorageDead(_26);
187-
StorageDead(_22);
188-
StorageDead(_17);
189-
StorageDead(_14);
170+
StorageDead(_25);
171+
StorageDead(_21);
172+
StorageDead(_16);
190173
StorageDead(_12);
191174
StorageDead(_4);
192175
_2 = &_3;
@@ -203,21 +186,21 @@
203186
+ nop;
204187
StorageLive(_7);
205188
_7 = copy _5;
206-
StorageLive(_28);
207-
_28 = const 1_usize;
208-
- _6 = *const [()] from (copy _7, copy _28);
189+
StorageLive(_27);
190+
_27 = const 1_usize;
191+
- _6 = *const [()] from (copy _7, copy _27);
209192
+ _6 = *const [()] from (copy _5, const 1_usize);
210-
StorageDead(_28);
193+
StorageDead(_27);
211194
StorageDead(_7);
212195
StorageLive(_8);
213196
StorageLive(_9);
214197
_9 = copy _6;
215-
StorageLive(_29);
216-
- _29 = copy _9;
198+
StorageLive(_28);
199+
- _28 = copy _9;
217200
- _8 = copy _9 as *mut () (PtrToPtr);
218-
+ _29 = copy _6;
201+
+ _28 = copy _6;
219202
+ _8 = copy _5 as *mut () (PtrToPtr);
220-
StorageDead(_29);
203+
StorageDead(_28);
221204
StorageDead(_9);
222205
_0 = const ();
223206
StorageDead(_8);

0 commit comments

Comments
 (0)