Proposal
Introduce a new Rvalue variant, Rvalue::ShallowInitBox. It accepts an operand and a type, and will convert the operand to a shallowly-initialized box. This design is considered the better approach than a Box terminator after the Zulip dicussion.
In today's the MIR, box expr is translated to:
let _1: Box<ty>;
_1 = Box(ty);
(*_1) = expr;
however this does not allow unwind. Unwinding is necessary for rust-lang/rfcs#2116's oom=panic support (tracked in rust-lang/rust#43596).
Under this proposal, the originally Rvalue::NullaryOp(NullOp::Box, ty) is split into two operations, first a call to exchange_malloc(size_of::<ty>(), align_of::<ty>()), then converts it into a shallow-initialized box:
let _1: *mut u8;
let _2: Box<ty>;
bb0: {
_1 = exchange_malloc(SizeOf(ty), AlignOf(ty)) -> [return: bb1, unwind: bb2];
}
bb1: {
_2 = ShallowInitBox(move _1, ty);
(*_2) = expr;
}
with the extra unwinding edge provided by the exchange_malloc call.
The operational behaviour of ShallowInitBox is simply transmuting *mut u8 to Box<T>. The only thing special is that dataflow analysis will treat the content of the box as uninitialized.
An alternative is to remove box_syntax and Box nullary op from MIR at all; however, an attempt in rust-lang/rust#87781 shows very significant regression when doing so (perf run). Here is an godbolt snippet shows a case where box still needs special treatment in the MIR, and thus box_syntax is still needed at least as an implementation detail of the library.
Another alternative is the original proposal, to add a TerminatorKind::Box. However adding a new terminator requires much more changes than the current proposal.
The original proposal
Introduce a new terminator, TerminatorKind::Box to the MIR of form:
_1 = Box(ty) -> [return: bb1, unwind: bb2];
it'll be roughly equivalent to
_1 = Box(ty) // Nullary op Box here
goto -> bb1
in today's MIR, but has an additional unwind edge.
Box needs to be a special terminator rather than a function call, because a function call will deep-initialize the return place while Box will only shallow-initialize its return place.
The overall plan is:
- Introduce
TerminatorKind::Box
- Benchmark performance difference from using
Box terminator vs Box nullary op
- If performance is reasonable, switch
box_syntax to use Box terminator instead of Box nullary op
- Remove
Box as a nullary op.
Mentors or Reviewers
If you have a reviewer or mentor in mind for this work, mention then
here. You can put your own name here if you are planning to mentor the
work.
Process
The main points of the Major Change Process are as follows:
You can read more about Major Change Proposals on forge.
Comments
This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.
Proposal
Introduce a new
Rvaluevariant,Rvalue::ShallowInitBox. It accepts an operand and a type, and will convert the operand to a shallowly-initialized box. This design is considered the better approach than aBoxterminator after the Zulip dicussion.In today's the MIR,
box expris translated to:however this does not allow unwind. Unwinding is necessary for rust-lang/rfcs#2116's
oom=panicsupport (tracked in rust-lang/rust#43596).Under this proposal, the originally
Rvalue::NullaryOp(NullOp::Box, ty)is split into two operations, first a call toexchange_malloc(size_of::<ty>(), align_of::<ty>()), then converts it into a shallow-initialized box:with the extra unwinding edge provided by the
exchange_malloccall.The operational behaviour of
ShallowInitBoxis simply transmuting*mut u8toBox<T>. The only thing special is that dataflow analysis will treat the content of the box as uninitialized.An alternative is to remove
box_syntaxandBoxnullary op from MIR at all; however, an attempt in rust-lang/rust#87781 shows very significant regression when doing so (perf run). Here is an godbolt snippet shows a case whereboxstill needs special treatment in the MIR, and thusbox_syntaxis still needed at least as an implementation detail of the library.Another alternative is the original proposal, to add a
TerminatorKind::Box. However adding a new terminator requires much more changes than the current proposal.The original proposal
Introduce a new terminator,
TerminatorKind::Boxto the MIR of form:it'll be roughly equivalent to
in today's MIR, but has an additional unwind edge.
Boxneeds to be a special terminator rather than a function call, because a function call will deep-initialize the return place whileBoxwill only shallow-initialize its return place.The overall plan is:
TerminatorKind::BoxBoxterminator vsBoxnullary opbox_syntaxto useBoxterminator instead ofBoxnullary opBoxas a nullary op.Mentors or Reviewers
If you have a reviewer or mentor in mind for this work, mention then
here. You can put your own name here if you are planning to mentor the
work.
Process
The main points of the Major Change Process are as follows:
@rustbot second.-C flag, then full team check-off is required.@rfcbot fcp mergeon either the MCP or the PR.You can read more about Major Change Proposals on forge.
Comments
This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.