Skip to content

comparison_chain vs. const generics #14936

@jcape

Description

@jcape

Summary

Clippy is asking to replace an if chain over const generic values with a non-constant match statement.

Lint Name

comparison_chain

Reproducer

I tried this code:

pub struct Decimal<const EXPONENT: i8>(i64);

impl<const E: i8> Decimal<const E: i8> {
   pub fn checked_add<const E2: i8>(self, rhs: Decimal<E2>) -> Option<Self> {
        let factor = 10i64.checked_pow(E.abs_diff(E2).into())?;

        let (lhs, rhs) = if E.abs() > E2.abs() {
            (self.0, rhs.0.checked_mul(factor)?)
        } else if E.abs() < E2.abs() {
            (self.0.checked_mul(factor)?, rhs.0)
        } else {
            (self.0, rhs.0)
        };

        ...
    }
}

I saw this happen:

warning: `if` chain can be rewritten with `match`
  --> .../decimal.rs:59:26
   |
59 |           let (lhs, rhs) = if E.abs() > E2.abs() {
   |  __________________________^
60 | |             (self.0, rhs.0.checked_mul(factor)?)
61 | |         } else if E.abs() < E2.abs() {
62 | |             (self.0.checked_mul(factor)?, rhs.0)
63 | |         } else {
64 | |             (self.0, rhs.0)
65 | |         };
   | |_________^ help: consider rewriting the `if` chain with `match`: `match E.abs().cmp(&E2.abs()) {...}`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#comparison_chain
   = note: `#[warn(clippy::comparison_chain)]` on by default

I expected to see this happen:

Nothing, because .cmp() is not a const fn, so the suggested style is a pessimisation: https://godbolt.org/z/3Woefv385

Version

rustc 1.87.0 (17067e9ac 2025-05-09)
binary: rustc
commit-hash: 17067e9ac6d7ecb70e50f92c1944e545188d2359
commit-date: 2025-05-09
host: x86_64-unknown-linux-gnu
release: 1.87.0
LLVM version: 20.1.1

Additional Labels

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: Clippy is not doing the correct thingI-false-positiveIssue: The lint was triggered on code it shouldn't have

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions