Variant without paramter by mistake

For example, I have an Enum:

enum Foo {
    Bar,
    Baz(i32)
}

And I write like this by mistake (forgot to add the parameter):let mode = Foo::Baz;. Surprised that the compiler didn't consider this as an error, it will compile, I want to know if mode's type is Foo anymore, I write like this:

    match mode {
        Foo::Bar => {}
        Foo::Baz(_) => {}
    }

But the compiler give me some error message that confused me a lot:

error[E0308]: mismatched types
 --> src/main.rs:9:9
  |
2 |     Bar,
  |     --- unit variant defined here
...
8 |     match mode {
  |           ---- this expression has type `fn(i32) -> Foo {Foo::Baz}`
9 |         Foo::Bar => {}
  |         ^^^^^^^^ expected fn item, found enum `Foo`
  |
  = note: expected fn item `fn(i32) -> Foo {Foo::Baz}`
                found enum `Foo`

So what is a Foo::Baz?

1 Like

Here's what the compiler thinks what it is: Rust Playground.

It's the "constructor" function for the Baz variant.

So, Foo::Baz(1) is actually a function call statement, right?

I think it's an expression, but yeah, it's a function call. You could also do mode(1) at that point.

1 Like

As a special case, Foo::Baz is both the name of a variant and a function associated with Foo. This is fine because the variant lives in the compiler's "types" namespace while the associated function lives in the "values" namespace.

This syntactic sugar is what lets you do things like this:

let collection_of_baz: Vec<Foo> = (0..100).map(Foo::Baz).collect();
4 Likes