Skip to content

Uplift clippy::clone_double_ref to rustc #109451

Closed
@fee1-dead

Description

@fee1-dead

In #109429, a snippet of code involves cloning references outputted a confusing compiler error:

use std::collections::hash_map::DefaultHasher;
use std::collections::HashMap;
use std::hash::BuildHasher;
use std::hash::Hash;

pub struct Hash128_1;

impl BuildHasher for Hash128_1 {
    type Hasher = DefaultHasher;
    fn build_hasher(&self) -> DefaultHasher { DefaultHasher::default() }
}

#[allow(unused)]
pub fn hashmap_copy<T, U>(
    map: &HashMap<T, U, Hash128_1>,
) where T: Hash + Clone, U: Clone
{
    let mut copy: Vec<U> = map.clone().into_values().collect();
}

pub fn make_map() -> HashMap<String, i64, Hash128_1>
{
    HashMap::with_hasher(Hash128_1)
}
error[E0507]: cannot move out of a shared reference
  --> src/lib.rs:19:28
   |
19 |     let mut copy: Vec<U> = map.clone().into_values().collect();
   |                            ^^^^^^^^^^^^-------------
   |                            |           |
   |                            |           value moved due to this method call
   |                            move occurs because value has type `HashMap<T, U, Hash128_1>`, which does not implement the `Copy` trait
   |
note: `HashMap::<K, V, S>::into_values` takes ownership of the receiver `self`, which moves value

Changing the diagnostic to provide help when we are trying to use a function that takes self after a .clone() call is nontrivial, since this is MIR borrowck and to my knowledge it is hard to know if it comes from the return value of a .clone() call.

Ideally we should have an error/warning like the one from clippy:

error: using `clone` on a double-reference; this will copy the reference of type `&HashMap<T, U, Hash128_1>` instead of cloning the inner type
  --> src/lib.rs:19:28
   |
19 |     let mut copy: Vec<U> = map.clone().into_values().collect();
   |                            ^^^^^^^^^^^

I think there are other ways this can be confusing, so uplifting can help with many issues related to this and not just the example I linked.


cc @rust-lang/lang: would uplifting be a good idea? I'd be willing to work on this if this gets approval.

@rustbot label +A-lint +T-compiler +T-lang +D-newcomer-roadblock

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.D-newcomer-roadblockDiagnostics: Confusing error or lint; hard to understand for new users.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions