How non_exhaustive works?

In rust 1.40.0 there is feature in changelog:

You can now mark structs, enums, and enum variants with the #[non_exhaustive] attribute to indicate that there may be variants or fields added in the future. For example this requires adding a wild-card branch (_ => {}) to any match statements on a non-exhaustive enum

But how it works? I try:

#[repr(u8)]
#[non_exhaustive]
enum Foo {
    A = 1,
    B = 2,
    C = 3,
}

fn main() {
    let foo = Foo::B;
    match foo {
        Foo::A => (),
        Foo::B => (),
        Foo::C => (),
    }
}

it compiles without problems wtih 1.41.1,
but as understand documentation it shouldn't compile?

1 Like

Hmm, I would guess it only has an effect across crate boundaries.

1 Like

This prevents downstream crates from exhaustively listing out all variants/fields. Within a crate you can always see all variants/fields.

1 Like

There's more information here: https://github.com/rust-lang/rfcs/blob/master/text/2008-non-exhaustive.md#enums-1

Within the crate that defines the enum, this attribute is essentially ignored, so that the current crate can continue to exhaustively match the enum. The justification for this is that any changes to the enum will likely result in more changes to the rest of the crate.

It goes on to give an example.

3 Likes

I would recommend reading the RFC.This specifies all the details around #[non_exhaustive] attribute, and is gives you a lot of information around why it was necessary and how it gets taught.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.