What's up with lax enum matching?

Just noticed this weird language quirk:

enum Foo {
  Struct { foo: u32 },
  Tuple(u32),
  Unit,
}

fn none(foo: Foo) {
  match foo {
    Foo::Struct => {}, // nope!
    Foo::Tuple => {}, // nope!
    Foo::Unit => {}, // fine
  }
}

fn braces(foo: Foo) {
  match foo {
    Foo::Struct { .. } => {}, // fine
    Foo::Tuple { .. } => {}, // fine
    Foo::Unit { .. } => {}, // nope!
  }
}

fn parens(foo: Foo) {
  match foo {
    Foo::Struct(..) => {}, // nope!
    Foo::Tuple(..) => {}, // fine
    Foo::Unit(..) => {}, // nope!
  }
}

So I guess the question is what's up with being able to match tuple variants with { .. }, but not vice-versa, or with unit variants?

I'm sure this has been addressed before, but I have no idea what keywords to search for.

3 Likes

This works, which surprised me:

    Foo::Tuple { 0: x } => println!("{x}"),

Probably related to why matching with braces was added, I would guess for code generation. But then why not unit variants?

I don't know what you were testing, but on my end your code using { .. } with unit variants does actually work. Rust Playground

And apparently, {} without the .. can match a unit variant, too.

3 Likes

Argh. I must have tested with Unit(..) and forgot to test Unit {..}. Tried to verify in playground, but failed to match up the errors properly - sorry for the distraction.

This makes sense at least, {..} being the generic matching mechanism.

Regarding braces for tuple variants or tuple structs, this works in expressions, too: Rust Playground

2 Likes

Filthy!

Those code generators must love it though.

The numeric fields for braced tuples came from RFC 1506, stabilized in Rust 1.19.

7 Likes

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