Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 7d65abf

Browse files
committedApr 28, 2025·
Auto merge of #123948 - azhogin:azhogin/async-drop, r=oli-obk
Async drop codegen Async drop implementation using templated coroutine for async drop glue generation. Scopes changes to generate `async_drop_in_place()` awaits, when async droppable objects are out-of-scope in async context. Implementation details: https://github.com/azhogin/posts/blob/main/async-drop-impl.md New fields in Drop terminator (drop & async_fut). Processing in codegen/miri must validate that those fields are empty (in full version async Drop terminator will be expanded at StateTransform pass or reverted to sync version). Changes in terminator visiting to consider possible new successor (drop field). ResumedAfterDrop messages for panic when coroutine is resumed after it is started to be async drop'ed. Lang item for generated coroutine for async function async_drop_in_place. `async fn async_drop_in_place<T>()::{{closure0}}`. Scopes processing for generate async drop preparations. Async drop is a hidden Yield, so potentially async drops require the same dropline preparation as for Yield terminators. Processing in StateTransform: async drops are expanded into yield-point. Generation of async drop of coroutine itself added. Shims for AsyncDropGlueCtorShim, AsyncDropGlue and FutureDropPoll. ```rust #[lang = "async_drop"] pub trait AsyncDrop { #[allow(async_fn_in_trait)] async fn drop(self: Pin<&mut Self>); } impl Drop for Foo { fn drop(&mut self) { println!("Foo::drop({})", self.my_resource_handle); } } impl AsyncDrop for Foo { async fn drop(self: Pin<&mut Self>) { println!("Foo::async drop({})", self.my_resource_handle); } } ``` First async drop glue implementation re-worked to use the same drop elaboration code as for sync drop. `async_drop_in_place` changed to be `async fn`. So both `async_drop_in_place` ctor and produced coroutine have their lang items (`AsyncDropInPlace`/`AsyncDropInPlacePoll`) and shim instances (`AsyncDropGlueCtorShim`/`AsyncDropGlue`). ``` pub async unsafe fn async_drop_in_place<T: ?Sized>(_to_drop: *mut T) { } ``` AsyncDropGlue shim generation uses `elaborate_drops::elaborate_drop` to produce drop ladder (in the similar way as for sync drop glue) and then `coroutine::StateTransform` to convert function into coroutine poll. AsyncDropGlue coroutine's layout can't be calculated for generic T, it requires known final dropee type to be generated (in StateTransform). So, `templated coroutine` was introduced here (`templated_coroutine_layout(...)` etc). Such approach overrides the first implementation using mixing language-level futures in #121801.
2 parents a932eb3 + c366756 commit 7d65abf

File tree

116 files changed

+4091
-1904
lines changed

Some content is hidden

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

116 files changed

+4091
-1904
lines changed
 

‎compiler/rustc_borrowck/src/lib.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,14 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a,
795795
TerminatorKind::SwitchInt { discr, targets: _ } => {
796796
self.consume_operand(loc, (discr, span), state);
797797
}
798-
TerminatorKind::Drop { place, target: _, unwind: _, replace } => {
798+
TerminatorKind::Drop {
799+
place,
800+
target: _,
801+
unwind: _,
802+
replace,
803+
drop: _,
804+
async_fut: _,
805+
} => {
799806
debug!(
800807
"visit_terminator_drop \
801808
loc: {:?} term: {:?} place: {:?} span: {:?}",

‎compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,14 @@ impl<'a, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'a, 'tcx> {
101101
TerminatorKind::SwitchInt { discr, targets: _ } => {
102102
self.consume_operand(location, discr);
103103
}
104-
TerminatorKind::Drop { place: drop_place, target: _, unwind: _, replace } => {
104+
TerminatorKind::Drop {
105+
place: drop_place,
106+
target: _,
107+
unwind: _,
108+
replace,
109+
drop: _,
110+
async_fut: _,
111+
} => {
105112
let write_kind =
106113
if *replace { WriteKind::Replace } else { WriteKind::StorageDeadOrDrop };
107114
self.access_place(

0 commit comments

Comments
 (0)
Please sign in to comment.