Skip to content

Diagnostics: Suggest Unit Variant Enum in match #84700

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jamesmunns opened this issue Apr 29, 2021 · 5 comments · Fixed by #84818
Closed

Diagnostics: Suggest Unit Variant Enum in match #84700

jamesmunns opened this issue Apr 29, 2021 · 5 comments · Fixed by #84818
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` C-enhancement Category: An issue proposing an enhancement or a PR with one. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jamesmunns
Copy link
Member

jamesmunns commented Apr 29, 2021

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`
@jamesmunns jamesmunns added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 29, 2021
@jamesmunns
Copy link
Member Author

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
Copy link

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

@camelid camelid added A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` C-enhancement Category: An issue proposing an enhancement or a PR with one. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. labels Apr 30, 2021
@ABouttefeux
Copy link
Contributor

@rustbot claim

@jamesmunns
Copy link
Member Author

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
Copy link
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
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` C-enhancement Category: An issue proposing an enhancement or a PR with one. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants