diff options
Diffstat (limited to 'compiler/rustc_mir_transform/src')
| -rw-r--r-- | compiler/rustc_mir_transform/src/coroutine/drop.rs | 21 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/elaborate_drop.rs | 14 |
2 files changed, 30 insertions, 5 deletions
diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs index 6021e795d21..dc68629ec0d 100644 --- a/compiler/rustc_mir_transform/src/coroutine/drop.rs +++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs @@ -132,6 +132,7 @@ fn build_poll_switch<'tcx>( body: &mut Body<'tcx>, poll_enum: Ty<'tcx>, poll_unit_place: &Place<'tcx>, + fut_pin_place: &Place<'tcx>, ready_block: BasicBlock, yield_block: BasicBlock, ) -> BasicBlock { @@ -162,9 +163,11 @@ fn build_poll_switch<'tcx>( Rvalue::Discriminant(*poll_unit_place), ))), }; + let storage_dead = + Statement { source_info, kind: StatementKind::StorageDead(fut_pin_place.local) }; let unreachable_block = insert_term_block(body, TerminatorKind::Unreachable); body.basic_blocks_mut().push(BasicBlockData { - statements: [discr_assign].to_vec(), + statements: [storage_dead, discr_assign].to_vec(), terminator: Some(Terminator { source_info, kind: TerminatorKind::SwitchInt { @@ -332,10 +335,17 @@ pub(super) fn expand_async_drops<'tcx>( kind: StatementKind::Assign(Box::new((context_ref_place, arg))), }); let yield_block = insert_term_block(body, TerminatorKind::Unreachable); // `kind` replaced later to yield - let switch_block = - build_poll_switch(tcx, body, poll_enum, &poll_unit_place, target, yield_block); let (pin_bb, fut_pin_place) = build_pin_fut(tcx, body, fut_place.clone(), UnwindAction::Continue); + let switch_block = build_poll_switch( + tcx, + body, + poll_enum, + &poll_unit_place, + &fut_pin_place, + target, + yield_block, + ); let call_bb = build_poll_call( tcx, body, @@ -357,16 +367,17 @@ pub(super) fn expand_async_drops<'tcx>( body.local_decls.push(LocalDecl::new(context_mut_ref, source_info.span)), ); let drop_yield_block = insert_term_block(body, TerminatorKind::Unreachable); // `kind` replaced later to yield + let (pin_bb2, fut_pin_place2) = + build_pin_fut(tcx, body, fut_place, UnwindAction::Continue); let drop_switch_block = build_poll_switch( tcx, body, poll_enum, &poll_unit_place, + &fut_pin_place2, drop.unwrap(), drop_yield_block, ); - let (pin_bb2, fut_pin_place2) = - build_pin_fut(tcx, body, fut_place, UnwindAction::Continue); let drop_call_bb = build_poll_call( tcx, body, diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 3a5e2620b14..c9bc52c6c7e 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -390,6 +390,20 @@ where Location { block: self.succ, statement_index: 0 }, StatementKind::StorageDead(fut.local), ); + // StorageDead(fut) in unwind block (at the begin) + if let Unwind::To(block) = unwind { + self.elaborator.patch().add_statement( + Location { block, statement_index: 0 }, + StatementKind::StorageDead(fut.local), + ); + } + // StorageDead(fut) in dropline block (at the begin) + if let Some(block) = dropline { + self.elaborator.patch().add_statement( + Location { block, statement_index: 0 }, + StatementKind::StorageDead(fut.local), + ); + } // #1:pin_obj_bb >>> call Pin<ObjTy>::new_unchecked(&mut obj) self.elaborator.patch().patch_terminator( |
