-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Force ADT to be matched exhaustively (opposite of #[non_exhaustive]
)
#69930
Comments
#[non_exhaustive]
)#[non_exhaustive]
)
#[non_exhaustive]
)#[non_exhaustive]
)
This also seems similar to |
The caveat about I'm also skeptical of this as a property of the ADT itself, although I see why this was chosen. For example, while there are plenty of places where we would e.g. want to match exhaustively on As for implementation complexity, I defer to @Nadrieril & @varkor. |
On a scale from 1 (only a few lines of code) to 5 (in-depth refactor), I'd expect 2-3 because it goes a bit against the grain of the uniformity of the exhaustiveness algorithm. It would be very easy to just detect uses of the |
I'm a bit dubious about how this would work in practice, because you're effectively special-casing the top level of pattern matching. Additionally, I'm not convinced that it's common to have data types which you always want to exhaustively match on. If you want to do an exhaustive match, I think comments telling future contributors not to add a wildcard is enough, and it can be left to the reviewer's judgement to decide whether or not a wildcard is warranted. |
We may not need to special-case the top-level. For example, I would expect the following to trigger the lint: match Some(x) {
Some(StatementKind::AscribeUserType(..)) => {}
_ => {}
} |
This is no longer hard to implement at all. It would be doing the same work as the Only remains to decide if we want this :D |
I think this would belong better as a clippy lint. Given the inactivity on this issue, I'm taking the initiative to close it. Feel free to reopen (or comment) if someone still want this, or to ping me if you open a clippy feature proposal for it. |
The
#[non_exhaustive]
attribute prevents exhaustively matching an enum outside of the defining crate. However, it's sometimes useful to have the opposite of this behavior - that is, prevent non-exhaustively matching an enum within the defining crate.For example, non-exhaustively matching on
DefPathData
orTyKind
is often the wrong choice. By writing an exhaustive match (explicitly mentioning all variants), any additions/removals from the enum will require explicit acknowledgment at the match site, helping to prevent bugs.Examples from
rustc
:rust/src/librustc_mir/dataflow/impls/storage_liveness.rs
Lines 133 to 140 in c20d7ee
rust/src/librustc_hir/intravisit.rs
Lines 939 to 940 in c20d7ee
rust/src/librustc_hir/intravisit.rs
Lines 948 to 958 in c20d7ee
It would be useful to have a compiler lint to enforce this programmatically.
As an initial implementation, we could add an unstable attribute
#[rustc_exhaustive]
and an internal lintEXHAUSTIVE_MATCH
. This lint fires on any non-exhaustivematch
or destructuringlet
expression (notif let
/while let
for single enum variants) that match on an ADT annotated with#[rustc_exhaustive]
. Since this would be a lint, it could be allowed on a case-by-case basis (e.g. performing an early exit onTyKind::Error
orTyKind::Infer
).If this proves useful, it could be made available to all Rust programs after an RFC.
The text was updated successfully, but these errors were encountered: