rust-lang / rust-lang/rust

Match on enum with a `non_snake_case` variable that has the same name as one of the enum variants is potentially confusing

Open
#121,704 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-diagnostics A-lints L-non_snake_case T-lang
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Code
enum Test {
    V1,
    V2,
    V3
}

fn process(t : &Test) -> u8 {
    match t {
        Test::V1 => 1,
        // here is the issue! Simple typo of missing '::' in Test::V2
        // results in errors of missing arms being removed and just few harmless
        // warnings emitted.
        TestV2 => 2,
    }
}

fn main() {
    let test_val = Test::V3;
    // to minimize amount of warnings, let's construct others too
    let _v1 = Test::V1;
    let _v2 = Test::V2;
    // let's process value which is "by mistake" not handled.
    let x = process(&test_val);
    println!("got: {}", x);
}
Current output
$ cargo build
   Compiling match1 v0.1.0 (/mnt/c/users/gardas/src/rust/bugs/match1)
warning: unused variable: `TestV2`
  --> src/main.rs:14:9
   |
14 |         TestV2 => 2,
   |         ^^^^^^ help: if this is intentional, prefix it with an underscore: `_TestV2`
   |
   = note: `#[warn(unused_variables)]` on by default

warning: variable `TestV2` should have a snake case name
  --> src/main.rs:14:9
   |
14 |         TestV2 => 2,
   |         ^^^^^^ help: convert the identifier to snake case: `test_v2`
   |
   = note: `#[warn(non_snake_case)]` on by default

warning: `match1` (bin "match1") generated 2 warnings (run `cargo fix --bin "match1"` to apply 1 suggestion)
    Finished dev [unoptimized + debuginfo] target(s) in 2.25s
Desired output
$ cargo build
   Compiling match1 v0.1.0 (/mnt/c/users/gardas/src/rust/bugs/match1)
error[E0004]: non-exhaustive patterns: `&Test::V2` and `&Test::V3` not covered
 --> src/main.rs:9:11
  |
9 |     match t {
  |           ^ patterns `&Test::V2` and `&Test::V3` not covered
  |
note: `Test` defined here
 --> src/main.rs:2:6
  |
2 | enum Test {
  |      ^^^^
3 |     V1,
4 |     V2,
  |     -- not covered
5 |     V3
  |     -- not covered
  = note: the matched value is of type `&Test`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
  |
10~         Test::V1 => 1,
11~         &Test::V2 | &Test::V3 => todo!(),
  |

For more information about this error, try `rustc --explain E0004`.
error: could not compile `match1` (bin "match1") due to 1 previous error
Rationale and extra context

No response

Other cases

No response

Rust Version
rustc 1.76.0 (07dca489a 2024-02-04)
binary: rustc
commit-hash: 07dca489ac2d933c78d3c5158e3f43beefeb02ce
commit-date: 2024-02-04
host: x86_64-unknown-linux-gnu
release: 1.76.0
LLVM version: 17.0.6
Anything else?

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the example in src/main.rs with rustc 1.76.0 and run cargo build. Start at the match expression in process and trace how the compiler interprets TestV2 when it resembles an enum variant. Done means the typo produces a non-exhaustive-pattern error covering Test::V2 and Test::V3, with regression coverage added where appropriate.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.