找到预期的 XYZ ()

Expected XYZ found ()

例如:

use futures::future::Future;

fn main() {
    let (stop_tokio, time_to_stop) = tokio::sync::oneshot::channel::<()>();
    let handler = std::thread::spawn(|| {
        tokio::run(
            time_to_stop, //           .map_err(|_| ())
        );
    });
    handler.join().expect("join failed");
}

编译器打印错误:

error[E0271]: type mismatch resolving `<tokio_sync::oneshot::Receiver<()> as futures::future::Future>::Error == ()`
 --> src/main.rs:6:9
  |
6 |         tokio::run(
  |         ^^^^^^^^^^ expected struct `tokio_sync::oneshot::error::RecvError`, found ()
  |
  = note: expected type `tokio_sync::oneshot::error::RecvError`
             found type `()`
  = note: required by `tokio::runtime::threadpool::run`

代码需要 (),得到的却是 RecvError,但编译器打印出相反的结果。

这是编译器中的错误,还是我遗漏了什么?

从表面上看,tokio::run 期望 具有关联 Error 类型 ()Future,但是 actual Future Receiver 的实现关联了 Error 类型 RecvError.

然而,Rust 的类型推断是双向的,预期类型和实际类型有时可以反过来看。 通常消息的措辞符合您的期望,但也有像这种情况那样让人感觉倒退的情况。当然,即使没有以最佳方式报告,也不难弄清楚发生了什么并知道类型不匹配发生在哪里。

将人类对哪种类型是 "actual" 和哪种类型是 "expected" 的解释编码可能不是一个在一般情况下很容易解决问题,但我同意此错误消息在您提供的代码中令人困惑。

我找不到关于此的问题,但我确信我之前已经看到过几次关于此的讨论。如果以前被举报过,再举报也没什么坏处,所以我就这么做了。