// run-pass // edition:2021 #![feature(async_fn_in_trait)] use std::future::Future; trait AsyncTrait { #[allow(async_fn_in_trait)] async fn default_impl() { assert!(false); } #[allow(async_fn_in_trait)] async fn call_default_impl() { Self::default_impl().await } } struct AsyncType; impl AsyncTrait for AsyncType { async fn default_impl() { // :) } } async fn async_main() { // Should not assert false AsyncType::call_default_impl().await; } // ------------------------------------------------------------------------- // // Implementation Details Below... use std::pin::Pin; use std::task::*; pub fn noop_waker() -> Waker { let raw = RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE); // SAFETY: the contracts for RawWaker and RawWakerVTable are upheld unsafe { Waker::from_raw(raw) } } const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop); unsafe fn noop_clone(_p: *const ()) -> RawWaker { RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE) } unsafe fn noop(_p: *const ()) {} fn main() { let mut fut = async_main(); // Poll loop, just to test the future... let waker = noop_waker(); let ctx = &mut Context::from_waker(&waker); loop { match unsafe { Pin::new_unchecked(&mut fut).poll(ctx) } { Poll::Pending => {} Poll::Ready(()) => break, } } }