-
Notifications
You must be signed in to change notification settings - Fork 13.4k
if
and else
have incompatible types in a let
statement, where else
block's evaluation will never be assigned
#133316
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
Unfortunately the diagnostic doesn't make this clear (we should fix that) but the culprit isn't the type of the
which leads to an error because |
You might wonder why there's an implicit Consider turning the two 'matches' into a single one for the code to pass compilation: let x = match res {
Ok(x) => x,
Err(e) =>{
cleanup();
return Err(e);
}
}; You can even write it pretty concisely as: let x = res.inspect_err(|_| cleanup())?; |
For the sake of completeness, I will mention that you could theoretically adjust your // Please DON'T! Harness the power of exhaustiveness checking instead!
let x = if let Ok(x) = res {
x // <-- i32
} else if let Err(e) = res {
cleanup();
return Err(e); // <-- /*unconstrained*/
} else {
// We "suppress" the implicit `else {}` / `else { () }` branch by providing an explicit branch
unreachable!() // <-- /*unconstrained*/
}; |
``` error[E0308]: `if` and `else` have incompatible types --> $DIR/if-else-chain-missing-else.rs:12:12 | LL | let x = if let Ok(x) = res { | ______________- LL | | x | | - expected because of this LL | | } else if let Err(e) = res { | | ____________^ LL | || return Err(e); LL | || }; | || ^ | ||_____| | |_____`if` and `else` have incompatible types | expected `i32`, found `()` | = note: `if` expressions without `else` evaluate to `()` = note: consider adding an `else` block that evaluates to the expected type ``` We probably want a longer explanation and fewer spans on this case. Partially address rust-lang#133316.
``` error[E0308]: `if` and `else` have incompatible types --> $DIR/if-else-chain-missing-else.rs:12:12 | LL | let x = if let Ok(x) = res { | ______________- LL | | x | | - expected because of this LL | | } else if let Err(e) = res { | | ____________^ LL | || return Err(e); LL | || }; | || ^ | ||_____| | |_____`if` and `else` have incompatible types | expected `i32`, found `()` | = note: `if` expressions without `else` evaluate to `()` = note: consider adding an `else` block that evaluates to the expected type ``` We probably want a longer explanation and fewer spans on this case. Partially address rust-lang#133316.
``` error[E0308]: `if` and `else` have incompatible types --> $DIR/if-else-chain-missing-else.rs:12:12 | LL | let x = if let Ok(x) = res { | ______________- LL | | x | | - expected because of this LL | | } else if let Err(e) = res { | | ____________^ LL | || return Err(e); LL | || }; | || ^ | ||_____| | |_____`if` and `else` have incompatible types | expected `i32`, found `()` | = note: `if` expressions without `else` evaluate to `()` = note: consider adding an `else` block that evaluates to the expected type ``` We probably want a longer explanation and fewer spans on this case. Partially address rust-lang#133316.
Detect if-else chains with a missing final else in type errors ``` error[E0308]: `if` and `else` have incompatible types --> $DIR/if-else-chain-missing-else.rs:12:12 | LL | let x = if let Ok(x) = res { | ______________- LL | | x | | - expected because of this LL | | } else if let Err(e) = res { | | ____________^ LL | || return Err(e); LL | || }; | || ^ | ||_____| | |_____`if` and `else` have incompatible types | expected `i32`, found `()` | = note: `if` expressions without `else` evaluate to `()` = note: consider adding an `else` block that evaluates to the expected type ``` We probably want a longer explanation and fewer spans on this case. Partially address rust-lang#133316.
Detect if-else chains with a missing final else in type errors ``` error[E0308]: `if` and `else` have incompatible types --> $DIR/if-else-chain-missing-else.rs:12:12 | LL | let x = if let Ok(x) = res { | ______________- LL | | x | | - expected because of this LL | | } else if let Err(e) = res { | | ____________^ LL | || return Err(e); LL | || }; | || ^ | ||_____| | |_____`if` and `else` have incompatible types | expected `i32`, found `()` | = note: `if` expressions without `else` evaluate to `()` = note: consider adding an `else` block that evaluates to the expected type ``` We probably want a longer explanation and fewer spans on this case. Partially address rust-lang#133316.
Rollup merge of rust-lang#135558 - estebank:issue-133316, r=chenyukang Detect if-else chains with a missing final else in type errors ``` error[E0308]: `if` and `else` have incompatible types --> $DIR/if-else-chain-missing-else.rs:12:12 | LL | let x = if let Ok(x) = res { | ______________- LL | | x | | - expected because of this LL | | } else if let Err(e) = res { | | ____________^ LL | || return Err(e); LL | || }; | || ^ | ||_____| | |_____`if` and `else` have incompatible types | expected `i32`, found `()` | = note: `if` expressions without `else` evaluate to `()` = note: consider adding an `else` block that evaluates to the expected type ``` We probably want a longer explanation and fewer spans on this case. Partially address rust-lang#133316.
Uh oh!
There was an error while loading. Please reload this page.
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:
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 theelse if
branch always returns,x
will always be ani32
.Instead, I get this compiler error:
Meta
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: