-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Open
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsD-confusingDiagnostics: Confusing error or lint that should be reworked.Diagnostics: Confusing error or lint that should be reworked.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
This code compiles without errors:
async fn foo() -> Result<(), Box<dyn std::error::Error>> {
async {
Err(anyhow!("oh no"))?;
Ok(())
}.await
}
Adding a return;
in the middle of the async
block makes this code wrong
async fn foo() -> Result<(), Box<dyn std::error::Error>> {
async {
Err(anyhow!("oh no"))?;
return;
Ok(())
}.await
}
and rustc
correctly produces an error. Playground link
However, the error is very confusing:
error[E0277]: the `?` operator can only be used in an async block that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> src/lib.rs:27:30
|
26 | async {
| ___________-
27 | | Err(anyhow!("oh no"))?;
| | ^ cannot use the `?` operator in an async block that returns `()`
28 | | return;
29 | | Ok(())
30 | | }.await
| |_____- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<Result<Infallible, anyhow::Error>>` is not implemented for `()`
error[E0308]: mismatched types
--> src/lib.rs:29:9
|
29 | Ok(())
| ^^^^^^ expected `()`, found enum `Result`
|
= note: expected type `()`
found enum `Result<(), _>`
note: return type inferred to be `()` here
--> src/lib.rs:27:9
|
27 | Err(anyhow!("oh no"))?;
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> src/lib.rs:26:5
|
26 | / async {
27 | | Err(anyhow!("oh no"))?;
28 | | return;
29 | | Ok(())
30 | | }.await
| |___________^ expected enum `Result`, found `()`
|
= note: expected enum `Result<(), Box<(dyn std::error::Error + 'static)>>`
found unit type `()`
help: try adding an expression at the end of the block
|
30 ~ }.await;
31 + Ok(())
|
It simultaneously complains in the first error that the ?
is invalid because the async block returns ()
and then in the next error it says that it inferred the return type to be ()
because of that ?
.
Ideally the compiler could figure out based on the return type of the function that the return;
is the problem here, but at the very least it would be good to not point at the Err(...)?
line as the reason for the return type being inferred as ()
.
Tested on stable 1.59 and nightly 1.61 (2022-03-16).
Metadata
Metadata
Assignees
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsD-confusingDiagnostics: Confusing error or lint that should be reworked.Diagnostics: Confusing error or lint that should be reworked.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.