Repository: rust
Issue: rustc non-exhaustive patterns: Misleading error message when `match` arm uses `if` over a general pattern
Labels: A-diagnostics,T-compiler

<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.

If you cannot produce a minimal reproduction case (something that would work in
isolation), please provide the steps or even link to a repository that causes
the problematic output to occur.
-->

Given the following code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f8368327e56743a1f798a6086383804d

```rust
fn main() {
    let some_condition = true;
    let some_option: Option<u8> = None;

    let _res = match some_option {
        Some(val) if some_condition => val,
        None => 0,
    };
}
```

The current output is:

```
Compiling playground v0.0.1 (/playground)
error[[E0004]](https://doc.rust-lang.org/stable/error-index.html#E0004): non-exhaustive patterns: `Some(_)` not covered
 --> src/main.rs:5:22
  |
5 |     let _res = match some_option {
  |                      ^^^^^^^^^^^ pattern `Some(_)` not covered
  |
note: `Option<u8>` defined here
  = note: the matched value is of type `Option<u8>`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
  |
7 ~         None => 0,
8 ~         Some(_) => todo!(),
  |

For more information about this error, try `rustc --explain E0004`.
error: could not compile `playground` due to previous error
```

<!-- The following is not always necessary. -->
The output might rather look like something akin to:


```
Compiling playground v0.0.1 (/playground)
error[[E0004]](https://doc.rust-lang.org/stable/error-index.html#E0004): non-exhaustive patterns: `Some(val) if !some_condition` not covered
 --> src/main.rs:5:22
  |
5 |     let _res = match some_option {
  |                      ^^^^^^^^^^^ pattern `Some(val) if !some_condition` not covered
  |
note: `Option<u8>` defined here
  = note: the matched value is of type `Option<u8>`
  = note: match arms are evaluated from top to bottom. 
  = note: instead of negating the condition of the previous match arm, just match without it to cover other cases
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
  |
7 ~         Some(val) => todo!(),
8 ~         None => 0,
  |

For more information about this error, try `rustc --explain E0004`.
error: could not compile `playground` due to previous error
```

<!--
If the problem is not self-explanatory, please provide a rationale for the
change.
-->

The main pattern `Some(val)` is general and matches identical to `Some(_)`.
The compiler should point to the `match` branch's `if` condition and explain how to match cases not covered by the initial pattern due to the `if` additional condition.

The compiler is misleading by indicating the `Some(val)` pattern did not match in all cases - although the restraint lies in the added `if` - and suggesting `Some(_)` to match all other patterns. The additional `if` condition is entirely ignored.

Ideally, the compiler should suggest two variants:

```rust
fn main() {
    let some_condition = true;
    let some_option: Option<u8> = None;

    let _res = match some_option {
        Some(val) if some_condition => val,
        Some(val) => todo!(),
        None => 0,
    };
}
```

And:
```rust
fn main() {
    let some_condition = true;
    let some_option: Option<u8> = None;

    let _res = match some_option {
        Some(val) if some_condition => val,
        _ => 0,
    };
}
```

<!--
If dramatically different output is caused by small changes, consider also
adding them here.

If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions. The output might also be
different depending on the Edition.
-->

The output on Nightly is identical to the output on Stable.

---

May be related: https://github.com/rust-lang/rust/issues/93611