Skip to content

unfriendly error diagnostic when using expressions in pattern #112593

Description

@ShE3py

Code

struct Foo(String);

fn bar(foo: Foo) -> bool {
    match foo {
        Foo("hi".to_owned()) => true,
        _ => false
    }
}

Current output

Compiling playground v0.0.1 (/playground)
error: expected one of `)`, `,`, `...`, `..=`, `..`, or `|`, found `.`
 --> src/lib.rs:5:17
  |
5 |         Foo("hi".to_owned()) => true,
  |                 ^
  |                 |
  |                 expected one of `)`, `,`, `...`, `..=`, `..`, or `|`
  |                 help: missing `,`

error[E0531]: cannot find tuple struct or tuple variant `to_owned` in this scope
 --> src/lib.rs:5:18
  |
5 |         Foo("hi".to_owned()) => true,
  |                  ^^^^^^^^ not found in this scope

error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 1 field
 --> src/lib.rs:5:13
  |
1 | struct Foo(String);
  |            ------ tuple struct has 1 field
...
5 |         Foo("hi".to_owned()) => true,
  |             ^^^^ ^^^^^^^^^^ expected 1 field, found 2

Some errors have detailed explanations: E0023, E0531.
For more information about an error, try `rustc --explain E0023`.
error: could not compile `playground` (lib) due to 3 previous errors

Desired output

Compiling playground v0.0.1 (/playground)
error[E0164]: expected tuple struct or tuple variant, found associated function `<&str as ToOwned>::to_owned`
 --> src/lib.rs:5:13
  |
5 |         Foo("hi".to_owned()) => true,
  |             ^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns
  |
  = help: for more information, visit https://doc.rust-lang.org/reference/patterns.html

For more information about this error, try `rustc --explain E0164`.
error: could not compile `playground` (lib) due to previous error

Rationale and extra context

This error occured while I was doing an assert!(matches!(...)) for a struct that doesn't implement Eq.

Using String::new gives better messages;

error[E0164]: expected tuple struct or tuple variant, found associated function `String::new`
 --> src/lib.rs:5:20
  |
5 |         Foo { bar: String::new("hi") } => true,
  |                    ^^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns
  |
  = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html

Clippy gives the same error messages.

Other cases

struct Foo { bar: String }

fn bar(foo: Foo) -> bool {
    match foo {
        Foo { bar: "hi".to_owned() } => true,
        _ => false
    }
}

rustc output:

   Compiling playground v0.0.1 (/playground)
error: expected `,`
 --> src/lib.rs:5:24
  |
5 |         Foo { bar: "hi".to_owned() } => true,
  |         ---            ^
  |         |
  |         while parsing the fields for this pattern

error: could not compile `playground` (lib) due to previous error

Similar errors when using expressions such as Foo(1 + 2).

Anything else?

No response

Activity

  1. 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 Jun 13, 2023
  2. ShE3py commented on Jun 13, 2023

    @ShE3py
    ContributorAuthor

    @rustbot label +A-patterns +C-enhancement

  3. added
    A-patternsRelating to patterns and pattern matching
    C-enhancementCategory: An issue proposing an enhancement or a PR with one.
    on Jun 13, 2023
  4. added
    A-parserArea: The lexing & parsing of Rust source code to an AST
    D-papercutDiagnostics: An error or lint that needs small tweaks.
    on Jun 17, 2023
  5. self-assigned this
    on Jun 18, 2023
  6. clubby789 commented on Oct 27, 2023

    @clubby789
    Contributor

    Looks like the same issue as #112593 (dot being recovered as a comma)

  7. Nadrieril commented on Dec 1, 2023

    @Nadrieril
    Member

    I have limited experience with parsing but I know where I'd start on this.

    This is where the pattern of a match arm is parsed. The idea would be, in the error case, to try to parse an expression and emit a better error message if that succeeds. This code is an example of "try to parse X and emit better error if that works". You want to do something similar, but try to parse an expression instead (I'm guessing with self.parse_expr_res). You'll also have to define a diagnostic struct (like MissingCommaAfterMatchArm in the example) with an appropriate message in messages.ftl. (diagnostic structs are documented in the dev-guide).

    @clubby789 which issue did you mean? You accidentally linked to this one. EDIT: I'm guessing #90121

    @TaKO8Ki I'm unassigining you because it's been a few months, feel free to reassign yourself

  8. added
    E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.
    E-mediumCall for participation: Medium difficulty. Experience needed to fix: Intermediate.
    E-help-wantedCall for participation: Help is requested to fix this issue.
    on Dec 1, 2023
  9. ShE3py commented on Dec 4, 2023

    @ShE3py
    ContributorAuthor

    @rustbot claim

  10. added a commit that references this issue on Jan 28, 2024
    390f768
  11. added a commit that references this issue on Jan 29, 2024
    0138151
  12. added a commit that references this issue on Jan 29, 2024
    2a79c40
  13. Nadrieril commented on Jan 30, 2024

    @Nadrieril
    Member

    Great work @ShE3py! Thanks for taking the time to fix this

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-parserArea: The lexing & parsing of Rust source code to an ASTA-patternsRelating to patterns and pattern matchingC-enhancementCategory: An issue proposing an enhancement or a PR with one.D-papercutDiagnostics: An error or lint that needs small tweaks.E-help-wantedCall for participation: Help is requested to fix this issue.E-mediumCall for participation: Medium difficulty. Experience needed to fix: Intermediate.E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.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

    Issue actions