FromResidual is from std: FromResidual in std::ops - Rust.
Here's a simplified example that triggers the same* error:
fn main() {
async {
something()?;
};
}
fn something() -> Result<(), ()> {
todo!()
}
Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `(): FromResidual<Result<Infallible, ()>>` is not satisfied
--> src/main.rs:2:11
|
2 | async {
| ___________-
3 | | something()?;
4 | | };
| | ^
| | |
| |_____the trait `FromResidual<Result<Infallible, ()>>` is not implemented for `()`
| required by a bound introduced by this call
For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` due to previous error
This is a case of a bad error message. Without the future we get a much better one:
fn main() {
something()?;
}
fn something() -> Result<(), ()> {
todo!()
}
Compiling playground v0.0.1 (/playground)
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> src/main.rs:2:16
|
1 | / fn main() {
2 | | something()?;
| | ^ cannot use the `?` operator in a function that returns `()`
3 | | }
| |_- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<Result<Infallible, ()>>` is not implemented for `()`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` due to previous error
So the issue here is that the future created by the async block returns the unit type ()
. As you may know, you can only use ?
in functions that return a Result or Option (or, as the error message says, another type that implements FromResidual). If we instead make it so the async block returns such a type:
fn main() {
async {
something()?;
Ok(())
};
}
fn something() -> Result<(), ()> {
todo!()
}
We get a different error:
Compiling playground v0.0.1 (/playground)
error[E0282]: type annotations needed
--> src/main.rs:4:9
|
4 | Ok(())
| ^^ cannot infer type for type parameter `E` declared on the enum `Result`
For more information about this error, try `rustc --explain E0282`.
error: could not compile `playground` due to previous error
Now it's complaining that it doesn't know what the error type is. If we annotate the full type of the result:
fn main() {
async {
something()?;
Result::<(), ()>::Ok(())
};
}
fn something() -> Result<(), ()> {
todo!()
}
We no longer get any errors.
*You didn't post the full error but I'm assuming this is the same
edit: I thought the error message was confusing enough to warrant an issue and I couldn't find an existing one so I created Improve error message when trying to use `?` in an async block that does not return a FromResidual type · Issue #94944 · rust-lang/rust · GitHub