1 | #![allow (clippy::diverging_sub_expression)] |
2 | |
3 | use std::rc::Rc; |
4 | |
5 | #[allow (dead_code)] |
6 | type BoxStream<T> = std::pin::Pin<Box<dyn tokio_stream::Stream<Item = T>>>; |
7 | |
8 | #[allow (dead_code)] |
9 | fn require_send<T: Send>(_t: &T) {} |
10 | #[allow (dead_code)] |
11 | fn require_sync<T: Sync>(_t: &T) {} |
12 | #[allow (dead_code)] |
13 | fn require_unpin<T: Unpin>(_t: &T) {} |
14 | |
15 | #[allow (dead_code)] |
16 | struct Invalid; |
17 | |
18 | trait AmbiguousIfSend<A> { |
19 | fn some_item(&self) {} |
20 | } |
21 | impl<T: ?Sized> AmbiguousIfSend<()> for T {} |
22 | impl<T: ?Sized + Send> AmbiguousIfSend<Invalid> for T {} |
23 | |
24 | trait AmbiguousIfSync<A> { |
25 | fn some_item(&self) {} |
26 | } |
27 | impl<T: ?Sized> AmbiguousIfSync<()> for T {} |
28 | impl<T: ?Sized + Sync> AmbiguousIfSync<Invalid> for T {} |
29 | |
30 | trait AmbiguousIfUnpin<A> { |
31 | fn some_item(&self) {} |
32 | } |
33 | impl<T: ?Sized> AmbiguousIfUnpin<()> for T {} |
34 | impl<T: ?Sized + Unpin> AmbiguousIfUnpin<Invalid> for T {} |
35 | |
36 | macro_rules! into_todo { |
37 | ($typ:ty) => {{ |
38 | let x: $typ = todo!(); |
39 | x |
40 | }}; |
41 | } |
42 | |
43 | macro_rules! async_assert_fn { |
44 | ($($f:ident $(< $($generic:ty),* > )? )::+($($arg:ty),*): Send & Sync) => { |
45 | #[allow(unreachable_code)] |
46 | #[allow(unused_variables)] |
47 | const _: fn() = || { |
48 | let f = $($f $(::<$($generic),*>)? )::+( $( into_todo!($arg) ),* ); |
49 | require_send(&f); |
50 | require_sync(&f); |
51 | }; |
52 | }; |
53 | ($($f:ident $(< $($generic:ty),* > )? )::+($($arg:ty),*): Send & !Sync) => { |
54 | #[allow(unreachable_code)] |
55 | #[allow(unused_variables)] |
56 | const _: fn() = || { |
57 | let f = $($f $(::<$($generic),*>)? )::+( $( into_todo!($arg) ),* ); |
58 | require_send(&f); |
59 | AmbiguousIfSync::some_item(&f); |
60 | }; |
61 | }; |
62 | ($($f:ident $(< $($generic:ty),* > )? )::+($($arg:ty),*): !Send & Sync) => { |
63 | #[allow(unreachable_code)] |
64 | #[allow(unused_variables)] |
65 | const _: fn() = || { |
66 | let f = $($f $(::<$($generic),*>)? )::+( $( into_todo!($arg) ),* ); |
67 | AmbiguousIfSend::some_item(&f); |
68 | require_sync(&f); |
69 | }; |
70 | }; |
71 | ($($f:ident $(< $($generic:ty),* > )? )::+($($arg:ty),*): !Send & !Sync) => { |
72 | #[allow(unreachable_code)] |
73 | #[allow(unused_variables)] |
74 | const _: fn() = || { |
75 | let f = $($f $(::<$($generic),*>)? )::+( $( into_todo!($arg) ),* ); |
76 | AmbiguousIfSend::some_item(&f); |
77 | AmbiguousIfSync::some_item(&f); |
78 | }; |
79 | }; |
80 | ($($f:ident $(< $($generic:ty),* > )? )::+($($arg:ty),*): !Unpin) => { |
81 | #[allow(unreachable_code)] |
82 | #[allow(unused_variables)] |
83 | const _: fn() = || { |
84 | let f = $($f $(::<$($generic),*>)? )::+( $( into_todo!($arg) ),* ); |
85 | AmbiguousIfUnpin::some_item(&f); |
86 | }; |
87 | }; |
88 | ($($f:ident $(< $($generic:ty),* > )? )::+($($arg:ty),*): Unpin) => { |
89 | #[allow(unreachable_code)] |
90 | #[allow(unused_variables)] |
91 | const _: fn() = || { |
92 | let f = $($f $(::<$($generic),*>)? )::+( $( into_todo!($arg) ),* ); |
93 | require_unpin(&f); |
94 | }; |
95 | }; |
96 | } |
97 | |
98 | async_assert_fn!(tokio_stream::empty<Rc<u8>>(): Send & Sync); |
99 | async_assert_fn!(tokio_stream::pending<Rc<u8>>(): Send & Sync); |
100 | async_assert_fn!(tokio_stream::iter(std::vec::IntoIter<u8>): Send & Sync); |
101 | |
102 | async_assert_fn!(tokio_stream::StreamExt::next(&mut BoxStream<()>): !Unpin); |
103 | async_assert_fn!(tokio_stream::StreamExt::try_next(&mut BoxStream<Result<(), ()>>): !Unpin); |
104 | async_assert_fn!(tokio_stream::StreamExt::all(&mut BoxStream<()>, fn(())->bool): !Unpin); |
105 | async_assert_fn!(tokio_stream::StreamExt::any(&mut BoxStream<()>, fn(())->bool): !Unpin); |
106 | async_assert_fn!(tokio_stream::StreamExt::fold(&mut BoxStream<()>, (), fn((), ())->()): !Unpin); |
107 | async_assert_fn!(tokio_stream::StreamExt::collect<Vec<()>>(&mut BoxStream<()>): !Unpin); |
108 | |