问题
For example:
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");
}
The compiler prints the error:
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`
The code requires ()
, got RecvError
instead, but the compiler print the opposite.
Is this a bug in the compiler, or have I missed something?
回答1:
On the surface, tokio::run
expects a Future
with associated Error
type ()
, but the actual Future
impl of Receiver
has associated Error
type RecvError
.
However, Rust's type inference works in both directions, and the expected and actual types can sometimes be seen the other way around. Usually the wording of the message fits your expectations, but there are situations like this one where it feels backwards. Of course, it isn't too difficult to work out what is going on and know where the type mis-match is happening even if it isn't reported in the best way.
Codifying the human interpretation of which type is "actual" and which is "expected" might not be an easy problem to solve in the general case, but I agree that this error message is confusing in the code you provided.
I couldn't find an issue about this, but I'm sure I've seen this talked about a few times before. If it's been reported before, it won't do much harm to report it again, so I would just do that.
来源:https://stackoverflow.com/questions/55694827/expected-xyz-found