I don't have the time or energy to defend this as a fleshed-out (pre-)RFC so my responses will be limited. I'm mostly just posting this here in case someone else sees merit in this concept and wants to see this through. While I have had a number of use-cases for something like this, I've only done cursory research into the design space and I don't care to exhaustively discuss alternatives.
Motivation
When writing low-level protocol-handling code, it's common to have a C-like enum to represent different message or packet types, e.g.:
#[repr(u8)]
enum PacketKind {
    Foo = 0,
    Bar,
    Baz
}
However, it then becomes tedious to use that in parsing code:
pub fn decode_packet(packet: &[u8]) -> Result<Packet, PacketError> {
    if packet.len() < 2 {
        return Err(PacketError::TooShort);
    }
    let kind = match packet[0] {
        0 => PacketKind::Foo,
        1 => PacketKind::Bar,
        2 => PacketKind::Baz,
        other => return Err(PacketError::unexpected_kind(other)),
    };
    match kind {
        PacketKind::Foo => decode_foo(&packet[1..]),
        PacketKind::Bar => decode_bar(&packet[1..]),
        PacketKind::Baz => decode_baz(&packet[1..]),
    }
}
Now, crates exist that let you generate a TryFrom impl with a derive, such as num_enum or enum-utils. And that would let you skip writing the first match.
However, using this in the above code effectively generates a redundant match, as there will be one in the TryFrom impl to convert from u8 to PacketKind, and then one in the code we write to dispatch on the value of PacketKind. Will the optimizer eliminate the redundant match? Probably, but as the Rust community has been learning, it's better to not generate as much redundant code in the first place.
It's also not super easy to discover these crates; even if you search "enum repr" on crates.io, you have to sift through a number of implementations of varying quality and maintenance status: https://crates.io/search?q=enum%20repr
Proposal
Allow using C-like enum variants in match arms for their #[repr] type:
match packet[0] /* : u8 */ {
    PacketKind::Foo => decode_foo(&packet[1..]),
    PacketKind::Bar => decode_bar(&packet[1..]),
    PacketKind::Baz => decode_baz(&packet[1..]),
    other /* : u8 */ => Err(PacketError::unexpected_kind(other)),
}
This would effectively desugar to something like:
match packet[0] /* : u8 */ {
    const { PacketKind::Foo as u8 } => decode_foo(&packet[1..]),
    const { PacketKind::Bar as u8 } => decode_bar(&packet[1..]),
    const { PacketKind::Baz as u8 } => decode_baz(&packet[1..]),
    other /* : u8 */ => Err(PacketError::unexpected_kind(other)),
}
though that's likely not valid syntax in the first place, hopefully you get the idea.
Having discussed this briefly with coworkers, we identified a few edge cases (not an exhaustive list):
- The catchall arm should be required to handle values that aren't a valid enum variant, unless
the enum exhaustively covers the value space of its #[repr](feasible for 8 and 16 bit enums).
- Obviously, enums with data wouldn't work with this so they should be rejected.
- We're not sure how this would interact with enum-variants-as-types but C-like enums aren't very useful with that feature anyway.
- I think you should be allowed to use multiple enum types in the same matchas long as they have the same#[repr], e.g.:
#[repr(u8)]
enum SomeOtherPacketKind {
    FooBar = 4,
    FooBaz,
    BarBaz,
}
match packet[0] {
   PacketKind::Foo => decode_foo(&packet[1..]),
   ...
   SomeOtherPacketKind::FooBar => decode_foo_bar(&packet[1..]),
    other /*: u8 */ => Err(PacketKind::unexpected_kind(other)),
}
though I do concede that this code kind of has a smell to it, so I wouldn't be against having a lint for this. If the enums overlap that should be fine as they can be linted just like other redundant match arms.
- Binding patterns should be allowed, but if mixing and matching is allowed then obviously you can't do that within a binding pattern because there's no applicable type without anonymous sum types:
match packet[0] /* : u8 */ {
    // Allowed
    kind /* : PacketKind */ @ (PacketKind::Foo | PacketKind::Bar) => decode_foo_or_bar(&packet[1..]), kind),
    // Rejected
    kind /* : ??? */ @ (PacketKind::Foo | SomeOtherPacketKind::FooBar) => (),
    ...
}