关于 Rust 中的 Boxed Future 的编译器错误消息有点令人困惑

sou*_*ics 0 future rust

我似乎不明白这里的编译器错误消息。对于以下代码片段

use std::pin::Pin;
use std::future::Future;

fn give_future<'a>(x : &'a i32) -> Pin<impl Future<Output=&'a i32> + 'a> {
    Box::pin(async move { x })
}
Run Code Online (Sandbox Code Playgroud)

它说以下内容

error[E0277]: `[async block@src/lib.rs]` cannot be unpinned
 --> src/lib.rs:7:47
  |
  | fn give_future<'a>(x : &'a i32) -> Pin<impl Future<Output=&'a i32> + 'a> {
  |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unpin` is not implemented for `[async block@src/lib.rs]`
  |
  = note: consider using the `pin!` macro
          consider using `Box::pin` if you need to access the pinned value outside of the current scope
  = note: required for `Box<[async block@src/lib.rs]>` to implement `Future`

For more information about this error, try `rustc --explain E0277`.
Run Code Online (Sandbox Code Playgroud)

据我了解,Pinx<Box<impl Future>>返回为Pin<impl Future>. 为什么编译器不直接这么说呢?

kmd*_*eko 5

据我了解,Pin<Box<impl Future>>返回为Pin<impl Future>. 为什么编译器不直接这么说呢?

您所写内容的基础可能是一件完全可行的事情。可能不是Pin特别的(因为它的功能非常狭窄且细致入微),但伪装Box<T>impl Trait一直在做的事情,以避免泄漏内部细节并且可以工作,因为特征通常在Box<T>s where上实现T: Trait

所以编译器只是想满足你的要求。为此,它只需要验证是否Box<T>实现Future,并且它有一个实现,但前提是该T实现Unpin。因此你会得到错误。