Commit 87e4c91
authored
Fixes a case where
Closes #16875
### What was wrong
The lint suggested collapsing `pattern => { if test { body } }` into
`pattern if test => { body }`. These are not equivalent. In the
original, once `pattern` matches, the match exits regardless of `test`.
In the suggestion, a failing guard allows fall-through to subsequent
arms, which can match values that previously never reached them.
```rust
// Before (original)
match a {
Some(_) => {
if b == 0 { res = 1 }
}
_ if b == 1 => res = 2, // unreachable when a is Some(_)
_ => {}
}
// After (suggestion — WRONG, changes behavior)
match a {
Some(_) if b == 0 => res = 1,
_ if b == 1 => res = 2, // now reachable when a is Some(_) and b != 0
_ => {}
}
```
### Fix
The `if`-guard collapsing is only safe when there are no non-wildcard
arms between the current arm and the wildcard arm. The fix adds a check
that all arms after the current one are "wild-like" (a bare `_`, a
binding, or `None`, all without guards) before suggesting the
transformation.
As a side effect, three `#[expect(clippy::collapsible_match)]`
suppressions in `clippy_lints/src/methods/mod.rs` are removed. They had
been added to suppress this exact false positive and are no longer
needed.
### Still lints correctly
When only wildcard arms follow, the transformation is safe and the lint
still fires:
```rust
// This still lints — only `_ => {}` follows, fall-through is harmless
match a {
Some(_) => {
if b == 0 { res = 1 } // triggers collapsible_match
}
_ => {}
}
```
changelog: [`collapsible_match`]: no longer suggests collapsing `pattern
=> { if test { body } }` into a match guard when non-wildcard arms
follow, as this changes the semantics of the match.
<!-- TRIAGEBOT_START -->
<!-- TRIAGEBOT_SUMMARY_START -->
### Summary Notes
-
[Beta-nomination](#16878 (review))
by [samueltardieu](https://github.com/samueltardieu)
*Managed by `@rustbot`—see
[help](https://forge.rust-lang.org/triagebot/note.html) for details*
<!-- TRIAGEBOT_SUMMARY_END -->
<!-- TRIAGEBOT_END -->collapsible_match suggested a transformation that changes runtime behavior. (#16878)6 files changed
Lines changed: 89 additions & 11 deletions
File tree
- clippy_lints/src
- matches
- methods
- tests/ui
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
26 | | - | |
27 | | - | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
28 | 40 | | |
29 | 41 | | |
30 | 42 | | |
| |||
37 | 49 | | |
38 | 50 | | |
39 | 51 | | |
40 | | - | |
| 52 | + | |
41 | 53 | | |
42 | 54 | | |
43 | 55 | | |
| |||
50 | 62 | | |
51 | 63 | | |
52 | 64 | | |
| 65 | + | |
53 | 66 | | |
54 | 67 | | |
55 | 68 | | |
| |||
126 | 139 | | |
127 | 140 | | |
128 | 141 | | |
| 142 | + | |
129 | 143 | | |
130 | 144 | | |
131 | 145 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5221 | 5221 | | |
5222 | 5222 | | |
5223 | 5223 | | |
5224 | | - | |
5225 | 5224 | | |
5226 | 5225 | | |
5227 | 5226 | | |
| |||
5546 | 5545 | | |
5547 | 5546 | | |
5548 | 5547 | | |
5549 | | - | |
5550 | | - | |
5551 | | - | |
| 5548 | + | |
5552 | 5549 | | |
5553 | 5550 | | |
5554 | 5551 | | |
| |||
5653 | 5650 | | |
5654 | 5651 | | |
5655 | 5652 | | |
5656 | | - | |
5657 | | - | |
5658 | | - | |
| 5653 | + | |
5659 | 5654 | | |
5660 | 5655 | | |
5661 | 5656 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
390 | 390 | | |
391 | 391 | | |
392 | 392 | | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
393 | 413 | | |
394 | 414 | | |
395 | 415 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
49 | | - | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
50 | 68 | | |
0 commit comments