Skip to content

Type confusion when interacting with HashMap both via Borrow and directly #141008

@bertptrs

Description

@bertptrs

I tried this code, simplified from the larger example.

use std::collections::HashMap;
use std::borrow::Borrow;
use std::hash::Hash;

pub struct MyStruct<K>(HashMap<K, Vec<K>>);

impl<K> MyStruct<K>
where K: Hash + Eq
{
    pub fn remove<Q>(&mut self, key: &Q)
    where
        Q: Hash + Eq + ?Sized,
        K: Borrow<Q>
    {
        if let Some(val) = self.0.remove(key) {
            for v in val {
                self.0.get_mut(&v).unwrap().clear();
                // works: self.0.get_mut::<K>(&v).unwrap().clear();
            }
        }
    }
}

I expected to see this happen: it compiles successfully.

Instead, this happened: It complains that the argument to get_mut is of type &K rather than the expected type &Q. While this is true, it's irrelevant, as &K is a valid argument to that function. This can be shown by turbofishing the call.

Meta

rustc --version --verbose:

rustc 1.86.0 (05f9846f8 2025-03-31) (Arch Linux rust 1:1.86.0-1)
binary: rustc
commit-hash: 05f9846f893b09a1be1fc8560e33fc3c815cfecb
commit-date: 2025-03-31
host: x86_64-unknown-linux-gnu
release: 1.86.0
LLVM version: 19.1.7

Also verified with nightly via the playground.

Backtrace

<backtrace>

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions