Skip to content

equatable-if-let not stable for consts yet #15376

@matthiaskrgr

Description

@matthiaskrgr

Using the following flags

--force-warn clippy::equatable-if-let

this code:

// check-pass

const _: i32 = if true { 5 } else { 6 };

const _: i32 = if let Some(true) = Some(false) { 0 } else { 1 };

const _: i32 = match 1 {
    2 => 3,
    4 => 5,
    _ => 0,
};

static FOO: i32 = {
    let x = if true { 0 } else { 1 };
    let x = match x {
        0 => 1,
        _ => 0,
    };
    if let Some(x) = Some(x) { x } else { 1 }
};

static mut BAR: i32 = {
    let x = if true { 0 } else { 1 };
    let x = match x {
        0 => 1,
        _ => 0,
    };
    if let Some(x) = Some(x) { x } else { 1 }
};

const fn if_() -> i32 {
    if true { 5 } else { 6 }
}

const fn if_let(a: Option<bool>) -> i32 {
    if let Some(true) = a { 0 } else { 1 }
}

const fn match_(i: i32) -> i32 {
    match i {
        i if i > 10 => i,
        1 => 2,
        _ => 0,
    }
}

pub trait Foo {
    const IF: i32 = if true { 5 } else { 6 };
    const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 };
    const MATCH: i32 = match 0 {
        1 => 2,
        _ => 0,
    };
}

impl Foo for () {
    const IF: i32 = if true { 5 } else { 6 };
    const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 };
    const MATCH: i32 = match 0 {
        1 => 2,
        _ => 0,
    };
}

fn non_const_outside() {
    const fn const_inside(y: bool) -> i32 {
        let x = if y { 0 } else { 1 };
        let x = match x {
            0 => 1,
            _ => 0,
        };
        if let Some(x) = Some(x) { x } else { 1 }
    }
}

const fn const_outside() {
    fn non_const_inside(y: bool) -> i32 {
        let x = if y { 0 } else { 1 };
        let x = match x {
            0 => 1,
            _ => 0,
        };
        if let Some(x) = Some(x) { x } else { 1 }
    }
}

fn main() {
    let _ = [0; {
        let x = if false { 0 } else { 1 };
        let x = match x {
            0 => 1,
            _ => 0,
        };
        if let Some(x) = Some(x) { x } else { 1 }
    }];
}

caused the following diagnostics:

    Checking _25c7d89391ba419647e7c93840343016b186793e v0.1.0 (/tmp/icemaker_global_tempdir.f0JXFBTcO4io/icemaker_clippyfix_tempdir.oAbQxx8YWj6r/_25c7d89391ba419647e7c93840343016b186793e)
warning: this pattern matching can be expressed using equality
 --> src/main.rs:5:19
  |
