I need to select a TCP connection that is writable.
I wrote a seemingly innocent async function using futures buffer_unordered and to my surprise it compiled the first time. But when I actually tried to call it from underneath a tokio::spawn
, the compiler didn't like it.
I paste a minimized example:
tokio::spawn(async move {
let mirrors: Vec<OwnedWriteHalf> = Vec::new();
futures::stream::iter(&mirrors)
.map(|s| s.writable())
.buffer_unordered(mirrors.len())
.next()
.await;
});
Error message:
error: implementation of `FnOnce` is not general enough
--> src/lib.rs:305:9
|
305 | tokio::spawn(async move {
| ^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'0 tokio::net::tcp::OwnedWriteHalf) -> impl futures::Future<Output = std::result::Result<(), std::io::Error>>` must implement `FnOnce<(&tokio::net::tcp::OwnedWriteHalf,)>`, for any lifetime `'0`...
= note: ...but it actually implements `FnOnce<(&tokio::net::tcp::OwnedWriteHalf,)>`
The error disappears when I remove .await
.
Or it disappears if I remove buffer_unordered
but call .await
on the first item in the vector (I mean mirrors[0].writable().await
), even though ti doesn't make much sense on an empty vector.