`if` and `else` have incompatible types in a `let` statement, where `else` block's evaluation will never be assigned
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.2k
- PR merge metrics
- PR metrics pending
Description
I apologize if this was already reported in a separate issue, or if this is a known issue - I wasn't sure how to best search for previous issues like this.
I also realize this might not be a "bug" per se, but the other issue templates didn't seem to quite fit either.
I tried this code:
enum Cause { Cause1, Cause2 }
struct MyErr { x: Cause }
fn main() {
_ = f();
}
fn f() -> Result<i32, MyErr> {
let res = could_fail();
let x = if let Ok(x) = res {
x
} else if let Err(e) = res {
cleanup();
return Err(e);
};
Ok(x)
}
fn could_fail() -> Result<i32, MyErr> {
// ... code that could fail and return an Err ...
Ok(0)
}
fn cleanup() {
// ... cleanup code ...
}
Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=60acf4e59e3c6403104e01aa409aa395
I expected the code to compile successfully, since the else if branch unconditionally returns. Because the else if branch always returns, x will always be an i32.
Instead, I get this compiler error:
error[E0308]: `if` and `else` have incompatible types
--> src/main.rs:12:12
|
10 | let x = if let Ok(x) = res {
| ______________-
11 | | x
| | - expected because of this
12 | | } else if let Err(e) = res {
| | ____________^
13 | || cleanup();
14 | || return Err(e);
15 | || };
| || ^
| ||_____|
| |_____`if` and `else` have incompatible types
| expected `i32`, found `()`
Meta
rustc --version --verbose:
rustc 1.82.0 (f6e511eec 2024-10-15)
binary: rustc
commit-hash: f6e511eec7342f59a25f7c0534f1dbea00d01b14
commit-date: 2024-10-15
host: x86_64-unknown-linux-gnu
release: 1.82.0
LLVM version: 19.1.1
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the minimal Rust Playground reproducer and the rustc 1.82.0 diagnostic; compare stable, beta, and nightly as suggested by the report. Trace how the compiler handles the if-let/else-if expression and its diverging return branch, and establish whether the behavior should change or is intended.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100