Open
Description
In the code below, both of the demo_*
functions provoke type inference errors that I believe should not happen.
use std::error::Error;
use std::process::exit;
fn demo_one<F>(f: F) -> ()
where
F: FnOnce() -> Result<(), Box<dyn Error>>,
{
f().or_else(|e| {
eprintln!("{:?}", e);
exit(1)
});
}
fn demo_two<F>(f: F) -> ()
where
F: FnOnce() -> Result<(), Box<dyn Error>>,
{
f().or_else(|e| -> ! {
eprintln!("{:?}", e);
exit(1)
});
}
The errors I observe are (suggestions omitted for space):
error[E0282]: type annotations needed for `Result<(), F>`
--> src/lib.rs:8:17
8 | f().or_else(|e| {
error[E0271]]: expected `[closure@lib.rs:18:17]` to be a closure that returns `Result<(), _>`, but it returns `!`
--> src/lib.rs:18:17
18 | f().or_else(|e| -> ! {
I believe these errors to be incorrect, because:
- Both closures end with a call to
std::process::exit
, which does not return. The return type of the closure indemo_one
should therefore have been inferred to be!
, matching the closure indemo_two
. (Note: whether that call has a;
afterward does not make any difference.) - As documented in https://doc.rust-lang.org/std/primitive.never.html,
!
coerces to any type, therefore a callable which never returns ought to be compatible with a caller expecting any return type.
Meta
rustc --version --verbose
:
rustc 1.69.0 (84c898d65 2023-04-16)
binary: rustc
commit-hash: 84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc
commit-date: 2023-04-16
host: aarch64-unknown-linux-gnu
release: 1.69.0
LLVM version: 15.0.7
Identical behavior observed from nightly (playground link).
Metadata
Metadata
Assignees
Labels
Area: Closures (`|…| { … }`)Area: Messages for errors, warnings, and lintsArea: Type inferenceCategory: This is a bug.Diagnostics: Confusing error or lint that should be reworked.Relevant to the compiler team, which will review and decide on the PR/issue.Relevant to the language team, which will review and decide on the PR/issue.