Require `_ => {...}` clause when matching enum

Is there any way to specify that matching on a particular enum mandates an else clause? For example, if I had an FFI library, and the library it was wrapping suddenly added a new variant to an enum, how would I add that to the wrapper without breaking all the current users' code? I see lots of comments in libraries saying "this enum is not meant to be exhaustively matched" so I'm guessing Rust doesn't have this feature, but I thought it'd be worth checking here just in case.

1 Like

Hm, I seem to recall there being a type in the standard library that had this same issue... I wonder if things are better now.

...ahah! Here it is:

pub enum ErrorKind {
    NotFound,
    PermissionDenied,
    // ...
    Interrupted,
    Other,
    UnexpectedEof,

    /// A marker variant that tells the compiler that users of this enum cannot
    /// match it exhaustively.
    #[unstable(feature = "io_error_internals",
               reason = "better expressed through extensible enums that this \
                         enum cannot be exhaustively matched against",
               issue = "0")]
    #[doc(hidden)]
    __Nonexhaustive,
}

Hm. Well, that's unfortunate; I guess you still can't really do much about it.

EDIT: I accidentally edited out the part where the standard library cheats. It's back now.

Upon further inspection, trying to reference that gives this error:

error: use of unstable library feature 'io_error_internals': better expressed through extensible enums that this enum cannot be exhaustively matched against (see issue #0)

A special feature just for io::ErrorKind isn't much of a solution... more importantly, though, why does it say issue #0?

It's not a speical feature for anything in libstd (well. besides the #[unstable(...)] thing which you don't need).

All it does is add an __Nonexhaustive variant that is not exposed through the docs (#[doc(hidden)]), so users don't even know what they would have to match on (except looking at the source directly, but at that point it's their own fault).

1 Like

But the point is, libstd has its own feature to make this a literal impossibility, whereas other libraries have to resort to documentation hiding, which is the worst kind of information hiding.

This is a bit like if all non-std struct fields were public, and we just hid the fields in the documentation and hoped no one would look at the code.

There is an open issue on this topic:
https://github.com/rust-lang/rust/issues/32770