Skip to content

Diagnostics: Suggest Unit Variant Enum in match #84700

Closed
@jamesmunns

Description

@jamesmunns
Member

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=5a6b1a3497842e4ddc883b2345febd8f

#[derive(PartialEq, Debug)]
enum FarmAnimal {
    Worm,
    Cow,
    Bull,
    Chicken { num_eggs: usize },
    Dog { name: String },
}

fn what_does_the_animal_say(animal: &FarmAnimal) {

    /* TODO: fill in the match statement below to make this code compile */
    
    let noise = match animal {
        FarmAnimal::Cow(_) => "moo".to_string(),
        // /* Chicken      */ => "cluck, cluck!".to_string(),
        // /* Dog          */  => format!("woof, woof! I am {}!", name),
        // /* Worm– or all silent animals?*/ => "-- (silence)".to_string(),
        _ => todo!()
    };
    
    /* Bonus task: Give Dogs named Lassie a different output */
    
    println!("{:?} says: {:?}", animal, noise);
}

fn main() {
    what_does_the_animal_say(
        &FarmAnimal::Dog {
            name: "Lassie".to_string()
    });
    what_does_the_animal_say(&FarmAnimal::Cow);
    what_does_the_animal_say(&FarmAnimal::Bull);
    what_does_the_animal_say(&FarmAnimal::Chicken{num_eggs: 3});
    what_does_the_animal_say(&FarmAnimal::Worm);

    /*
    Output should be:
    
    Dog { name: "Lassie" } says: "woof, woof! I am Lassie!"
    Cow says: "moo"
    Bull says: "moo"
    Chicken { num_eggs: 3 } says: "cluck, cluck!"
    Worm says: "-- (silence)"
    
    */
}

The current output is:

error[E0532]: expected tuple struct or tuple variant, found unit variant `FarmAnimal::Cow`
  --> src/main.rs:15:9
   |
15 |         FarmAnimal::Cow(_) => "moo".to_string(),
   |         ^^^^^^^^^^^^^^^ not a tuple struct or tuple variant

error: aborting due to previous error

For more information about this error, try `rustc --explain E0532`.
error: could not compile `playground`

To learn more, run the command again with --verbose.

Ideally the output should look like:

I'd like it to say "try to use a tuple unit variant like "FarmAnimal::Cow" instead".

For example, here's what happens if you use Tuple syntax instead of Struct syntax:

error[E0532]: expected tuple struct or tuple variant, found struct variant `FarmAnimal::Chicken`
  --> src/main.rs:16:9
   |
6  |     Chicken { num_eggs: usize },
   |     --------------------------- `FarmAnimal::Chicken` defined here
...
16 |         FarmAnimal::Chicken(x)  => "cluck, cluck!".to_string(),
   |         ^^^^^^^^^^^^^^^^^^^^^^ help: use struct pattern syntax instead: `FarmAnimal::Chicken { num_eggs }`

error: aborting due to 2 previous errors

So I'd like the new diagnostic to look something like:

error[Exxxx]: expected tuple struct or tuple variant, found unit variant `FarmAnimal::Cow`
  --> src/main.rs:16:9
   |
6  |     Cow,
   |     --- `FarmAnimal::Cow` defined here
...
16 |         FarmAnimal::Cow(_)  => "moo".to_string(),
   |         ^^^^^^^^^^^^^^^^^^ help: use unit pattern syntax instead: `FarmAnimal::Cow`

Activity

added
A-diagnosticsArea: Messages for errors, warnings, and lints
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Apr 29, 2021
jamesmunns

jamesmunns commented on Apr 29, 2021

@jamesmunns
MemberAuthor

This is an example Ferrous Systems uses in our trainings, and some of our participants have tripped over this lack of suggestion here.

The compiler DOES provide diagnostics when you use a struct syntax instead of a tuple syntax.

leonardo-m

leonardo-m commented on Apr 29, 2021

@leonardo-m

Alternatively the help could suggest a more direct: "Remove the parenthesis here".

added
A-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`
C-enhancementCategory: An issue proposing an enhancement or a PR with one.
E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.
on Apr 30, 2021
ABouttefeux

ABouttefeux commented on Apr 30, 2021

@ABouttefeux
Contributor

@rustbot claim

added a commit that references this issue on May 2, 2021

Rollup merge of rust-lang#84818 - ABouttefeux:enum-suggest, r=jackh726

b0c7e64
jamesmunns

jamesmunns commented on May 3, 2021

@jamesmunns
MemberAuthor

I just wanted to mention @ABouttefeux, we wrote a little bit of context and details from Ferrous' perspective on this fix, and I wanted to thank you personally for implementing this diagnostics improvement so quickly! Let me know if you have a blog or twitter you'd like us to link to (rather than your GH profile).

ABouttefeux

ABouttefeux commented on May 3, 2021

@ABouttefeux
Contributor

Hello, linking to my GH profile is fine. I did not know I would contribute to such an interesting learning experience.
Anyway thank you for mentioning me in your blog post 😄.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`C-enhancementCategory: An issue proposing an enhancement or a PR with one.E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    Participants

    @jamesmunns@leonardo-m@camelid@ABouttefeux

    Issue actions

      Diagnostics: Suggest Unit Variant Enum in match · Issue #84700 · rust-lang/rust