Expand description

The non_exhaustive_omitted_patterns lint aims to help consumers of a #[non_exhaustive] struct or enum who want to match all of its fields/variants explicitly.

The #[non_exhaustive] annotation forces matches to use wildcards, so exhaustiveness checking cannot be used to ensure that all fields/variants are matched explicitly. To remedy this, this allow-by-default lint warns the user when a match mentions some but not all of the fields/variants of a #[non_exhaustive] struct or enum.


// crate A
pub enum Bar {
    B, // added variant in non breaking change

// in crate B
match Bar::A {
    Bar::A => {},
    _ => {},

This will produce:

warning: some variants are not matched explicitly
   --> $DIR/
LL |         match Bar::A {
   |               ^ pattern `Bar::B` not covered
 note: the lint level is defined here
  --> $DIR/
LL |         #[warn(non_exhaustive_omitted_patterns)]
   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = help: ensure that all variants are matched explicitly by adding the suggested match arms
   = note: the matched value is of type `Bar` and the `non_exhaustive_omitted_patterns` attribute was found

Warning: setting this to deny will make upstream non-breaking changes (adding fields or variants to a #[non_exhaustive] struct or enum) break your crate. This goes against expected semver behavior.


Structs and enums tagged with #[non_exhaustive] force the user to add a (potentially redundant) wildcard when pattern-matching, to allow for future addition of fields or variants. The non_exhaustive_omitted_patterns lint detects when such a wildcard happens to actually catch some fields/variants. In other words, when the match without the wildcard would not be exhaustive. This lets the user be informed if new fields/variants were added.