{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreigvj34ck7wvcim4mdfhd4qhmcxlqdsqil2zi4gmqamzlwfljapmdq",
    "uri": "at://did:plc:ivbknywyskln22er3nkssdhl/app.bsky.feed.post/3meqbhrgro7t2"
  },
  "path": "/t/get-mut-map-back-from-entry-api/24003#post_1",
  "publishedAt": "2026-02-13T09:15:22.000Z",
  "site": "https://internals.rust-lang.org",
  "textContent": "Consider the following API:\n\n\n    use std::collections::HashMap;\n    use std::hash::Hash;\n\n    pub fn get_priority_mut<'a, K, V>(\n        map: &'a mut HashMap<K, V>,\n        key1: &K,\n        key2: &K,\n    ) -> Option<&'a mut V>\n    where\n        K: Eq + Hash,\n    {\n        // Check for the first key without mutably borrowing the map\n        if map.contains_key(key1) {\n            map.get_mut(key1)\n        } else {\n            // If the first isn't there, we are free to mutably borrow for the second\n            map.get_mut(key2)\n        }\n    }\n\n\nI would like to avoid the double-lookup of `key1`, but we can't because of the usual borrow checker limitation. The usual fix for that is to use entry api, but even that doesn't work in this case:\n\n\n    use std::collections::HashMap;\n    use std::collections::hash_map::Entry;\n    use std::hash::Hash;\n\n    // ❌ THIS WILL NOT COMPILE\n    pub fn get_priority_mut_entry<'a, K, V>(\n        map: &'a mut HashMap<K, V>,\n        key1: K,\n        key2: K,\n    ) -> Option<&'a mut V>\n    where\n        K: Eq + Hash,\n    {\n        match map.entry(key1) {\n            Entry::Occupied(occupied) => Some(occupied.into_mut()),\n            Entry::Vacant(_vacant) => {\n                match map.entry(key2) {\n                    Entry::Occupied(occupied2) => Some(occupied2.into_mut()),\n                    Entry::Vacant(_) => None,\n                }\n            }\n        }\n    }\n\n\n\n    error[E0499]: cannot borrow `*map` as mutable more than once at a time\n      --> src/lib.rs:17:19\n       |\n     6 | pub fn get_priority_mut_entry<'a, K, V>(\n       |                               -- lifetime `'a` defined here\n    ...\n    14 |     match map.entry(key1) {\n       |           --- first mutable borrow occurs here\n    15 |         Entry::Occupied(occupied) => Some(occupied.into_mut()),\n       |                                      ------------------------- returning this value requires that `*map` is borrowed for `'a`\n    16 |         Entry::Vacant(_vacant) => {\n    17 |             match map.entry(key2) {\n       |                   ^^^ second mutable borrow occurs here\n\n\nI'd like to propose a potential solution: Add a method to `[Vacant|Occupied]Entry` that consumes the entry and returns `&mut HashMap`. If you had this API, you could write this:\n\n\n    match map.entry(key1) {\n        Entry::Occupied(occupied) => Some(occupied.into_mut()),\n        Entry::Vacant(vacant) => {\n            match vacant.into_map().entry(key2) {\n                Entry::Occupied(occupied2) => Some(occupied2.into_mut()),\n                Entry::Vacant(_) => None,\n            }\n        }\n    }\n\n\nwhich does not run into the borrow checker limitation.",
  "title": "Get `&mut Map` back from entry API"
}