Open zackw opened 1 year ago
@rustbot label A-inference
Current output:
error[E0282]: type annotations needed for `Result<(), F>`
--> f71.rs:8:17
|
8 | f().or_else(|e| {
| ^^^
|
help: try giving this closure an explicit return type
|
8 | f().or_else(|e| -> Result<(), F> {
| ++++++++++++++++
error[E0271]: expected `[closure@f71.rs:18:17]` to be a closure that returns `Result<(), _>`, but it returns `!`
--> f71.rs:18:17
|
18 | f().or_else(|e| -> ! {
| _________-------_^
| | |
| | required by a bound introduced by this call
19 | | eprintln!("{:?}", e);
20 | | exit(1)
21 | | });
| |_____^ expected `Result<(), _>`, found `!`
|
= note: expected enum `Result<(), _>`
found type `!`
note: required by a bound in `Result::<T, E>::or_else`
--> /home/gh-estebank/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:1379:39
|
1379 | pub fn or_else<F, O: FnOnce(E) -> Result<T, F>>(self, op: O) -> Result<T, F> {
| ^^^^^^^^^^^^ required by this bound in `Result::<T, E>::or_else`
I'm running into this same issue with a closure that calls panic!
with rustc 1.81.0 (eeb90cda1 2024-09-04)
Rustc 1.82.0 gives same output as 1.81.0.
Note that the way to write this is by making the closures return Result<(), Box<dyn Error>
and make their bodies be !
(which in both cases they already are). I don't think this is necessarily a limitation of the type system/inference (although an RFC could be written to make Fn() -> !
be accepted anywhere for<T> Fn() -> T
is), but rather bad compiler diagnostics.
https://doc.rust-lang.org/std/primitive.never.html says !
coerces to any type, so I think this is a type system/inference issue; it should not be necessary to give these closures a return type; whatever the compiler thinks the closure's return type needs to be, !
should satisfy it.
@zackw even when !
is the explicit return type? I can buy the argument that a closure with inferred !
return type should be accepted, but the explicit case isn't as clear to me.
In the code below, both of the
demo_*
functions provoke type inference errors that I believe should not happen.The errors I observe are (suggestions omitted for space):
I believe these errors to be incorrect, because:
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.)!
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
:Identical behavior observed from nightly (playground link).