Should clippy warn about function calls outside closures if those are const? [Answered]

Consider this code:

use std::collections::HashMap;

fn main() {
    let mut map = HashMap::new();
    map.entry(12_u8).or_insert(Vec::new()).push(34_u8);
    dbg!(map);
}

Clippy complains that the Vec::new() call is not closured:

warning: use of `or_insert` followed by a function call
 --> src/main.rs:5:22
  |
5 |     map.entry(12_u8).or_insert(Vec::new()).push(34_u8);
  |                      ^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(Vec::new)`
  |
  = note: `#[warn(clippy::or_fun_call)]` on by default

However, Vec::new() is const, so presumably the closure is not needed(?). While I'm reasonably confident the closure will get optimised away anyway, could clippy avoid the warning in this case?

1 Like

const doesn't mean trivial, and it also doesn't guarantee that the function is evaluated at compile time.

A const function is only const evaluated if it's in a required const context (effectively, used to create a const binding or generic). If it's not in a required const context (such as here), it's just a normal function call.

If there were some way to force const evaluation of the argument (const blocks?), then the unwrap_or branch can just bit copy the constant value. But without that language-level guarantee, it's up to the inliner to optimize the regular function call into a constant value, and unwrap_or_else properly communicates to the optimizer that the fallback value only should be computed if the fallback case is needed.

3 Likes

Ah. Of course. Thank you!

Hmm, raises an interesting API option. If there was a const such that one could say .or_insert(Vec::EMPTY) and because it's a const be confident that it's not a concern.

And it looks like if you do that, clippy is happy with it: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=4cecdfcc136a38260852437de859b1d4

Looks like the const blocks that CAD97 mentioned also cause clippy to not warn for this: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=dc850d10fc9a205846c86b73f02ad60c

2 Likes