Skip to content

Commit

Permalink
Auto merge of rust-lang#124662 - zetanumbers:needs_async_drop, r=oli-obk
Browse files Browse the repository at this point in the history
Implement `needs_async_drop` in rustc and optimize async drop glue

This PR expands on rust-lang#121801 and implements `Ty::needs_async_drop` which works almost exactly the same as `Ty::needs_drop`, which is needed for rust-lang#123948.

Also made compiler's async drop code to look more like compiler's regular drop code, which enabled me to write an optimization where types which do not use `AsyncDrop` can simply forward async drop glue to `drop_in_place`. This made size of the async block from the [async_drop test](https://github.com/zetanumbers/rust/blob/67980dd6fb11917d23d01a19c2cf4cfc3978aac8/tests/ui/async-await/async-drop.rs) to decrease by 12%.
  • Loading branch information
bors committed May 31, 2024
2 parents ba98164 + bb6d4eb commit 9fe1803
Showing 1 changed file with 13 additions and 0 deletions.
13 changes: 13 additions & 0 deletions core/src/future/async_drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ async unsafe fn surface_drop_in_place<T: Drop + ?Sized>(ptr: *mut T) {
/// wrapped future completes by returning `Poll::Ready(())` on poll. This
/// is useful for constructing async destructors to guarantee this
/// "fuse" property
//
// FIXME: Consider optimizing combinators to not have to use fuse in majority
// of cases, perhaps by adding `#[(rustc_)idempotent(_future)]` attribute for
// async functions and blocks with the unit return type. However current layout
// optimizations currently encode `None` case into the async block's discriminant.
struct Fuse<T> {
inner: Option<T>,
}
Expand Down Expand Up @@ -251,6 +256,14 @@ async unsafe fn either<O: IntoFuture<Output = ()>, M: IntoFuture<Output = ()>, T
}
}

#[cfg(not(bootstrap))]
#[lang = "async_drop_deferred_drop_in_place"]
async unsafe fn deferred_drop_in_place<T>(to_drop: *mut T) {
// SAFETY: same safety requirements as with drop_in_place (implied by
// function's name)
unsafe { crate::ptr::drop_in_place(to_drop) }
}

/// Used for noop async destructors. We don't use [`core::future::Ready`]
/// because it panics after its second poll, which could be potentially
/// bad if that would happen during the cleanup.
Expand Down

0 comments on commit 9fe1803

Please sign in to comment.