`unreachable_patterns` fires on match arm that can't be removed.
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
use core::future::Future;
async fn select<A: Future, B: Future>(_: A, _: B) -> Result<A::Output, B::Output> {
todo!()
}
pub async fn wtf() -> ! {
let a = async { loop {} };
let b = async { loop {} };
match select(a, b).await {
Ok(x) => x,
Err(x) => x,
}
}
warns with unreachable_patterns on both arms
warning: unreachable pattern
--> src/lib.rs:11:9
|
11 | Ok(x) => x,
| ^^^^^
|
= note: this pattern matches no values because `Result<!, !>` is uninhabited
= note: `#[warn(unreachable_patterns)]` on by default
but removing either doesn't actually compile
error[E0004]: non-exhaustive patterns: `Ok(_)` not covered
--> src/lib.rs:10:11
|
10 | match select(a, b).await {
| ^^^^^^^^^^^^^^^^^^ pattern `Ok(_)` not covered
|
note: `Result<(), !>` defined here
--> /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:527:1
|
527 | pub enum Result<T, E> {
| ^^^^^^^^^^^^^^^^^^^^^
...
531 | Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
| -- not covered
= note: the matched value is of type `Result<(), !>`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
11 ~ Err(x) => x,
12 ~ Ok(_) => todo!(),
So this code seems "unfixable" with the new lint.
What's happening is the match arm is unreachable, but it still has the "side effect" of making the async block be inferred to Future<Output=!> instead of Future<Output=()>. So, if you remove it the future now gets inferred to return (), and the arm is not unreachable anymore.
In edition 2024 it Just Works if you write match select(a, b).await {}, because the fallback is ! instead of ().
This seems a bit hard to mitigate in Edition 2021, it seems more like an unfortunate combination of the lint and the inference fallback more than a bug. I'm opening the issue anyway to share it, just in case anyone has an idea.
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 by reproducing the linked Playground example in Rust editions 2021 and 2024. Investigate the interaction between the unreachable_patterns lint and async future output inference, including the fallback from ! to (). Done means establishing a decided compiler behavior or mitigation and covering the regression with an appropriate test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 28/100