rust-lang / rust-lang/rust-clippy

Use enum discriminant instead of matching variants

Open
#9,660 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-lint
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

What it does

Lints against code that exhaustively matches an enum and returns a unique constant number for each variant.

enum Function {
    ReadCoils,
    WriteSingleCoil,
}

impl Function {
    pub fn as_u8(&self) -> u8 {
        match self {
            Self::ReadCoils => 0x01,
            Self::WriteSingleCoil => 0x05,
        }
    }
}

It suggests adding a discriminant for each variant of the enum and to replace the match with a cast:

enum Function {
    ReadCoils = 0x01,
    WriteSingleCoil = 0x05,
}

impl Function {
    pub fn as_u8(&self) -> u8 {
        *self as u8
    }
}
Lint Name

use_enum_discriminant

Category

complexity, pedantic

Advantage
  • Results in smaller code => easier to read
Drawbacks
  • a discriminant must be unique => one can not add a new variant with the same number to the enum in the future.
Example
pub enum Month {
    January,
    February,
    March,
    April,
    May,
    June,
    July,
    August,
    September,
    October,
    November,
    December,
}

impl Month {
    #[must_use]
    pub fn as_usize(&self) -> usize {
        match self {
            Self::January => 1,
            Self::February => 2,
            Self::March => 3,
            Self::April => 4,
            Self::May => 5,
            Self::June => 6,
            Self::July => 7,
            Self::August => 8,
            Self::September => 9,
            Self::October => 10,
            Self::November => 11,
            Self::December => 12,
        }
    }
}

Could be written as:

pub enum Month {
    January = 1,
    February = 2,
    March = 3,
    April = 4,
    May = 5,
    June = 6,
    July = 7,
    August = 8,
    September = 9,
    October = 10,
    November = 11,
    December = 12,
}

impl Month {
    #[must_use]
    pub fn as_usize(&self) -> usize {
        *self as usize
    }
}

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

Start with the issue's proposed use_enum_discriminant behavior and compare the two Rust examples: the lint should detect exhaustive enum-to-constant matches and suggest explicit discriminants plus a cast. Done means the lint handles the described pattern, reports the stated category, and accounts for the uniqueness drawback.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
devtools
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.