1
Fork 0

Auto merge of #89030 - nbdd0121:box2, r=jonas-schievink

Introduce `Rvalue::ShallowInitBox`

Polished version of #88700.

Implements MCP rust-lang/compiler-team#460, and should allow #43596 to go forward.

In short, creating an empty box is split from a nullary-op `NullOp::Box` into two steps, first a call to `exchange_malloc`, then a `Rvalue::ShallowInitBox` which transmutes `*mut u8` to a shallow-initialized `Box<T>`. This allows the `exchange_malloc` call to unwind. Details can be found in the MCP.

`NullOp::Box` is not yet removed, purely to make reverting easier in case anything goes wrong as the result of this PR. If revert is needed a reversion of "Use Rvalue::ShallowInitBox for box expression" commit followed by a test bless should be sufficient.

Experiments in #88700 showed a very slight compile-time perf regression due to (supposedly) slightly more time spent in LLVM. We could omit unwind edge generation (in non-`oom=panic` case) in box expression MIR construction to restore perf; but I don't think it's necessary since runtime perf isn't affected and perf difference is rather small.
This commit is contained in:
bors 2021-09-25 11:01:13 +00:00
commit e9f29a8519
31 changed files with 478 additions and 237 deletions

View file

@ -316,7 +316,8 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
Rvalue::Use(ref operand)
| Rvalue::Repeat(ref operand, _)
| Rvalue::UnaryOp(_ /*un_op*/, ref operand)
| Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/) => {
| Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/)
| Rvalue::ShallowInitBox(ref operand, _ /*ty*/) => {
self.consume_operand(location, operand)
}

View file

@ -1361,7 +1361,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
Rvalue::Use(ref operand)
| Rvalue::Repeat(ref operand, _)
| Rvalue::UnaryOp(_ /*un_op*/, ref operand)
| Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/) => {
| Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/)
| Rvalue::ShallowInitBox(ref operand, _ /*ty*/) => {
self.consume_operand(location, (operand, span), flow_state)
}

View file

@ -2024,13 +2024,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
}
Rvalue::NullaryOp(_, ty) => {
// Even with unsized locals cannot box an unsized value.
if self.unsized_feature_enabled() {
let span = body.source_info(location).span;
self.ensure_place_sized(ty, span);
}
Rvalue::NullaryOp(_, ty) | Rvalue::ShallowInitBox(_, ty) => {
let trait_ref = ty::TraitRef {
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
substs: tcx.mk_substs_trait(ty, &[]),
@ -2363,6 +2357,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
| Rvalue::AddressOf(..)
| Rvalue::Len(..)
| Rvalue::Cast(..)
| Rvalue::ShallowInitBox(..)
| Rvalue::BinaryOp(..)
| Rvalue::CheckedBinaryOp(..)
| Rvalue::NullaryOp(..)