Why it complains "enum is never used"?

enum Foo {
    V1,
    V2 (String),
}

fn main() {
    let foo = Foo::V2("some string".to_owned());
    
    match foo {
        Foo::V1 => println!("this is Foo::V1"),
        Foo::V2(_) => println!("this is Foo::V2"),
    }
}

Why the linter complains Foo is never used? Am I not using Foo here?

The specific lint that I get is

warning: variant is never constructed: `V1`

which is accurate. It does not stop compiling, but it does mention that a variant may not be necessary.

3 Likes

Interesting. Both the linter on my local machine and the one used by https://play.rust-lang.org/ complained "enum is never used". Which version of Rust are you using?

The code you linked to the playground is different from the code in your original post.
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=a4fed778d662a06b3704f25d55001495
At that link you see that the main function is using one of the variants of the enum, so the lint message changes.
The message you get without the main function is still accurate. It's telling you that you have created an enum that you never use. It will still compile, it's just letting you know that you might want to clean the code up.

Ah, I see. If I click "Build", it warns "main fn is never used" and, I guess, therefore is eliminated, which results in "enum is never used". But if I click "Run", main fn is used and thus enum Foo is used. Interesting...

This is an artifact of the playground trying to be helpful by not requiring you to have a main() function just to play with some code. When you hit "Build", your code is built as a library not an executable which implicitly calls main(). Since your main function isn't public, it can't be called which triggers the dead code warnings you're seeing.

1 Like

If you find the message bothersome, you can get rid of it by adding #[allow(dead_code)] to your enum declaration:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=562a195bdb0b164daba81905070205b5

1 Like

Just throwing my two cents in here...

If this problem is small reproduction of something you are seeing in a library you are building, the problem stems from Foo not being public. If it is public, the compiler will know that it is not required to be used in the current crate, so changing it to be pub enum Foo{} will also solve your problem! If you dont want it to be public, then i would remove the dead code. #[allow(dead_code)] is never a good idea imo :).

Good luck!

1 Like

Also, be aware that there's a false positive "variant is not constructed" bug: https://github.com/rust-lang/rust/issues/64362

I ran into this a few days ago and it was pretty confusing... :grimacing:

FTR I wasn't necessarily recommending #[allow(dead_code)] in real practice, just pointing out it would hide the error in cases where it was trivial and annoying.