Skip to content

Commit 511333f

Browse files
committed
Use Rvalue::ShallowInitBox for box expression
1 parent c38da2e commit 511333f

File tree

2 files changed

+53
-3
lines changed

2 files changed

+53
-3
lines changed

compiler/rustc_mir_build/src/build/expr/as_rvalue.rs

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_index::vec::Idx;
55
use crate::build::expr::as_place::PlaceBase;
66
use crate::build::expr::category::{Category, RvalueFunc};
77
use crate::build::{BlockAnd, BlockAndExtension, Builder};
8+
use rustc_hir::lang_items::LangItem;
89
use rustc_middle::middle::region;
910
use rustc_middle::mir::AssertKind;
1011
use rustc_middle::mir::Place;
@@ -88,6 +89,56 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
8889
}
8990
ExprKind::Box { value } => {
9091
let value = &this.thir[value];
92+
let tcx = this.tcx;
93+
94+
// `exchange_malloc` is unsafe but box is safe, so need a new scope.
95+
let synth_scope = this.new_source_scope(
96+
expr_span,
97+
LintLevel::Inherited,
98+
Some(Safety::BuiltinUnsafe),
99+
);
100+
let synth_info = SourceInfo { span: expr_span, scope: synth_scope };
101+
102+
let size = this.temp(tcx.types.usize, expr_span);
103+
this.cfg.push_assign(
104+
block,
105+
synth_info,
106+
size,
107+
Rvalue::NullaryOp(NullOp::SizeOf, value.ty),
108+
);
109+
110+
let align = this.temp(tcx.types.usize, expr_span);
111+
this.cfg.push_assign(
112+
block,
113+
synth_info,
114+
align,
115+
Rvalue::NullaryOp(NullOp::AlignOf, value.ty),
116+
);
117+
118+
// malloc some memory of suitable size and align:
119+
let exchange_malloc = Operand::function_handle(
120+
tcx,
121+
tcx.require_lang_item(LangItem::ExchangeMalloc, Some(expr_span)),
122+
ty::List::empty(),
123+
expr_span,
124+
);
125+
let storage = this.temp(tcx.mk_mut_ptr(tcx.types.u8), expr_span);
126+
let success = this.cfg.start_new_block();
127+
this.cfg.terminate(
128+
block,
129+
synth_info,
130+
TerminatorKind::Call {
131+
func: exchange_malloc,
132+
args: vec![Operand::Move(size), Operand::Move(align)],
133+
destination: Some((Place::from(storage), success)),
134+
cleanup: None,
135+
from_hir_call: false,
136+
fn_span: expr_span,
137+
},
138+
);
139+
this.diverge_from(block);
140+
block = success;
141+
91142
// The `Box<T>` temporary created here is not a part of the HIR,
92143
// and therefore is not considered during generator auto-trait
93144
// determination. See the comment about `box` at `yield_in_scope`.
@@ -101,8 +152,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
101152
this.schedule_drop_storage_and_value(expr_span, scope, result);
102153
}
103154

104-
// malloc some memory of suitable type (thus far, uninitialized):
105-
let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
155+
// Transmute `*mut u8` to the box (thus far, uninitialized):
156+
let box_ = Rvalue::ShallowInitBox(Operand::Move(Place::from(storage)), value.ty);
106157
this.cfg.push_assign(block, source_info, Place::from(result), box_);
107158

108159
// initialize the box contents:

library/alloc/src/alloc.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,6 @@ unsafe impl Allocator for Global {
307307
}
308308

309309
/// The allocator for unique pointers.
310-
// This function must not unwind. If it does, MIR codegen will fail.
311310
#[cfg(all(not(no_global_oom_handling), not(test)))]
312311
#[lang = "exchange_malloc"]
313312
#[inline]

0 commit comments

Comments
 (0)