Inline async iter adapter

planning rfc

This Appendix demonstrates how the inline async iterator adapter works.

#![allow(unused)] fn main() { pub struct InlineAsyncIterator<'me, T: AsyncIterator> { iterator: T, future: MaybeUninit<T::next<'me>>, } impl<T> AsyncIterator for InlineAsyncIterator<T> where T: AsyncIterator, { type Item = T::Item; #[dyn(identity)] // default is "identity" fn next<'a>(&'a mut self) -> InlineFuture<'me, T::next<'me>> { let future: T::next<'a> = MaybeUninit::new(self.iterator.next()); // Why do we need this transmute? Is 'a not sufficient? let future: T::next<'me> = transmute(future); self.future = future; InlineFuture::new(self.future.assume_init_mut()) } } pub struct InlineFuture<'me, F> where F: Future { future: *mut F, phantom &'me mut F } impl<'me, F> InlineFuture<'me, F> { /// Unsafety condition: /// /// `future` must remain valid for all of `'me` pub unsafe fn new(future: *mut F) -> Self { Self { future } } } impl<'me, F> Future for InlineFuture<'me, F> where F: Future, { fn poll(self: Pin<&mut Self>, context: &mut Context) { // Justified by the condition on `new` unsafe { ... } } } impl<F> IntoRawPointer for InlineFuture<F> { type Target = F; // This return value is the part that has to be thin. fn into_raw(self) -> *mut Self::Target { self.future } // This will be the drop function in the vtable. unsafe fn drop_raw(this: *mut Self::Target) { unsafe { drop_in_place(self.future) } } } impl<'me> Drop for InlineFuture<'me, F> { fn drop(&mut self) { unsafe { <Self as IntoRawPointer>::drop_raw(self.future); } } } }