Ignore a non_exhaustive attribute in a pattern match?

I'm reading the docs at rfcs/text/2008-non-exhaustive.md at master · rust-lang/rfcs · GitHub

but I have a situation where I want to do the opposite to what the feature is trying to do. I understand that when applied to an enum the library author who uses non_exhaustive is trying to make sure that (a subset of) future breaking changes are handled but I actually want to fail to compile if my dependencies add a new entry into the enum.

Instead of having a _ => todo!() (because I can't actually implement a default fallback path) I'd rather get a compile error, thus undoing the non_exhaustive attribute.

As a solid example, I'm currently writing a function with this signature

fn waiter_extracted<O: Debug, E>(
    e: WaiterError<O, E>,
) -> Result<WaiterError<String, Infallible>, SdkError<E, HttpResponse>>

which is taking an AWS SDK WaiterError in aws_smithy_runtime_api::client::waiters::error - Rust and stripping it of its generic parameters. To do this I have to pattern match on the WaiterError but it is marked #[non_exhaustive]. I definitely want to get a compile failure if another entry is added, instead of hitting whatever random code I could put in there as a _ => block.

This earlier discussion of the same question may help.

3 Likes

There's also a clippy lint which seems to be similar to the unstable rust linked above

#![feature(non_exhaustive_omitted_patterns_lint)]
use foo::Foo;

fn main() {
    let f = Foo::F1;

    // #[deny(non_exhaustive_omitted_patterns)]
    #[deny(clippy::wildcard_enum_match_arm)]
    let x = match f {
        Foo::F1 => 1,
        Foo::F2 => 2,
        _ => 3,
    };
    println!("{x:?}");
}

2 Likes

aargh, sorry, I should have searched the forums better before posting :face_with_open_eyes_and_hand_over_mouth:

1 Like

No problem. I happened to remember it being asked.