为什么迭代器的实现在异步上下文中不够通用?

Sta*_*eur 6 rust rust-tokio

在github上交叉发布

鉴于以下代码段:

use futures::stream::{self, StreamExt};

async fn from_bar(bar: &[Vec<&u8>]) {
    let x = bar.iter().flat_map(|i| i.iter().map(|_| async { 42 }));
    let foo: Vec<_> = stream::iter(x).collect().await;
}

#[tokio::main]
async fn main() {
    for bar in vec![] {
        tokio::spawn(async {
            from_bar(bar).await;
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

error[E0308]: mismatched types
  --> src/main.rs:11:9
   |
11 |         tokio::spawn(async {
   |         ^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected type `std::ops::FnOnce<(&&u8,)>`
              found type `std::ops::FnOnce<(&&u8,)>`

error: implementation of `std::iter::Iterator` is not general enough
    --> src/main.rs:11:9
     |
11   |           tokio::spawn(async {
     |           ^^^^^^^^^^^^ implementation of `std::iter::Iterator` is not general enough
     |
     = note: `std::iter::Iterator` would have to be implemented for the type `std::slice::Iter<'0, &u8>`, for any lifetime `'0`...
     = note: ...but `std::iter::Iterator` is actually implemented for the type `std::slice::Iter<'1, &u8>`, for some specific lifetime `'1`
Run Code Online (Sandbox Code Playgroud)

我期待没有错误,因为生命周期对我来说似乎是正确的。请注意,删除main()或删除内部代码from_bar() 都可以消除错误。不仅如此,错误信息也很奇怪。它们可能与编译器中的回归有关,但更重要的是它们似乎在错误的地方(可能相关)。

版本rustc 1.43.0 (4fb7144ed 2020-04-20)

[dependencies]
futures = '0.3.1'

[dependencies.tokio]
version = '0.2'
features = ['full']
Run Code Online (Sandbox Code Playgroud)

Jmb*_*Jmb -1

稍微简单一点的复制:

\n\n
use futures::stream::{self, StreamExt};\n\nasync fn from_bar(bar: &[Vec<&u8>]) {\n    let x = bar.iter().flat_map(|i| i.iter().map(|_| async { 42 }));\n    let foo: Vec<_> = stream::iter(x).collect().await;\n}\n\n#[tokio::main]\nasync fn main() {\n    tokio::spawn(async {\n        from_bar(&vec![]).await;\n    });\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

操场

\n\n

这个示例使问题变得更清楚:您传递给的引用from_bar仅存活到结束main(或者甚至可能是示例中的当前循环迭代),但spawn需要它的存活时间更长,因为生成的任务可能运行更长时间。

\n\n

我不明白的是这如何转化为我们得到的错误消息\xe2\x80\xa6

\n