use std::rc::Rc; #[allow(dead_code)] type BoxStream = std::pin::Pin>>; #[allow(dead_code)] fn require_send(_t: &T) {} #[allow(dead_code)] fn require_sync(_t: &T) {} #[allow(dead_code)] fn require_unpin(_t: &T) {} #[allow(dead_code)] struct Invalid; trait AmbiguousIfSend { fn some_item(&self) {} } impl AmbiguousIfSend<()> for T {} impl AmbiguousIfSend for T {} trait AmbiguousIfSync { fn some_item(&self) {} } impl AmbiguousIfSync<()> for T {} impl AmbiguousIfSync for T {} trait AmbiguousIfUnpin { fn some_item(&self) {} } impl AmbiguousIfUnpin<()> for T {} impl AmbiguousIfUnpin for T {} macro_rules! into_todo { ($typ:ty) => {{ let x: $typ = todo!(); x }}; } macro_rules! async_assert_fn { ($($f:ident $(< $($generic:ty),* > )? )::+($($arg:ty),*): Send & Sync) => { #[allow(unreachable_code)] #[allow(unused_variables)] const _: fn() = || { let f = $($f $(::<$($generic),*>)? )::+( $( into_todo!($arg) ),* ); require_send(&f); require_sync(&f); }; }; ($($f:ident $(< $($generic:ty),* > )? )::+($($arg:ty),*): Send & !Sync) => { #[allow(unreachable_code)] #[allow(unused_variables)] const _: fn() = || { let f = $($f $(::<$($generic),*>)? )::+( $( into_todo!($arg) ),* ); require_send(&f); AmbiguousIfSync::some_item(&f); }; }; ($($f:ident $(< $($generic:ty),* > )? )::+($($arg:ty),*): !Send & Sync) => { #[allow(unreachable_code)] #[allow(unused_variables)] const _: fn() = || { let f = $($f $(::<$($generic),*>)? )::+( $( into_todo!($arg) ),* ); AmbiguousIfSend::some_item(&f); require_sync(&f); }; }; ($($f:ident $(< $($generic:ty),* > )? )::+($($arg:ty),*): !Send & !Sync) => { #[allow(unreachable_code)] #[allow(unused_variables)] const _: fn() = || { let f = $($f $(::<$($generic),*>)? )::+( $( into_todo!($arg) ),* ); AmbiguousIfSend::some_item(&f); AmbiguousIfSync::some_item(&f); }; }; ($($f:ident $(< $($generic:ty),* > )? )::+($($arg:ty),*): !Unpin) => { #[allow(unreachable_code)] #[allow(unused_variables)] const _: fn() = || { let f = $($f $(::<$($generic),*>)? )::+( $( into_todo!($arg) ),* ); AmbiguousIfUnpin::some_item(&f); }; }; ($($f:ident $(< $($generic:ty),* > )? )::+($($arg:ty),*): Unpin) => { #[allow(unreachable_code)] #[allow(unused_variables)] const _: fn() = || { let f = $($f $(::<$($generic),*>)? )::+( $( into_todo!($arg) ),* ); require_unpin(&f); }; }; } async_assert_fn!(tokio_stream::empty>(): Send & Sync); async_assert_fn!(tokio_stream::pending>(): Send & Sync); async_assert_fn!(tokio_stream::iter(std::vec::IntoIter): Send & Sync); async_assert_fn!(tokio_stream::StreamExt::next(&mut BoxStream<()>): !Unpin); async_assert_fn!(tokio_stream::StreamExt::try_next(&mut BoxStream>): !Unpin); async_assert_fn!(tokio_stream::StreamExt::all(&mut BoxStream<()>, fn(())->bool): !Unpin); async_assert_fn!(tokio_stream::StreamExt::any(&mut BoxStream<()>, fn(())->bool): !Unpin); async_assert_fn!(tokio_stream::StreamExt::fold(&mut BoxStream<()>, (), fn((), ())->()): !Unpin); async_assert_fn!(tokio_stream::StreamExt::collect>(&mut BoxStream<()>): !Unpin);