Skip to content

Commit 996c127

Browse files
committed
Async drop - fix for StorageLive/StorageDead codegen for pinned async drop future
1 parent 7c10378 commit 996c127

File tree

5 files changed

+41
-9
lines changed

5 files changed

+41
-9
lines changed

compiler/rustc_mir_transform/src/coroutine/drop.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ fn build_poll_switch<'tcx>(
132132
body: &mut Body<'tcx>,
133133
poll_enum: Ty<'tcx>,
134134
poll_unit_place: &Place<'tcx>,
135+
fut_pin_place: &Place<'tcx>,
135136
ready_block: BasicBlock,
136137
yield_block: BasicBlock,
137138
) -> BasicBlock {
@@ -162,9 +163,11 @@ fn build_poll_switch<'tcx>(
162163
Rvalue::Discriminant(*poll_unit_place),
163164
))),
164165
};
166+
let storage_dead =
167+
Statement { source_info, kind: StatementKind::StorageDead(fut_pin_place.local) };
165168
let unreachable_block = insert_term_block(body, TerminatorKind::Unreachable);
166169
body.basic_blocks_mut().push(BasicBlockData {
167-
statements: [discr_assign].to_vec(),
170+
statements: [storage_dead, discr_assign].to_vec(),
168171
terminator: Some(Terminator {
169172
source_info,
170173
kind: TerminatorKind::SwitchInt {
@@ -332,10 +335,17 @@ pub(super) fn expand_async_drops<'tcx>(
332335
kind: StatementKind::Assign(Box::new((context_ref_place, arg))),
333336
});
334337
let yield_block = insert_term_block(body, TerminatorKind::Unreachable); // `kind` replaced later to yield
335-
let switch_block =
336-
build_poll_switch(tcx, body, poll_enum, &poll_unit_place, target, yield_block);
337338
let (pin_bb, fut_pin_place) =
338339
build_pin_fut(tcx, body, fut_place.clone(), UnwindAction::Continue);
340+
let switch_block = build_poll_switch(
341+
tcx,
342+
body,
343+
poll_enum,
344+
&poll_unit_place,
345+
&fut_pin_place,
346+
target,
347+
yield_block,
348+
);
339349
let call_bb = build_poll_call(
340350
tcx,
341351
body,
@@ -357,16 +367,17 @@ pub(super) fn expand_async_drops<'tcx>(
357367
body.local_decls.push(LocalDecl::new(context_mut_ref, source_info.span)),
358368
);
359369
let drop_yield_block = insert_term_block(body, TerminatorKind::Unreachable); // `kind` replaced later to yield
370+
let (pin_bb2, fut_pin_place2) =
371+
build_pin_fut(tcx, body, fut_place, UnwindAction::Continue);
360372
let drop_switch_block = build_poll_switch(
361373
tcx,
362374
body,
363375
poll_enum,
364376
&poll_unit_place,
377+
&fut_pin_place2,
365378
drop.unwrap(),
366379
drop_yield_block,
367380
);
368-
let (pin_bb2, fut_pin_place2) =
369-
build_pin_fut(tcx, body, fut_place, UnwindAction::Continue);
370381
let drop_call_bb = build_poll_call(
371382
tcx,
372383
body,

compiler/rustc_mir_transform/src/elaborate_drop.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,20 @@ where
390390
Location { block: self.succ, statement_index: 0 },
391391
StatementKind::StorageDead(fut.local),
392392
);
393+
// StorageDead(fut) in unwind block (at the begin)
394+
if let Unwind::To(block) = unwind {
395+
self.elaborator.patch().add_statement(
396+
Location { block, statement_index: 0 },
397+
StatementKind::StorageDead(fut.local),
398+
);
399+
}
400+
// StorageDead(fut) in dropline block (at the begin)
401+
if let Some(block) = dropline {
402+
self.elaborator.patch().add_statement(
403+
Location { block, statement_index: 0 },
404+
StatementKind::StorageDead(fut.local),
405+
);
406+
}
393407

394408
// #1:pin_obj_bb >>> call Pin<ObjTy>::new_unchecked(&mut obj)
395409
self.elaborator.patch().patch_terminator(

tests/ui/async-await/async-drop/async-drop-initial.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ fn main() {
6262
test_async_drop(&j, 16).await;
6363
test_async_drop(
6464
AsyncStruct { b: AsyncInt(8), a: AsyncInt(7), i: 6 },
65-
if cfg!(panic = "unwind") { 168 } else { 136 },
65+
136,
6666
).await;
6767
test_async_drop(ManuallyDrop::new(AsyncInt(9)), 16).await;
6868

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
//@ known-bug: #140429
1+
// ex-ice: #140429
22
//@ compile-flags: -Zlint-mir --crate-type lib
33
//@ edition:2024
4+
//@ build-pass
45

56
#![feature(async_drop)]
7+
#![allow(incomplete_features)]
8+
69
async fn a<T>(x: T) {}
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
//@ known-bug: #140531
2-
//@compile-flags: -Zlint-mir --crate-type lib
1+
// ex-ice: #140531
2+
//@ compile-flags: -Zlint-mir --crate-type lib
33
//@ edition:2024
4+
//@ build-pass
5+
46
#![feature(async_drop)]
7+
#![allow(incomplete_features)]
8+
59
async fn call_once(f: impl AsyncFnOnce()) {
610
let fut = Box::pin(f());
711
}

0 commit comments

Comments
 (0)