Skip to content

Deleting enum variant unexpectedly changes behavior in match statement #84078

Open
@jmikkola

Description

@jmikkola

This came up when I was deleting some variants of a rather large enum. The variants were never used (indeed, the compiler warned me that they were unused), so deleting them should be safe. Much to my surprise, this caused test failures.

Upon closer inspection, it turned out that although my code never created those enum values, it did match them in a match statement (which I had not cleaned up). This caused the reference to that variant in the pattern to turn into a variable, which matched everything.

Here's a simplified example where B represents the enum variant[s] deleted.

I tried this code:

playground

enum MyEnum {
    A,
    // B, // the assertion below works if B is uncommented
    C,
}

fn to_int(my_enum: MyEnum) -> i32 {
    use MyEnum::*;
    match my_enum {
        A => 1,
        B => 2,
        C => 3,
    }
}

fn main() {
    assert_eq!(3, to_int(MyEnum::C));
}

I expected to see this happen:

When removing the variant B of the enum, I expected the match statement to fail to compile because it still referenced B.

Instead, this happened:

It compiled with a warning that the C variant is unreachable because B matches any pattern.


This feels like Rust behaving correctly according to the indented behavior, but the intended behavior is confusing.

I'm not sure if there is anything useful that could be done about this (perhaps disallow capitalized variables in patterns? or replace the warning with an error?).

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.A-patternsRelating to patterns and pattern matchingC-enhancementCategory: An issue proposing an enhancement or a PR with one.L-unreachable_patternsLint: unreachable_patternsT-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