Skip to content

clippy's automatic fix for map_entry fails to compile, with a borrow error #11935

@SanjitBasker

Description

@SanjitBasker

Summary

I've been doing Advent of Code to learn Rust and I wrote some code which involves counting the appearances of each character in a string. Clippy suggests that I can make the code more efficient by using entry, but the proposed fix fails due to some borrow errors. The proposed fix doesn't work, but I was able to use entry and the compiler's feedback to get some code which does compile.

Reproducer

I tried this code:

let hand = "ABCDABCAA";
let mut counts: HashMap<char, u64> = HashMap::new();
for c in hand.chars() {
    if !counts.contains_key(&c) {
        counts.insert(c, 1);
    } else {
        counts.insert(c, counts.get(&c).unwrap() + 1);
    }
}

I ran cargo clippy --fix and got the following output:

warning: failed to automatically apply fixes suggested by rustc to crate `day_7`

after fixes were automatically applied the compiler reported errors within these files:

  * src/day_7.rs

This likely indicates a bug in either rustc or cargo itself,
and we would appreciate a bug report! You're likely to see 
a number of compiler warnings after this message which cargo
attempted to fix but failed. If you could open an issue at
https://github.com/rust-lang/rust-clippy/issues
quoting the full output of this command we'd be very appreciative!
Note that you may be able to make some more progress in the near-term
fixing code with the `--broken-code` flag

The following errors were reported:
error[E0502]: cannot borrow `counts` as immutable because it is also borrowed as mutable
  --> src/day_7.rs:97:34
   |
92 |                 match counts.entry(c) {
   |                       ------ mutable borrow occurs here
...
97 |                         e.insert(counts.get(&c).unwrap() + 1);
   |                           ------ ^^^^^^ immutable borrow occurs here
   |                           |
   |                           mutable borrow later used by call

error[E0502]: cannot borrow `counts` as immutable because it is also borrowed as mutable
   --> src/day_7.rs:199:26
    |
194 |         match counts.entry(c) {
    |               ------ mutable borrow occurs here
...
199 |                 e.insert(counts.get(&c).unwrap() + 1);
    |                   ------ ^^^^^^ immutable borrow occurs here
    |                   |
    |                   mutable borrow later used by call

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0502`.
Original diagnostics will follow.

warning: function `silly` is never used
   --> src/day_7.rs:187:4
    |
187 | fn silly() {
    |    ^^^^^
    |
    = note: `#[warn(dead_code)]` on by default

warning: usage of `contains_key` followed by `insert` on a `HashMap`
  --> src/day_7.rs:92:17
   |
92 | /                 if !counts.contains_key(&c) {
93 | |                     counts.insert(c, 1);
94 | |                 } else {
95 | |                     counts.insert(c, counts.get(&c).unwrap() + 1);
96 | |                 }
   | |_________________^
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#map_entry
   = note: `#[warn(clippy::map_entry)]` on by default
help: try
   |
92 ~                 match counts.entry(c) {
93 +                     std::collections::hash_map::Entry::Vacant(e) => {
94 +                         e.insert(1);
95 +                     }
96 +                     std::collections::hash_map::Entry::Occupied(mut e) => {
97 +                         e.insert(counts.get(&c).unwrap() + 1);
98 +                     }
99 +                 }
   |

warning: usage of `contains_key` followed by `insert` on a `HashMap`
   --> src/day_7.rs:191:9
    |
191 | /         if !counts.contains_key(&c) {
192 | |             counts.insert(c, 1);
193 | |         } else {
194 | |             counts.insert(c, counts.get(&c).unwrap() + 1);
195 | |         }
    | |_________^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#map_entry
help: try
    |
191 ~         match counts.entry(c) {
192 +             std::collections::hash_map::Entry::Vacant(e) => {
193 +                 e.insert(1);
194 +             }
195 +             std::collections::hash_map::Entry::Occupied(mut e) => {
196 +                 e.insert(counts.get(&c).unwrap() + 1);
197 +             }
198 +         }
    |

warning: `all-days` (bin "day_7" test) generated 3 warnings (run `cargo clippy --fix --bin "day_7" --tests` to apply 2 suggestions)
warning: failed to automatically apply fixes suggested by rustc to crate `day_7`

after fixes were automatically applied the compiler reported errors within these files:

  * src/day_7.rs

This likely indicates a bug in either rustc or cargo itself,
and we would appreciate a bug report! You're likely to see 
a number of compiler warnings after this message which cargo
attempted to fix but failed. If you could open an issue at
https://github.com/rust-lang/rust-clippy/issues
quoting the full output of this command we'd be very appreciative!
Note that you may be able to make some more progress in the near-term
fixing code with the `--broken-code` flag

The following errors were reported:
error[E0502]: cannot borrow `counts` as immutable because it is also borrowed as mutable
  --> src/day_7.rs:97:34
   |
92 |                 match counts.entry(c) {
   |                       ------ mutable borrow occurs here
...
97 |                         e.insert(counts.get(&c).unwrap() + 1);
   |                           ------ ^^^^^^ immutable borrow occurs here
   |                           |
   |                           mutable borrow later used by call

error[E0502]: cannot borrow `counts` as immutable because it is also borrowed as mutable
   --> src/day_7.rs:199:26
    |
194 |         match counts.entry(c) {
    |               ------ mutable borrow occurs here
...
199 |                 e.insert(counts.get(&c).unwrap() + 1);
    |                   ------ ^^^^^^ immutable borrow occurs here
    |                   |
    |                   mutable borrow later used by call

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0502`.
Original diagnostics will follow.

warning: `all-days` (bin "day_7") generated 3 warnings (3 duplicates)

Version

rustc 1.74.0 (79e9716c9 2023-11-13)
binary: rustc
commit-hash: 79e9716c980570bfd1f666e3b16ac583f0168962
commit-date: 2023-11-13
host: aarch64-apple-darwin
release: 1.74.0
LLVM version: 17.0.4

Additional Labels

No response

Metadata

Metadata

Assignees

Labels

C-bugCategory: Clippy is not doing the correct thingI-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