Skip to content

Confusing: Implementation of FnOnce is not general enough #89976

Open
@Darksonn

Description

@Darksonn

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();
}

playground

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions