Async drop box support by azhogin · Pull Request #145316 · rust-lang/rust (original) (raw)
Support for Box async drop.
Support for dyn traits async drop.
This is a draft PR because of experimental solution for dyn traits support.
Dyn traits async drop requires additional vtable slot 'COMMON_VTABLE_ENTRIES_ASYNCDROPINPLACE', similar to 'COMMON_VTABLE_ENTRIES_DROPINPLACE'. This slot exists in any vtable, just without 'async_drop' feature it is set to null.
'AsyncDropInPlaceDyn' is lang item function declared in std library (in alloc):
/// Async drop for usage in vtable
#[lang = "async_drop_in_place_dyn"]
pub unsafe fn async_drop_in_place_dyn<T: ?Sized + 'static>(
to_drop: *mut T,
) -> Pin<Box<dyn Future<Output = ()>>> {
Box::pin(unsafe { async_drop_in_place(to_drop) })
}
This function converts 'async_drop_in_place::{closure}' to common 'Pin<Box<dyn Future<Output = ()>>>'.
And this future, provided by virtual call, is polled in the similar way as 'ordinary' async drop features.
Dyn async drop is expanded in StateTransform into AsyncDropInPlaceDyn lang_item call and is codegen'ed later to virtual call (in the similar way as virtual sync drop call, just with return value). Only implemented in ssa codegen yet.
async_drop_in_place<T>::{closure} is a special case for vtable generation, because such coroutine is its async drop future itself.
To drop this coroutine we need to continue poll it. So, its async drop constructor function in vtable returns its address (from argument), boxed and pinned. 'async_drop_in_place_self' lang item function is used for it.
#[lang = "async_drop_in_place_self"]
pub unsafe fn async_drop_in_place_self(
to_drop: *mut dyn Future<Output = ()>,
) -> Pin<Box<dyn Future<Output = ()>>> {
Box::into_pin(unsafe { Box::from_raw(to_drop) })
}
Fixes #143658.