rust-lang / rust-clippy

A bunch of lints to catch common mistakes and improve your Rust code. Book: https://doc.rust-lang.org/clippy/
https://rust-lang.github.io/rust-clippy/
Other
11.37k stars 1.53k forks source link

Clippy: Wrongly suggests `Option::if_let_else` in const function #7902

Closed Mythra closed 2 years ago

Mythra commented 2 years ago

Lint name: option_if_let_else

I tried this code:

    #[must_use]
    pub const fn new_from_parts(db_version: [u8; 10], tx_version: Option<[u8; 2]>) -> Self {
        let database_version: [u8; 8] = [
            db_version[0],
            db_version[1],
            db_version[2],
            db_version[3],
            db_version[4],
            db_version[5],
            db_version[6],
            db_version[7],
        ];
        let batch_version: [u8; 2] = [db_version[8], db_version[9]];

        Self {
            database_version,
            batch_version,
            tx_version: if let Some(txv) = tx_version {
                ([MaybeUninit::new(txv[0]), MaybeUninit::new(txv[1])], true)
            } else {
                ([MaybeUninit::uninit(); 2], false)
            },
        }
    }

Then clippy generated a warning:

error: use Option::map_or_else instead of an if let/else
  --> <project>/src/db.rs:77:16
   |
77 |               tx_version: if let Some(txv) = tx_version {
   |  _________________________^
78 | |                 ([MaybeUninit::new(txv[0]), MaybeUninit::new(txv[1])], true)
79 | |             } else {
80 | |                 ([MaybeUninit::uninit(); 2], false)
81 | |             },
   | |_____________^ help: try: `tx_version.map_or_else(|| ([MaybeUninit::uninit(); 2], false), |txv| ([MaybeUninit::new(txv[0]), MaybeUninit::new(txv[1])], true))`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#option_if_let_else

I'm generally not a fan of this lint anyone, but I do it to hopefully be consistent with the rest of the ecosystem and juggling lints is really hard to do. However, replacing this particular code results in a failure to compile on stable as you cannot call if_let_else in a constant function. Meaning the resulting checked code fails to compile.

Meta

Rust version (rustc -Vv):

rustc 1.56.0 (09c42c458 2021-10-18)
binary: rustc
commit-hash: 09c42c45858d5f3aedfa670698275303a3d19afa
commit-date: 2021-10-18
host: x86_64-unknown-linux-gnu
release: 1.56.0
LLVM version: 13.0.0
xFrednet commented 2 years ago

@rustbot label +I-suggestion-causes-error

giraffate commented 2 years ago

The option_if_let_else was fixed not to warn in const function by https://github.com/rust-lang/rust-clippy/pull/7573. Can you try currently beta (1.57.0)?

Mythra commented 2 years ago

Thanks! Sorry I missed that I did try looking for already existing PRs or issues but I guess not thoroughly enough! Seems to work for me on beta, thanks for the help'