Skip to content

map_entry: the insert suggestion doesn't take into account #[cfg]-d-out code and comments #15781

@ada4a

Description

@ada4a

Summary

Normally, if a block that contains insert contains anything else, or_insert_with is suggested, and if it's the only thing in the block, then or_insert is suggested instead. But if the only other things that the block contains are statements that are #[cfg]-d out, or comments, then they get ignored by the lint, and an or_insert is suggested that doesn't contain them.

Reproducer

I tried this code:

#![allow(unused)]
#![warn(clippy::map_entry)]

fn very_important_fn() {}

fn foo(m: &mut std::collections::HashMap<i32, i32>, k: i32, v: i32) {
    if !m.contains_key(&k) {
        // very important comment
        #[cfg(test)]
        very_important_fn();
        m.insert(k, v);
    }
}

I expected to see this happen:

warning: usage of `contains_key` followed by `insert` on a `HashMap`
  --> src/main.rs:7:5
   |
 7 | /     if !m.contains_key(&k) {
 8 | |         // very important comment
 9 | |         #[cfg(test)]
10 | |         very_important_fn();
11 | |         m.insert(k, v);
12 | |     }
   | |_____^
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#map_entry
note: the lint level is defined here
  --> src/main.rs:2:9
   |
 2 | #![warn(clippy::map_entry)]
   |         ^^^^^^^^^^^^^^^^^
help: try
   |
 7 ~     m.entry(k).or_insert_with(|| {
 8 +         // very important comment
 9 +         #[cfg(test)]
10 +         very_important_fn();
11 +         v
12 +     });
   |

Instead, this happened:

warning: usage of `contains_key` followed by `insert` on a `HashMap`
  --> src/main.rs:7:5
   |
 7 | /     if !m.contains_key(&k) {
 8 | |         // very important comment
 9 | |         #[cfg(test)]
10 | |         very_important_fn();
11 | |         m.insert(k, v);
12 | |     }
   | |_____^ help: try: `m.entry(k).or_insert(v);`
   |

And if I make change the cfg condition to something that's true:

fn foo(m: &mut std::collections::HashMap<i32, i32>, k: i32, v: i32) {
    if !m.contains_key(&k) {
        // very important comment
        #[cfg(not(test))]
        very_important_fn();
        m.insert(k, v);
    }
}

I get the correct suggestion again:

help: try
   |
 7 ~     m.entry(k).or_insert_with(|| {
 8 +         // very important comment
 9 +         #[cfg(not(test))]
10 +         very_important_fn();
11 +         v
12 +     });
   |

Version

rustc 1.90.0 (1159e78c4 2025-09-14)
binary: rustc
commit-hash: 1159e78c4747b02ef996e55082b704c09b970588
commit-date: 2025-09-14
host: x86_64-unknown-linux-gnu
release: 1.90.0
LLVM version: 20.1.8

rustc 1.92.0-nightly (c8905eaa6 2025-09-28)
binary: rustc
commit-hash: c8905eaa66e0c35a33626e974b9ce6955c739b5b
commit-date: 2025-09-28
host: x86_64-unknown-linux-gnu
release: 1.92.0-nightly
LLVM version: 21.1.2

Additional Labels

@rustbot label I-suggestion-causes-bug

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: Clippy is not doing the correct thingI-suggestion-causes-bugIssue: The suggestion compiles but changes the code to behave in an unintended way

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions