Error message suggestion for cloning HashMap a when K or V don't clone

This took me too long to figure out (I'm still a Rust noob). I was cloning a &HashMap<> so it can become owned, but kept giving me another &HashMap. The error I was getting was similar to this SO question (ignoring that the answer's HashMap contains generics--my case was using concrete types), and here is where I found the answer that I had to make sure K and V are Clone too.

The error:

   = note: expected type `std::collections::HashMap<K, std::collections::HashSet<V>>`
              found type `&std::collections::HashMap<K, std::collections::HashSet<V>>`

This error isn't directly because of that, but it makes me suggest that the compiler can detect that and suggest something along the lines of:

Looks like you tried to clone() your HashMap earlier and it's a still borrow. You will need to make sure your key and value types impl the Clone trait too.

1 Like

This is a more general problem than just with HashMaps, it can happen with any reference.

I can perhaps imagine a compiler that notices when a type mismatch was influenced by calling .clone() on a reference (which is never necessary, since references are Copy) and gives a help message something like

error[E0308]: mismatched types
  --> src/lib.rs:14:28
   |
14 |         self.data.set(Some(data.clone()));
   |                            ^^^^^^^^^^^^ expected struct `std::collections::HashMap`, found reference
   |
   = note: expected struct `std::collections::HashMap<K, std::collections::HashSet<V>>`
           found reference `&std::collections::HashMap<K, std::collections::HashSet<V>>`
note: a reference was cloned instead of the underlying type
  --> src/lib.rs:14:28
   |
14 |         self.data.set(Some(data.clone()));
   |                            ^^^^ this reference was cloned
   |
   = note: because `*data` does not implement `Clone`, `data` was cloned instead due to auto-referencing
   = help: try implementing `Clone` for `std::collections::HashMap<K, std::collections::HashSet<V>>`

I put the help message at the bottom which actually is no help in this particular case, but might be applicable in a lot of other situations where you get similar errors.

One caveat: attaching this note to mismatched types errors only might be overly specific. Calling clone on a reference might cause a wide variety of downstream errors, and is something you should probably never do anyway, so maybe it would be better just to lint whenever type inference calls .clone() by auto-ref, which might be easier to detect.

2 Likes

There is a proposal for a new compiler lint along these lines:

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.