Open
Description
Someone on the Tokio discord came across the following bad compiler error message. Given the following code:
use std::sync::Arc;
use futures::stream::{self, StreamExt};
struct MyStruct {}
impl MyStruct {
async fn import_all(&self, list: Arc<Vec<String>>) {
stream::iter(&*list)
.map(|txn| {
let bd_c = list.clone();
async move { self.import(bd_c, txn).await }
})
.buffer_unordered(10)
.collect::<Vec<bool>>()
.await;
}
async fn import(&self, list: Arc<Vec<String>>, now: &str) -> bool {
list.iter().any(|v| v == now)
}
}
#[tokio::main]
async fn main() {
let ms = MyStruct {};
tokio::spawn(async move {
ms.import_all(Arc::new(vec![])).await;
}).await.unwrap();
}
The current output is:
error: implementation of `FnOnce` is not general enough
--> src/main.rs:27:5
|
27 | tokio::spawn(async move {
| ^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'0 String) -> impl futures::Future` must implement `FnOnce<(&String,)>`, for any lifetime `'0`...
= note: ...but it actually implements `FnOnce<(&String,)>`
This is an incredibly confusing error message, and it isn't in the right place. This fix is to change import
to take an index instead of a reference in the last argument. Interestingly if you remove the main function, the error disappears. If you replace the import_all
function with a function returning a boxed future, then the error happens in the import_all
function instead.
cc @ryanobjc