-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Be more specific on non-exhaustive matches on non-sum-types #105479
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
Comments
So what ideally output would you suggest? |
I'd want us to add some text about how the final match arm should cover every possible value of a (&str, &str). |
@rustbot claim |
Sorry, should have asked before claiming. @lyming2007 were you gonna work on this? |
@estebank While implementing this to check for strings, both single strings and as members of a tuple, I noticed some differences for enums. enum Enum {
One,
Two,
Three,
}
fn main() {
use Enum::*;
let a = One;
let b = Two;
match (a, b) {
(One, One) => {}
(Two, One) => {}
//(Three, _) => {}
}
}
If you follow the suggestion, this is the following output
It includes both "patterns not covered" and the full wildcard arm. Shouldn't they have similar diagnostics since they're effectively the same case, except for the position in the tuple? |
no problem. Go ahead please. :) |
Yes they should. I'm guessing we have an early return in the pattern exhaustiveness check that trips up the suggestion. If you can fix it, that'd be great, but don't spend yourself on it if you can't, just open a ticket for that case. As long as invalid code continues to be rejected, and the subsequent suggestions get you there, the status quo is ok. |
The difference of diagnostic is due to how exhaustiveness is implemented: it looks at patterns from left to right, and bails as soon as it's sure that something is missing. Avoiding the asymmetry isn't unthinkable but would need a deep rewrite the algorithm |
As far as fixing this issue is concerned, I can give some pointers. We want to detect when the user is matching on a type that can't be matched exhaustively and tell them what's happening. A check exactly like this is already done for So as a first step we need to change the Note the match Some("") {
None => {}
}
match Some("") {
None => {}
Some("a") => {}
Some("b") => {}
} Both cases report |
@rustbot release-assignment |
Work in that direction is being done in #114397 |
The first part of what I suggested has been merged in #114397! What remains to be done is to add more cases to this if statement. We want to test for |
sure, I've opened a PR!
I'm not sure I understand why we want this. Is |
No sorry, I'm talking about doing two different things. The first thing is handling The second thing is changing how we handle the The logic of |
Thanks for the explanation! I tried adding the check but it seems that when matching on non-exhaustive enums, the witness's constructor is Wildcard instead of |
…eril Add note on non-exhaustiveness when matching on str and nested non-exhaustive enums Fixes rust-lang#105479 r? `@Nadrieril`
Add note on non-exhaustiveness when matching on str and nested non-exhaustive enums Fixes rust-lang/rust#105479 r? `@Nadrieril`
When matching on non-sum types we tell people they should add a new fallback case
but we should go further and check whether the fallback is because of a free-form non-sum type (namely, not an
enum
) and explain that, for example, &str can hold any arbitrary string and match needs an arm to account for it.simonw/advent-of-code-2022-in-rust#3 (comment)
The text was updated successfully, but these errors were encountered: