Skip to content

Commit e12d2c6

Browse files
committed
Async drop codegen (WIP)
1 parent 5bd5d21 commit e12d2c6

File tree

55 files changed

+1534
-129
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1534
-129
lines changed

compiler/rustc_borrowck/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
675675
TerminatorKind::SwitchInt { discr, targets: _ } => {
676676
self.consume_operand(loc, (discr, span), flow_state);
677677
}
678-
TerminatorKind::Drop { place, target: _, unwind: _, replace } => {
678+
TerminatorKind::Drop { place, target: _, unwind: _, replace, drop: _, async_fut: _ } => {
679679
debug!(
680680
"visit_terminator_drop \
681681
loc: {:?} term: {:?} place: {:?} span: {:?}",

compiler/rustc_borrowck/src/polonius/loan_invalidations.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'cx, 'tcx> {
9999
TerminatorKind::SwitchInt { discr, targets: _ } => {
100100
self.consume_operand(location, discr);
101101
}
102-
TerminatorKind::Drop { place: drop_place, target: _, unwind: _, replace } => {
102+
TerminatorKind::Drop { place: drop_place, target: _, unwind: _, replace, drop: _, async_fut: _ } => {
103103
let write_kind =
104104
if *replace { WriteKind::Replace } else { WriteKind::StorageDeadOrDrop };
105105
self.access_place(

compiler/rustc_borrowck/src/type_check/mod.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1684,8 +1684,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
16841684
}
16851685
}
16861686
TerminatorKind::Unreachable => {}
1687-
TerminatorKind::Drop { target, unwind, .. }
1688-
| TerminatorKind::Assert { target, unwind, .. } => {
1687+
TerminatorKind::Drop { target, unwind, drop, .. } => {
1688+
self.assert_iscleanup(body, block_data, target, is_cleanup);
1689+
self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup);
1690+
if let Some(drop) = drop {
1691+
self.assert_iscleanup(body, block_data, drop, is_cleanup);
1692+
}
1693+
}
1694+
TerminatorKind::Assert { target, unwind, .. } => {
16891695
self.assert_iscleanup(body, block_data, target, is_cleanup);
16901696
self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup);
16911697
}

compiler/rustc_codegen_cranelift/src/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
481481
| TerminatorKind::CoroutineDrop => {
482482
bug!("shouldn't exist at codegen {:?}", bb_data.terminator());
483483
}
484-
TerminatorKind::Drop { place, target, unwind: _, replace: _ } => {
484+
TerminatorKind::Drop { place, target, unwind: _, replace: _, drop: _, async_fut: _ } => {
485485
let drop_place = codegen_place(fx, *place);
486486
crate::abi::codegen_drop(fx, source_info, drop_place);
487487

compiler/rustc_codegen_ssa/src/mir/block.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1232,7 +1232,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
12321232
MergingSucc::False
12331233
}
12341234

1235-
mir::TerminatorKind::Drop { place, target, unwind, replace: _ } => {
1235+
mir::TerminatorKind::Drop { place, target, unwind, replace: _, drop: _, async_fut: _ } => {
12361236
self.codegen_drop_terminator(helper, bx, place, target, unwind, mergeable_succ())
12371237
}
12381238

compiler/rustc_const_eval/src/const_eval/machine.rs

+1
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
568568
RemainderByZero(op) => RemainderByZero(eval_to_int(op)?),
569569
ResumedAfterReturn(coroutine_kind) => ResumedAfterReturn(*coroutine_kind),
570570
ResumedAfterPanic(coroutine_kind) => ResumedAfterPanic(*coroutine_kind),
571+
ResumedAfterDrop(coroutine_kind) => ResumedAfterDrop(*coroutine_kind),
571572
MisalignedPointerDereference { ref required, ref found } => {
572573
MisalignedPointerDereference {
573574
required: eval_to_int(required)?,

compiler/rustc_const_eval/src/interpret/terminator.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
170170
}
171171
}
172172

173-
Drop { place, target, unwind, replace: _ } => {
173+
Drop { place, target, unwind, replace: _, drop: _, async_fut: _ } => {
174174
let frame = self.frame();
175175
let ty = place.ty(&frame.body.local_decls, *self.tcx).ty;
176176
let ty = self.subst_from_frame_and_normalize_erasing_regions(frame, ty)?;
@@ -542,6 +542,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
542542
| ty::InstanceDef::ReifyShim(..)
543543
| ty::InstanceDef::ClosureOnceShim { .. }
544544
| ty::InstanceDef::FnPtrShim(..)
545+
| ty::InstanceDef::FutureDropPollShim(..)
545546
| ty::InstanceDef::DropGlue(..)
546547
| ty::InstanceDef::CloneShim(..)
547548
| ty::InstanceDef::FnPtrAddrShim(..)

compiler/rustc_const_eval/src/transform/validate.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -363,9 +363,12 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
363363
);
364364
}
365365
}
366-
TerminatorKind::Drop { target, unwind, .. } => {
366+
TerminatorKind::Drop { target, unwind, drop, .. } => {
367367
self.check_edge(location, *target, EdgeKind::Normal);
368368
self.check_unwind_edge(location, *unwind);
369+
if let Some(drop) = drop {
370+
self.check_edge(location, *drop, EdgeKind::Normal);
371+
}
369372
}
370373
TerminatorKind::Call { args, destination, target, unwind, .. } => {
371374
if let Some(target) = target {

compiler/rustc_feature/src/unstable.rs

+2
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,8 @@ declare_features! (
355355
(unstable, associated_type_defaults, "1.2.0", Some(29661)),
356356
/// Allows `async || body` closures.
357357
(unstable, async_closure, "1.37.0", Some(62290)),
358+
/// Allows implementing `AsyncDrop`.
359+
(incomplete, async_drop, "CURRENT_RUSTC_VERSION", None),
358360
/// Allows `#[track_caller]` on async functions.
359361
(unstable, async_fn_track_caller, "1.73.0", Some(110011)),
360362
/// Allows `for await` loops.

compiler/rustc_hir/src/lang_items.rs

+4
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ language_item_table! {
163163

164164
Drop, sym::drop, drop_trait, Target::Trait, GenericRequirement::None;
165165
Destruct, sym::destruct, destruct_trait, Target::Trait, GenericRequirement::None;
166+
AsyncDrop, sym::async_drop, async_drop_trait, Target::Trait, GenericRequirement::None;
167+
AsyncDropInPlace, sym::async_drop_in_place, async_drop_in_place_fn, Target::Fn, GenericRequirement::Exact(1);
168+
FutureDropPoll, sym::future_drop_poll, future_drop_poll_fn, Target::Fn, GenericRequirement::Exact(1);
166169

167170
CoerceUnsized, sym::coerce_unsized, coerce_unsized_trait, Target::Trait, GenericRequirement::Minimum(1);
168171
DispatchFromDyn, sym::dispatch_from_dyn, dispatch_from_dyn_trait, Target::Trait, GenericRequirement::Minimum(1);
@@ -260,6 +263,7 @@ language_item_table! {
260263

261264
ExchangeMalloc, sym::exchange_malloc, exchange_malloc_fn, Target::Fn, GenericRequirement::None;
262265
DropInPlace, sym::drop_in_place, drop_in_place_fn, Target::Fn, GenericRequirement::Minimum(1);
266+
DropInPlaceFuture, sym::drop_in_place_future,drop_in_place_future_fn, Target::Fn, GenericRequirement::Minimum(1);
263267
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;
264268

265269
Start, sym::start, start_fn, Target::Fn, GenericRequirement::Exact(1);

compiler/rustc_middle/messages.ftl

+6
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,21 @@ middle_assert_async_resume_after_panic = `async fn` resumed after panicking
55
66
middle_assert_async_resume_after_return = `async fn` resumed after completion
77
8+
middle_assert_async_resume_after_drop = `async fn` resumed after async drop
9+
810
middle_assert_coroutine_resume_after_panic = coroutine resumed after panicking
911
1012
middle_assert_coroutine_resume_after_return = coroutine resumed after completion
1113
14+
middle_assert_coroutine_resume_after_drop = coroutine resumed after async drop
15+
1216
middle_assert_divide_by_zero =
1317
attempt to divide `{$val}` by zero
1418
1519
middle_assert_gen_resume_after_panic = `gen` fn or block cannot be further iterated on after it panicked
1620
21+
middle_assert_gen_resume_after_drop = `gen` fn or block cannot be further iterated on after it async dropped
22+
1723
middle_assert_misaligned_ptr_deref =
1824
misaligned pointer dereference: address must be a multiple of {$required} but is {$found}
1925

compiler/rustc_middle/src/mir/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,9 @@ pub struct CoroutineInfo<'tcx> {
255255
/// Coroutine drop glue.
256256
pub coroutine_drop: Option<Body<'tcx>>,
257257

258+
/// Coroutine async drop glue.
259+
pub coroutine_drop_async: Option<Body<'tcx>>,
260+
258261
/// The layout of a coroutine. Produced by the state transformation.
259262
pub coroutine_layout: Option<CoroutineLayout<'tcx>>,
260263

@@ -275,6 +278,7 @@ impl<'tcx> CoroutineInfo<'tcx> {
275278
yield_ty: Some(yield_ty),
276279
resume_ty: Some(resume_ty),
277280
coroutine_drop: None,
281+
coroutine_drop_async: None,
278282
coroutine_layout: None,
279283
}
280284
}
@@ -578,6 +582,11 @@ impl<'tcx> Body<'tcx> {
578582
self.coroutine.as_ref().and_then(|coroutine| coroutine.coroutine_drop.as_ref())
579583
}
580584

585+
#[inline]
586+
pub fn coroutine_drop_async(&self) -> Option<&Body<'tcx>> {
587+
self.coroutine.as_ref().and_then(|coroutine| coroutine.coroutine_drop_async.as_ref())
588+
}
589+
581590
#[inline]
582591
pub fn coroutine_kind(&self) -> Option<CoroutineKind> {
583592
self.coroutine.as_ref().map(|coroutine| coroutine.coroutine_kind)

compiler/rustc_middle/src/mir/mono.rs

+1
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ impl<'tcx> CodegenUnit<'tcx> {
402402
| InstanceDef::FnPtrShim(..)
403403
| InstanceDef::Virtual(..)
404404
| InstanceDef::ClosureOnceShim { .. }
405+
| InstanceDef::FutureDropPollShim(..)
405406
| InstanceDef::DropGlue(..)
406407
| InstanceDef::CloneShim(..)
407408
| InstanceDef::ThreadLocalShim(..)

compiler/rustc_middle/src/mir/pretty.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -855,7 +855,9 @@ impl<'tcx> TerminatorKind<'tcx> {
855855
Call { target: None, unwind: _, .. } => vec![],
856856
Yield { drop: Some(_), .. } => vec!["resume".into(), "drop".into()],
857857
Yield { drop: None, .. } => vec!["resume".into()],
858-
Drop { unwind: UnwindAction::Cleanup(_), .. } => vec!["return".into(), "unwind".into()],
858+
Drop { unwind: UnwindAction::Cleanup(_), drop: Some(_), .. } => vec!["return".into(), "unwind".into(), "drop".into() ],
859+
Drop { unwind: UnwindAction::Cleanup(_), drop: None, .. } => vec!["return".into(), "unwind".into()],
860+
Drop { unwind: _, drop: Some(_), .. } => vec!["return".into(), "drop".into() ],
859861
Drop { unwind: _, .. } => vec!["return".into()],
860862
Assert { unwind: UnwindAction::Cleanup(_), .. } => {
861863
vec!["success".into(), "unwind".into()]

compiler/rustc_middle/src/mir/syntax.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,16 @@ pub enum TerminatorKind<'tcx> {
656656
/// The `replace` flag indicates whether this terminator was created as part of an assignment.
657657
/// This should only be used for diagnostic purposes, and does not have any operational
658658
/// meaning.
659-
Drop { place: Place<'tcx>, target: BasicBlock, unwind: UnwindAction, replace: bool },
659+
Drop {
660+
place: Place<'tcx>,
661+
target: BasicBlock,
662+
unwind: UnwindAction,
663+
replace: bool,
664+
/// Cleanup to be done if the coroutine is dropped at this suspend point (for async drop).
665+
drop: Option<BasicBlock>,
666+
/// Prepared async future local (for async drop)
667+
async_fut: Option<Local>,
668+
},
660669

661670
/// Roughly speaking, evaluates the `func` operand and the arguments, and starts execution of
662671
/// the referred to function. The operand types must match the argument types of the function.
@@ -888,6 +897,7 @@ pub enum AssertKind<O> {
888897
RemainderByZero(O),
889898
ResumedAfterReturn(CoroutineKind),
890899
ResumedAfterPanic(CoroutineKind),
900+
ResumedAfterDrop(CoroutineKind),
891901
MisalignedPointerDereference { required: O, found: O },
892902
}
893903

0 commit comments

Comments
 (0)