Enums with 'Other' values

This is a very good way of handling special values on current Rust. I've also just directly used a single element tuple struct for this before, rather than having to name It::Other.

The big question, though, is whether matches!(Ipv6, Other(_)) is true. Obviously, Other(0x86DD) has to be allowed, because we can't express u16 but not these niches as a surface level type.

If that's true, then exhaustive match checking doesn't mean anything, because you need to have the wildcard Other arm anyway. In a way, this is similar to #[non_exhaustive].

If it's false, then you can't name previously unnamed variants (see also the io::ErrorKind problem for naming new kinds, where std is (ab)using stability to be able to do so). In a way, it's similar to #[non_exhaustive]...

I don't know how plausible it is in practice, but there's a potential design where this is "just" a non exhaustive enum, but the unspecified discriminants are not niches (validity invariant), but allowed variants a la C++ enum class.

The benefit of modelling this as non exhaustive enums is that then they would benefit from whatever linting non exhaustive enums get to lint for this-version-exhaustive matching. (Though they would have to be non exhaustive locally as well.)


The semantic idea is the core of the idea here, but to throw out syntax, I'm still fond of first class syntax for non exhaustive enums:

#[repr(u16)]
enum Ethertype {
    Ipv6 = 0x86DD,
    ..
    // other values are INVALID
    // but can be added semver-compatibly
}

So that could be extended for a "valid non exhaustive":

#[repr(u16)]
enum Ethertype {
    Ipv6 = 0x86DD,
    Other = ..
    // other values are VALID
    // and can be named semver-compatibly
}

Ethertype::Other would not be valid in expression position, as it could have many values. Instead, you create other values of Ethertype via 0u16 as Ethertype. (Or perhaps Ethertype(0), syntax is just random could-maybe-work ideas.)

Ethertype::Other not being a real variant I think makes this a meaningful improvement over just (a proc macro automating) the surface language version possible today, and potentially sidesteps the question of what Other(0x86DD) is and whether matches!(Ipv6, Other(0x86DD)).

1 Like