5 | const _: i32 = if let Some(true) = Some(false) { 0 } else { 1 };
  |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(false) == Some(true)`
  |
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#equatable_if_let
  = note: requested on the command line with `--force-warn clippy::equatable-if-let`

warning: this pattern matching can be expressed using equality
  --> src/main.rs:36:8
   |
36 |     if let Some(true) = a { 0 } else { 1 }
   |        ^^^^^^^^^^^^^^^^^^ help: try: `a == Some(true)`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#equatable_if_let

warning: this pattern matching can be expressed using equality
  --> src/main.rs:49:28
   |
49 |     const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 };
   |                            ^^^^^^^^^^^^^^^^^^^^^ help: try: `None == Some(true)`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#equatable_if_let

warning: this pattern matching can be expressed using equality
  --> src/main.rs:58:28
   |
58 |     const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 };
   |                            ^^^^^^^^^^^^^^^^^^^^^ help: try: `None == Some(true)`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#equatable_if_let

warning: `_25c7d89391ba419647e7c93840343016b186793e` (bin "_25c7d89391ba419647e7c93840343016b186793e") generated 4 warnings (run `cargo clippy --fix --bin "_25c7d89391ba419647e7c93840343016b186793e"` to apply 4 suggestions)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.41s

However after applying these diagnostics, the resulting code:

// check-pass

#![feature(const_cmp)]
const _: i32 = if true { 5 } else { 6 };

const _: i32 = if Some(false) == Some(true) { 0 } else { 1 };

const _: i32 = match 1 {
    2 => 3,
    4 => 5,
    _ => 0,
};

static FOO: i32 = {
    let x = if true { 0 } else { 1 };
    let x = match x {
        0 => 1,
        _ => 0,
    };
    if let Some(x) = Some(x) { x } else { 1 }
};

static mut BAR: i32 = {
    let x = if true { 0 } else { 1 };
    let x = match x {
        0 => 1,
        _ => 0,
    };
    if let Some(x) = Some(x) { x } else { 1 }
};

const fn if_() -> i32 {
    if true { 5 } else { 6 }
}

const fn if_let(a: Option<bool>) -> i32 {
    if a == Some(true) { 0 } else { 1 }
}

const fn match_(i: i32) -> i32 {
    match i {
        i if i > 10 => i,
        1 => 2,
        _ => 0,
    }
}

pub trait Foo {
    const IF: i32 = if true { 5 } else { 6 };
    const IF_LET: i32 = if None == Some(true) { 5 } else { 6 };
    const MATCH: i32 = match 0 {
        1 => 2,
        _ => 0,
    };
}

impl Foo for () {
    const IF: i32 = if true { 5 } else { 6 };
    const IF_LET: i32 = if None == Some(true) { 5 } else { 6 };
    const MATCH: i32 = match 0 {
        1 => 2,
        _ => 0,
    };
}

fn non_const_outside() {
    const fn const_inside(y: bool) -> i32 {
        let x = if y { 0 } else { 1 };
        let x = match x {
            0 => 1,
            _ => 0,
        };
        if let Some(x) = Some(x) { x } else { 1 }
    }
}

const fn const_outside() {
    fn non_const_inside(y: bool) -> i32 {
        let x = if y { 0 } else { 1 };
        let x = match x {
            0 => 1,
            _ => 0,
        };
        if let Some(x) = Some(x) { x } else { 1 }
    }
}

fn main() {
    let _ = [0; {
        let x = if false { 0 } else { 1 };
        let x = match x {
            0 => 1,
            _ => 0,
        };
        if let Some(x) = Some(x) { x } else { 1 }
    }];
}

no longer compiled:

    Checking _25c7d89391ba419647e7c93840343016b186793e v0.1.0 (/tmp/icemaker_global_tempdir.f0JXFBTcO4io/icemaker_clippyfix_tempdir.oAbQxx8YWj6r/_25c7d89391ba419647e7c93840343016b186793e)
error[E0658]: cannot call conditionally-const operator in constants
 --> src/main.rs:6:19
  |
6 | const _: i32 = if Some(false) == Some(true) { 0 } else { 1 };
  |                   ^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: calls in constants are limited to constant functions, tuple structs and tuple variants
  = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
  = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
  = note: this compiler was built on 2025-07-31; consider upgrading it if it is out of date

error[E0658]: cannot call conditionally-const operator in constant functions
  --> src/main.rs:37:8
   |
37 |     if a == Some(true) { 0 } else { 1 }
   |        ^^^^^^^^^^^^^^^
   |
   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
   = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
   = note: this compiler was built on 2025-07-31; consider upgrading it if it is out of date

error[E0658]: cannot call conditionally-const operator in constants
  --> src/main.rs:50:28
   |
50 |     const IF_LET: i32 = if None == Some(true) { 5 } else { 6 };
   |                            ^^^^^^^^^^^^^^^^^^
   |
   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
   = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
   = note: this compiler was built on 2025-07-31; consider upgrading it if it is out of date

error[E0658]: cannot call conditionally-const operator in constants
  --> src/main.rs:59:28
   |
59 |     const IF_LET: i32 = if None == Some(true) { 5 } else { 6 };
   |                            ^^^^^^^^^^^^^^^^^^
   |
   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
   = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
   = note: this compiler was built on 2025-07-31; consider upgrading it if it is out of date

For more information about this error, try `rustc --explain E0658`.
error: could not compile `_25c7d89391ba419647e7c93840343016b186793e` (bin "_25c7d89391ba419647e7c93840343016b186793e" test) due to 4 previous errors
warning: build failed, waiting for other jobs to finish...
error: could not compile `_25c7d89391ba419647e7c93840343016b186793e` (bin "_25c7d89391ba419647e7c93840343016b186793e") due to 4 previous errors

Version:

rustc 1.90.0-nightly (cc0a5b730 2025-07-31)
binary: rustc
commit-hash: cc0a5b73053c62a3df5f84b3ee85079c9b65fa87
commit-date: 2025-07-31
host: x86_64-unknown-linux-gnu
release: 1.90.0-nightly
LLVM version: 20.1.8

Metadata

Metadata

Assignees

Labels

I-suggestion-causes-errorIssue: The suggestions provided by this Lint cause an ICE/error when applied

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions