-
-
Notifications
You must be signed in to change notification settings - Fork 310
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
The non_exhaustive_omitted_patterns
lint changed
#1522
Comments
Thank you for the heads up, and for your ongoing contributions to this lint! From reading the summary of rust-lang/rust#116734, I have a hard time making sense of what this lint, as newly formulated, is intended to detect. The first code snippet suggests that maybe it triggers on "any The second code snippet tells me my first guess cannot be right, because that match contains a wildcard pattern that can match variants of a non_exhaustive enum, but the explanation indicates a lint is not expected to trigger in that case. My second guess is that it triggers on "any Then from experimenting with some cases myself, I figured out my second guess cannot be right, because a lint does not trigger for I am starting to think that in the pursuit of being useful, this lint may be getting too smart in a way that makes it challenging for users to use correctly, especially if the failure mode for using it incorrectly is that silently it does nothing when a variant is added upstream. It's challenging to check whether you have used it correctly. I think you'd need to fork the dependency, introduce a new variant for the non_exhaustive enum you care about, get the dependency's code to compile again by inserting cases into all its exhaustive matches of that enum (this is likely the most time-consuming step), use a Compare against the original formulation in rust-lang/rust#81657: lint that triggers if "a specific arm is reachable at runtime for any reason, assuming the As I recall, the original reason for implementing as a smart But in hindsight, is module-level |
<3
Yep, precisely! Couldn't have said it better. EDIT: upon rereading I might have misread you; allow me to be pedantic: the lint is "any match whose scrutinee contains a 'place' whose type is a non_exhaustive enum, at least one variant of that enum is explicitly present as a pattern for that place, and at the same time not every variant of that enum is present as a pattern for that place among all the match arms". There are no considerations of matching anymore, just presence or absence of The reason I require at least one variant is for consistency. If I didn't, The intuition I'm aiming for is "look at the match, do you see all variants or not?". I think you're greatly overestimating how predictable the old formulation was; imo the rewrite is a ton more predictable. Just an example: in what follows the first match used to trigger the lint and the second didn't, for reasons internal to how exhaustiveness proceeds. rust-lang/rust#116734 has more examples in the tests, specifically this file. match (true, x) {
(true, Enum::A) => {}
(true, Enum::B) => {}
(false, Enum::C) => {}
_ => {}
}
match (x, true) {
(Enum::A, true) => {}
(Enum::B, true) => {}
(Enum::C, false) => {}
_ => {}
}
Can't you just remove an arm that mentions one of the variants and see if the lint triggers?
Now that I think about it, that could be an implementation strategy: just look at all the variants mentioned in the match, with no extra cleverness. That would be annoying to implement tho in terms of tracking the types.
I recall a different reason: in the following, match x {
(Foo::A, true) => {}
(Foo::B, _) => {}
#[deny(reachable)]
_ => {}
} |
Hi! In rust-lang/rust#116734 I changed how the lint works to make it more consistent. A consequence is that it no longer makes sense to set the lint level on a specific arm like was recommended before:
It is now recommended to set it on the whole match, or even globally.
I didn't realize there was heavy usage of this lint when I made the change, but I understand
syn
recommends it to avoid breakage? Once rust-lang/rust#117094 lands, setting the lint level on a single arm will raise an error, so the users can update. I thought I'd warn you before, also lmk if I should wait or do it differently. If it's really bad I can emulate the old behavior for a while.The text was updated successfully, but these errors were encountered: