An alternative to enum variants types

Disclaimer: I'm very ignorant of compiler internals and what the implications of any of this is for the compiler

I've often wanted the opposite. In your example, something like

Option::{Some}
MyEnum::{B, D}

The main use case in my mind is being able to make function signatures more explicit as to what enum variants they return, mainly when it comes to error enums. Making an error enum for each function is cumbersome, and every function returning a big enum with all the possible errors that can occur in a library loses some of the benefits that should come with an error enum.

I think explicitly listing the included variants is preferable, because knowing what MyEnum - { A, C } means requires knowing and remembering all the variants of MyEnum, and I feel this feature would be most useful with big enums where you're only returning a couple of variants. That said, I'd be interested to know what your use cases are.

My thoughts on the questions from @mathstuf:

  • How is name lookup done on the right side? Must it be MyEnum - { MyEnum::A } ? What if it was MyEnum - { MyEnum::None } (where the name would be potentially ambiguous otherwise)? (This goes back to this previous thread.)

Since the type of the enum is always included, this shouldn't be an issue.

  • What is Option - { Some, None } ? It should be a Never -like type (unless the type is #[non_exhaustive] I suppose).

It'd function the same as enum MyOption {}.

  • Given type MySmallerEnum = MyEnum - { MyEnum::A }; , is MySmallerEnum - { MyEnum::A } valid? How about MySmallerEnum::C (or must it still be MyEnum::C )?

If it's not necessary to include the type before each variant (it should not even be allowed, imo), this shouldn't be an issue. I don't think

type MySmallerEnum = MyEnum - A;
type EvenSmallerEnum = MySmallerEnum - A;

makes sense, since MySmallerEnum has no A variant to exclude, but I also don't think it would be harmful to allow it if it was simpler to implement like that.

  • Can this stack? Given type MyOtherSmallerEnum = MyEnum - { MyEnum::C }; , is MySmallerEnum - MyOtherSmallerEnum possible? If so, is it the same type as MyEnum - { MyEnum::A, MyEnum::C } or are they distinct? If distinct, do I need a .into() for each "type subtraction" layer to get to the original?

I don't think MySmallerEnum - MyOtherSmallerEnum should work. MySmallerEnum - { C } should be interchangeable with MyEnum - {A, C}

  • Is u8 - { 0 } equivalent to NonZero<u8> ?

I don't think this should be usable for anything but enums.

2 Likes