-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Incorrect non-exaustive match statement (where the user may think that all case are covered) #92197
Comments
This doesn't necessarily require an adversarial implementation of the comparison operators; fn main() {
match (f32::NAN, f32::NAN) {
(x, y) if x > y => {},
(x, y) if x < y => {},
(x, y) if x == y => {},
_ => unreachable!("oh no"),
}
} This is a correct implementation of the comparison operators since @rustbot modify labels: +A-exhaustiveness-checking +D-papercut +D-terse |
I do not believe |
Looks like nope (playground): fn foo(i: i32) {
match i {
i if i == 0 => {},
i if i != 0 => {},
}
}
fn main() {}
|
Guards indeed don't and likely will never count into exhaustiveness checking. I think that's a common mistake though? It would be nice if we could detect this. A potential good start would be: if every arm in a match has a guard it's almost surely a mistake, so we can remind the user that guards don't count. If someone want to have a go, you likely want to add a check somewhere in this function |
@rustbot claim |
…on-exhaustion, r=fee1-dead add note for non-exhaustive matches with guards Associated issue: rust-lang#92197 When a match statement includes guards on every match arm (and is therefore necessarily non-exhaustive), add a note to the error E0004 diagnostic noting this.
A note was added in #113019, thank you @ericmarkmartin! I think that's the most we can do about this issue |
Given the following code:
The current output is:
At first, I thought it was a compiler bug (an understandable one since exhaustiveness checking is hard), but then I realized that an buggy (or adversarial) implementation of
Ord
could lead tolhs
being neither less than, greater than nor equal torhs
. So the compiler is right, just confusing.Ideally the output should look like (line 8 has been edited):
And the error
E0004
could contain or more detailed explanation of why such code isn’t covering all cases.It addition, but I’m less sure of this, a suggestion to be made to either change the last arm to a wildcard (
_ => lhs.cmp(rhs)
or to add an extra arm_ => unreachable!()
with an explanation of why the user should choose one or the other.Of course in this specific case
(i32, i32)
we could trust the implementation, but I’m not sure either that it would be a good idea to special-case them (since it would be even more confusing for a user type that is not special cased).The text was updated successfully, but these errors were encountered: