Skip to content

unhelpful compiler error when using curly braces with enum variants in matches #79652

@woody77

Description

@woody77

I tried this code:

enum Foo {
    Bar(i32),
}

fn main() {
   let f = Foo::Bar(3);
   
   // compiler error that could be clearer:
   if let Foo::Bar{} = f {
      println!("hello");
   }
   
   // better suggestion for the compiler error:
   if let Foo::Bar(_) = f {
       println!("goodbye");
   }
}

playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=4984d4711270142a41aa9a0e77eb82d8

I expected to see this happen:

A suggestion to use a match pattern such as:

if let Foo::Bar(val) = f {

or

if let Foo::Bar(_) = f {

Instead, this happened:

error[E0027]: pattern does not mention field `0`
 --> src/main.rs:9:11
  |
9 |    if let Foo::Bar{} = f {
  |           ^^^^^^^^^^ missing field `0`
  |
help: include the missing field in the pattern
  |
9 |    if let Foo::Bar { 0 } = f {
  |                    ^^^^^
help: if you don't care about this missing field, you can explicitely ignore it
  |
9 |    if let Foo::Bar { .. } = f {
  |                    ^^^^^^

Activity

added
A-diagnosticsArea: Messages for errors, warnings, and lints
A-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`
D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.
D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Dec 3, 2020
GuillaumeGomez

GuillaumeGomez commented on Dec 3, 2020

@GuillaumeGomez
Member

Well, you can in fact do:

if let Foo::Bar { 0: i } = f {
    println!("hello");
}
PatchMixolydic

PatchMixolydic commented on Dec 4, 2020

@PatchMixolydic
Contributor

Incidentally, placing just an identifier in the braces (without the field name) produces a clearer diagnostic, which may also be useful in the case presented in the report:

if let Foo::Bar{ foo } = f {
   println!("hello");
}
error[E0769]: tuple variant `Foo::Bar` written as struct variant
 --> src/main.rs:9:11
  |
9 |    if let Foo::Bar{ foo } = f {
  |           ^^^^^^^^^^^^^^^ help: use the tuple variant pattern syntax instead: `Foo::Bar(foo)`

Using 0 directly as the suggestion in the report suggests (without binding the field to a valid identifier like in the above comment) causes an error, as one might expect:

   if let Foo::Bar{ 0 } = f {
      println!("hello");
   }
error: expected identifier, found `0`
 --> src/main.rs:9:21
  |
9 |    if let Foo::Bar{ 0 } = f {
  |           --------  ^ expected identifier
  |           |
  |           while parsing the fields for this pattern

I'd posit that using the struct syntax to bind values from a tuple variant would be rather strange/unexpected, so the diagnostics should probably push towards the use of the tuple syntax instead. I'm only one person, though, and I'm far from an expert on these matters.

LeSeulArtichaut

LeSeulArtichaut commented on Dec 7, 2020

@LeSeulArtichaut
Contributor

Also note that this diagnostic gets emitted for any tuple struct, not just enum variants:

struct Bar(i32);

fn main() {
   let f = Bar(3);
   
   // compiler error that could be clearer:
   if let Bar{} = f {
      println!("hello");
   }
}
error[E0027]: pattern does not mention field `0`
 --> src/main.rs:7:11
  |
7 |    if let Bar{} = f {
  |           ^^^^^ missing field `0`
  |
help: include the missing field in the pattern
  |
7 |    if let Bar { 0 } = f {
  |               ^^^^^
help: if you don't care about this missing field, you can explicitely ignore it
  |
7 |    if let Bar { .. } = f {
  |               ^^^^^^
LeSeulArtichaut

LeSeulArtichaut commented on May 22, 2021

@LeSeulArtichaut
Contributor

This seems to be fixed now:

error[E0769]: tuple variant `Foo::Bar` written as struct variant
 --> src/main.rs:9:11
  |
9 |    if let Foo::Bar{} = f {
  |           ^^^^^^^^^^
  |
help: use the tuple variant pattern syntax instead
  |
9 |    if let Foo::Bar(_) = f {
  |                   ^^^
removed their assignment
on Jun 2, 2021
Dylan-DPC

Dylan-DPC commented on Apr 15, 2023

@Dylan-DPC
Member

Closing this as fixed

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`C-bugCategory: This is a bug.D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.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

      No branches or pull requests

        Participants

        @GuillaumeGomez@PatchMixolydic@woody77@JohnTitor@LeSeulArtichaut

        Issue actions

          unhelpful compiler error when using curly braces with enum variants in matches · Issue #79652 · rust-lang/rust