Skip to content

map_entry false positives with lifetimes #9470

Closed
@Sciencentistguy

Description

@Sciencentistguy

Summary

This code:

if self.globals.contains_key(&name) {
    let value = self.stack_top().clone();
    self.globals.insert(name, value);
} else {
    let interner = INTERNER.lock();
    return Err(LoxError::UndefinedVariable(
        interner.resolve(name).unwrap().to_owned(),
    ));
}

triggers the following response from clippy:

warning: usage of `contains_key` followed by `insert` on a `HashMap`
   --> src/virtual_machine.rs:185:21
    |
185 | /                     if self.globals.contains_key(&name) {
186 | |                         let value = self.stack_top().clone();
187 | |                         self.globals.insert(name, value);
188 | |                     } else {
...   |
192 | |                         ));
193 | |                     }
    | |_____________________^
    |
    = note: `#[warn(clippy::map_entry)]` on by default
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#map_entry
help: try this
    |
185 ~                     if let std::collections::hash_map::Entry::Occupied(mut e) = self.globals.entry(name) {
186 +                         let value = self.stack_top().clone();
187 +                         e.insert(value);
188 +                     } else {
189 +                         let interner = INTERNER.lock();
190 +                         return Err(LoxError::UndefinedVariable(
191 +                             interner.resolve(name).unwrap().to_owned(),
192 +                         ));
193 +                     }
    |

The suggestion does not compile:

error[E0502]: cannot borrow `*self` as immutable because it is also borrowed as mutable
   --> src/virtual_machine.rs:186:37
    |
185 |                     if let std::collections::hash_map::Entry::Occupied(mut e) = self.globals.entry(name) {
    |                                                                                 ------------------------ mutable borrow occurs here
186 |                         let value = self.stack_top().clone();
    |                                     ^^^^^^^^^^^^^^^^ immutable borrow occurs here
187 |                         e.insert(value);
    |                         --------------- mutable borrow later used here

For more information about this error, try `rustc --explain E0502`.

This is because self.stack_top() borrows self, which also contains the map.

Lint Name

map_entry

Reproducer

I tried this code:

if self.globals.contains_key(&name) {
    let value = self.stack_top().clone();
    self.globals.insert(name, value);
} else {
    let interner = INTERNER.lock();
    return Err(LoxError::UndefinedVariable(
        interner.resolve(name).unwrap().to_owned(),
    ));
}

I saw this happen:

warning: usage of `contains_key` followed by `insert` on a `HashMap`
   --> src/virtual_machine.rs:185:21
    |
185 | /                     if self.globals.contains_key(&name) {
186 | |                         let value = self.stack_top().clone();
187 | |                         self.globals.insert(name, value);
188 | |                     } else {
...   |
192 | |                         ));
193 | |                     }
    | |_____________________^
    |
    = note: `#[warn(clippy::map_entry)]` on by default
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#map_entry
help: try this
    |
185 ~                     if let std::collections::hash_map::Entry::Occupied(mut e) = self.globals.entry(name) {
186 +                         let value = self.stack_top().clone();
187 +                         e.insert(value);
188 +                     } else {
189 +                         let interner = INTERNER.lock();
190 +                         return Err(LoxError::UndefinedVariable(
191 +                             interner.resolve(name).unwrap().to_owned(),
192 +                         ));
193 +                     }
    |

I expected to see this happen:
No suggestion, this is the only way to do this.

Version

rustc 1.63.0
binary: rustc
commit-hash: unknown
commit-date: unknown
host: aarch64-apple-darwin
release: 1.63.0
LLVM version: 14.0.6

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