Open shanebishop opened 4 days ago
Unfortunately the diagnostic doesn't make this clear (we should fix that) but the culprit isn't the type of the else if
branch, it's the type of the implicit else
branch: There's an invisible else {}
/ else { () }
at the end of the if-expression. As a result of that the type checker tries to unify three types:
i32
,/*unconstrained*/
()
which leads to an error because i32
and ()
aren't compatible.
You might wonder why there's an implicit else {}
/ else { () }
at all if the two branches seemingly cover the whole input space (Ok(_)
and Err(_)
for Result<_, _>
). Well, in this case the checks are two separate pattern matches from the perspective of the exhaustiveness checker and therefore the match on Err(_)
doesn't count towards the exhaustiveness of the first match that contains the Ok(_)
! Rust doesn't have flow-sensitive typing.
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 if let … else if let
the following way to make your code compile but that's ill-advised:
// 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*/
};
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
: