-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
single_match
should not lint exhaustive match
#8282
Comments
The problem is in this line, for some reasons |
I think the important thing here is that there is no wild pattern ( |
There's also |
The presence of Also, a wild in a branch with an |
I'm not sure what you mean. "non-exhaustive" means the match doesn't cover all cases.
Right. |
Oh you're right, there's a crack in my logic somewhere... I guess the criteria should be "the 'else' branch contains a wild". |
I think the lint should only trigger if one of the match arms is a "catch-all", where "catch-all" is defined as:
|
I see. The definition needs to be recursive though so that else_pat.walk_short(|p| {
if matches!(p.kind, Path | Lit | Range | Slice) {
// not exhaustive
}
}) |
What do you mean by "else branch"? E.g., there can be multiple wildcard branches, possibly overlapping. |
The lint detects a |
Ah, then I think your definition from above is correct:
|
Well, as far as I understood from the original zulip message, the problem is that the user wants to lint only exhaustive matches. They want to match explicitly defined cases by them own, to avoid possible regressions, when changing the data structure to be matched. So, what we actually want here is to avoid running this check if there is no wildcard matches. Consider the following examples (they may be included as tests): // We can't actually write non-exhaustive matching for ranges, because compiler will force us
// to write exhaustive match anyway. The two examples below will be linted.
match (1u8, 1u8) {
(1, 2) => (),
(_, _) => (),
}
match (1u8, 1u8) {
(1, 2) => (),
_ => (),
}
enum E {
V1(u32),
}
// Don't lint. The point is that `E` enum could be extended later. So, if the user will apply
// the suggested lint, they may lose information that the added field must be hanlded here too.
match Some(E::V1(42)) {
Some(E::V1(_)) => (),
None => (),
}
// Do lint, because the user doesn't care about the type inside `Some`.
match Some(E::V1(42)) {
Some(_) => (),
None => (),
}
struct S {
f1: u32,
f2: i32,
}
// I think, we should lint in all these cases, because applying the refactoring suggested by
// the linter could not cause errors.
match Some(S { f1: 1, f2: 2 }) {
Some(S { f1, f2 }) => (),
None => (),
}
match Some(S { f1: 1, f2: 2 }) {
Some(S { .. }) => (),
None => (),
}
match Some(S { f1: 1, f2: 2 }) {
Some(S { f1, .. }) => (),
None => (),
}
match Some(S { f1: 1, f2: 2 }) {
Some(_) => (),
None => (),
} What do you think? |
@rustbot claim |
This keeps getting more complicated... Consider these examples: // don't lint
match x {
(Some(E::V), _) => todo!(),
(None, _) => {}
}
// lint
match x {
(Some(_), _) => todo!(),
(None, _) => {}
}
// lint
match x {
(Some(E::V), _) => todo!(),
(_, _) => {}
} I think we have to walk the two patterns at the same time in order to detect a pairing like |
single_match: Don't lint non-exhaustive matches; support tuples `single_match` lint: * Don't lint exhaustive enum patterns without a wild. Rationale: The definition of the enum could be changed, so the user can get non-exhaustive match after applying the suggested lint (see #8282 (comment) for context). * Lint `match` constructions with tuples (as suggested at #8282 (comment)) Closes #8282
single_match: Don't lint non-exhaustive matches; support tuples `single_match` lint: * Don't lint exhaustive enum patterns without a wild. Rationale: The definition of the enum could be changed, so the user can get non-exhaustive match after applying the suggested lint (see #8282 (comment) for context). * Lint `match` constructions with tuples (as suggested at #8282 (comment)) Closes #8282 --- changelog: [`single_match`]: Don't lint exhaustive enum patterns without a wild. changelog: [`single_match`]: Lint `match` constructions with tuples
Summary
single_match
should not lint an exhaustivematch
Lint Name
single_match
Reproducer
I tried this code:
I saw this happen:
I expected to see this happen: nothing
Version
No response
Additional Labels
No response
The text was updated successfully, but these errors were encountered: