entry.rs - source
Description: Source of the Rust file `library/alloc/src/collections/btree/map/entry.rs`.

#
alloc/collections/btree/map/
entry.rs

    1use core::fmt::{self, Debug};
    2use core::marker::PhantomData;
    3use core::mem;
    4
    5use Entry::*;
    6
    7use super::super::borrow::DormantMutRef;
    8use super::super::node::{Handle, NodeRef, marker};
    9use super::BTreeMap;
    10use crate::alloc::{Allocator, Global};
    11
    12/// A view into a single entry in a map, which may either be vacant or occupied.
    13///
    14/// This `enum` is constructed from the [`entry`] method on [`BTreeMap`].
    15///
    16/// [`entry`]: BTreeMap::entry
    17#[stable(feature = "rust1", since = "1.0.0")]
    18#[cfg_attr(not(test), rustc_diagnostic_item = "BTreeEntry")]
    19pub enum Entry<
    20    'a,
    21    K: 'a,
    22    V: 'a,
    23    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global,
    24> {
    25    /// A vacant entry.
    26    #[stable(feature = "rust1", since = "1.0.0")]
    27    Vacant(#[stable(feature = "rust1", since = "1.0.0")] VacantEntry<'a, K, V, A>),
    28
    29    /// An occupied entry.
    30    #[stable(feature = "rust1", since = "1.0.0")]
    31    Occupied(#[stable(feature = "rust1", since = "1.0.0")] OccupiedEntry<'a, K, V, A>),
    32}
    33
    34#[stable(feature = "debug_btree_map", since = "1.12.0")]
    35impl<K: Debug + Ord, V: Debug, A: Allocator + Clone> Debug for Entry<'_, K, V, A> {
    36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    37        match *self {
    38            Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
    39            Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
    40        }
    41    }
    42}
    43
    44/// A view into a vacant entry in a `BTreeMap`.
    45/// It is part of the [`Entry`] enum.
    46#[stable(feature = "rust1", since = "1.0.0")]
    47pub struct VacantEntry<
    48    'a,
    49    K,
    50    V,
    51    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global,
    52> {
    53    pub(super) key: K,
    54    /// `None` for a (empty) map without root
    55    pub(super) handle: Option<Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>>,
    56    pub(super) dormant_map: DormantMutRef<'a, BTreeMap<K, V, A>>,
    57
    58    /// The BTreeMap will outlive this IntoIter so we don't care about drop order for `alloc`.
    59    pub(super) alloc: A,
    60
    61    // Be invariant in `K` and `V`
    62    pub(super) _marker: PhantomData<&'a mut (K, V)>,
    63}
    64
    65#[stable(feature = "debug_btree_map", since = "1.12.0")]
    66impl<K: Debug + Ord, V, A: Allocator + Clone> Debug for VacantEntry<'_, K, V, A> {
    67    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    68        f.debug_tuple("VacantEntry").field(self.key()).finish()
    69    }
    70}
    71
    72/// A view into an occupied entry in a `BTreeMap`.
    73/// It is part of the [`Entry`] enum.
    74#[stable(feature = "rust1", since = "1.0.0")]
    75pub struct OccupiedEntry<
    76    'a,
    77    K,
    78    V,
    79    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global,
    80> {
    81    pub(super) handle: Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV>,
    82    pub(super) dormant_map: DormantMutRef<'a, BTreeMap<K, V, A>>,
    83
    84    /// The BTreeMap will outlive this IntoIter so we don't care about drop order for `alloc`.
    85    pub(super) alloc: A,
    86
    87    // Be invariant in `K` and `V`
    88    pub(super) _marker: PhantomData<&'a mut (K, V)>,
    89}
    90
    91#[stable(feature = "debug_btree_map", since = "1.12.0")]
    92impl<K: Debug + Ord, V: Debug, A: Allocator + Clone> Debug for OccupiedEntry<'_, K, V, A> {
    93    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    94        f.debug_struct("OccupiedEntry").field("key", self.key()).field("value", self.get()).finish()
    95    }
    96}
    97
    98/// The error returned by [`try_insert`](BTreeMap::try_insert) when the key already exists.
    99///
    100/// Contains the occupied entry, and the value that was not inserted.
    101#[unstable(feature = "map_try_insert", issue = "82766")]
    102pub struct OccupiedError<
    103    'a,
    104    K: 'a,
    105    V: 'a,
    106    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global,
    107> {
    108    /// The entry in the map that was already occupied.
    109    pub entry: OccupiedEntry<'a, K, V, A>,
    110    /// The value which was not inserted, because the entry was already occupied.
    111    pub value: V,
    112}
    113
    114#[unstable(feature = "map_try_insert", issue = "82766")]
    115impl<K: Debug + Ord, V: Debug, A: Allocator + Clone> Debug for OccupiedError<'_, K, V, A> {
    116    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    117        f.debug_struct("OccupiedError")
    118            .field("key", self.entry.key())
    119            .field("old_value", self.entry.get())
    120            .field("new_value", &self.value)
    121            .finish()
    122    }
    123}
    124
    125#[unstable(feature = "map_try_insert", issue = "82766")]
    126impl<'a, K: Debug + Ord, V: Debug, A: Allocator + Clone> fmt::Display
    127    for OccupiedError<'a, K, V, A>
    128{
    129    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    130        write!(
    131            f,
    132            "failed to insert {:?}, key {:?} already exists with value {:?}",
    133            self.value,
    134            self.entry.key(),
    135            self.entry.get(),
    136        )
    137    }
    138}
    139
    140#[unstable(feature = "map_try_insert", issue = "82766")]
    141impl<'a, K: core::fmt::Debug + Ord, V: core::fmt::Debug> core::error::Error
    142    for crate::collections::btree_map::OccupiedError<'a, K, V>
    143{
    144}
    145
    146impl<'a, K: Ord, V, A: Allocator + Clone> Entry<'a, K, V, A> {
    147    /// Ensures a value is in the entry by inserting the default if empty, and returns
    148    /// a mutable reference to the value in the entry.
    149    ///
    150    /// # Examples
    151    ///
    152    /// ```
    153    /// use std::collections::BTreeMap;
    154    ///
    155    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
    156    /// map.entry("poneyland").or_insert(12);
    157    ///
    158    /// assert_eq!(map["poneyland"], 12);
    159    /// ```
    160    #[stable(feature = "rust1", since = "1.0.0")]
    161    pub fn or_insert(self, default: V) -> &'a mut V {
    162        match self {
    163            Occupied(entry) => entry.into_mut(),
    164            Vacant(entry) => entry.insert(default),
    165        }
    166    }
    167
    168    /// Ensures a value is in the entry by inserting the result of the default function if empty,
    169    /// and returns a mutable reference to the value in the entry.
    170    ///
    171    /// # Examples
    172    ///
    173    /// ```
    174    /// use std::collections::BTreeMap;
    175    ///
    176    /// let mut map: BTreeMap<&str, String> = BTreeMap::new();
    177    /// let s = "hoho".to_string();
    178    ///
    179    /// map.entry("poneyland").or_insert_with(|| s);
    180    ///
    181    /// assert_eq!(map["poneyland"], "hoho".to_string());
    182    /// ```
    183    #[stable(feature = "rust1", since = "1.0.0")]
    184    pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
    185        match self {
    186            Occupied(entry) => entry.into_mut(),
    187            Vacant(entry) => entry.insert(default()),
    188        }
    189    }
    190
    191    /// Ensures a value is in the entry by inserting, if empty, the result of the default function.
    192    ///
    193    /// This method allows for generating key-derived values for insertion by providing the default
    194    /// function a reference to the key that was moved during the `.entry(key)` method call.
    195    ///
    196    /// The reference to the moved key is provided so that cloning or copying the key is
    197    /// unnecessary, unlike with `.or_insert_with(|| ... )`.
    198    ///
    199    /// # Examples
    200    ///
    201    /// ```
    202    /// use std::collections::BTreeMap;
    203    ///
    204    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
    205    ///
    206    /// map.entry("poneyland").or_insert_with_key(|key| key.chars().count());
    207    ///
    208    /// assert_eq!(map["poneyland"], 9);
    209    /// ```
    210    #[inline]
    211    #[stable(feature = "or_insert_with_key", since = "1.50.0")]
    212    pub fn or_insert_with_key<F: FnOnce(&K) -> V>(self, default: F) -> &'a mut V {
    213        match self {
    214            Occupied(entry) => entry.into_mut(),
    215            Vacant(entry) => {
    216                let value = default(entry.key());
    217                entry.insert(value)
    218            }
    219        }
    220    }
    221
    222    /// Returns a reference to this entry's key.
    223    ///
    224    /// # Examples
    225    ///
    226    /// ```
    227    /// use std::collections::BTreeMap;
    228    ///
    229    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
    230    /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
    231    /// ```
    232    #[stable(feature = "map_entry_keys", since = "1.10.0")]
    233    pub fn key(&self) -> &K {
    234        match *self {
    235            Occupied(ref entry) => entry.key(),
    236            Vacant(ref entry) => entry.key(),
    237        }
    238    }
    239
    240    /// Provides in-place mutable access to an occupied entry before any
    241    /// potential inserts into the map.
    242    ///
    243    /// # Examples
    244    ///
    245    /// ```
    246    /// use std::collections::BTreeMap;
    247    ///
    248    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
    249    ///
    250    /// map.entry("poneyland")
    251    ///    .and_modify(|e| { *e += 1 })
    252    ///    .or_insert(42);
    253    /// assert_eq!(map["poneyland"], 42);
    254    ///
    255    /// map.entry("poneyland")
    256    ///    .and_modify(|e| { *e += 1 })
    257    ///    .or_insert(42);
    258    /// assert_eq!(map["poneyland"], 43);
    259    /// ```
    260    #[stable(feature = "entry_and_modify", since = "1.26.0")]
    261    pub fn and_modify<F>(self, f: F) -> Self
    262    where
    263        F: FnOnce(&mut V),
    264    {
    265        match self {
    266            Occupied(mut entry) => {
    267                f(entry.get_mut());
    268                Occupied(entry)
    269            }
    270            Vacant(entry) => Vacant(entry),
    271        }
    272    }
    273
    274    /// Sets the value of the entry, and returns an `OccupiedEntry`.
    275    ///
    276    /// # Examples
    277    ///
    278    /// ```
    279    /// use std::collections::BTreeMap;
    280    ///
    281    /// let mut map: BTreeMap<&str, String> = BTreeMap::new();
    282    /// let entry = map.entry("poneyland").insert_entry("hoho".to_string());
    283    ///
    284    /// assert_eq!(entry.key(), &"poneyland");
    285    /// ```
    286    #[inline]
    287    #[stable(feature = "btree_entry_insert", since = "1.92.0")]
    288    pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, A> {
    289        match self {
    290            Occupied(mut entry) => {
    291                entry.insert(value);
    292                entry
    293            }
    294            Vacant(entry) => entry.insert_entry(value),
    295        }
    296    }
    297}
    298
    299impl<'a, K: Ord, V: Default, A: Allocator + Clone> Entry<'a, K, V, A> {
    300    #[stable(feature = "entry_or_default", since = "1.28.0")]
    301    /// Ensures a value is in the entry by inserting the default value if empty,
    302    /// and returns a mutable reference to the value in the entry.
    303    ///
    304    /// # Examples
    305    ///
    306    /// ```
    307    /// use std::collections::BTreeMap;
    308    ///
    309    /// let mut map: BTreeMap<&str, Option<usize>> = BTreeMap::new();
    310    /// map.entry("poneyland").or_default();
    311    ///
    312    /// assert_eq!(map["poneyland"], None);
    313    /// ```
    314    pub fn or_default(self) -> &'a mut V {
    315        match self {
    316            Occupied(entry) => entry.into_mut(),
    317            Vacant(entry) => entry.insert(Default::default()),
    318        }
    319    }
    320}
    321
    322impl<'a, K: Ord, V, A: Allocator + Clone> VacantEntry<'a, K, V, A> {
    323    /// Gets a reference to the key that would be used when inserting a value
    324    /// through the VacantEntry.
    325    ///
    326    /// # Examples
    327    ///
    328    /// ```
    329    /// use std::collections::BTreeMap;
    330    ///
    331    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
    332    /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
    333    /// ```
    334    #[stable(feature = "map_entry_keys", since = "1.10.0")]
    335    pub fn key(&self) -> &K {
    336        &self.key
    337    }
    338
    339    /// Take ownership of the key.
    340    ///
    341    /// # Examples
    342    ///
    343    /// ```
    344    /// use std::collections::BTreeMap;
    345    /// use std::collections::btree_map::Entry;
    346    ///
    347    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
    348    ///
    349    /// if let Entry::Vacant(v) = map.entry("poneyland") {
    350    ///     v.into_key();
    351    /// }
    352    /// ```
    353    #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")]
    354    pub fn into_key(self) -> K {
    355        self.key
    356    }
    357
    358    /// Sets the value of the entry with the `VacantEntry`'s key,
    359    /// and returns a mutable reference to it.
    360    ///
    361    /// # Examples
    362    ///
    363    /// ```
    364    /// use std::collections::BTreeMap;
    365    /// use std::collections::btree_map::Entry;
    366    ///
    367    /// let mut map: BTreeMap<&str, u32> = BTreeMap::new();
    368    ///
    369    /// if let Entry::Vacant(o) = map.entry("poneyland") {
    370    ///     o.insert(37);
    371    /// }
    372    /// assert_eq!(map["poneyland"], 37);
    373    /// ```
    374    #[stable(feature = "rust1", since = "1.0.0")]
    375    #[rustc_confusables("push", "put")]
    376    pub fn insert(self, value: V) -> &'a mut V {
    377        self.insert_entry(value).into_mut()
    378    }
    379
    380    /// Sets the value of the entry with the `VacantEntry`'s key,
    381    /// and returns an `OccupiedEntry`.
    382    ///
    383    /// # Examples
    384    ///
    385    /// ```
    386    /// use std::collections::BTreeMap;
    387    /// use std::collections::btree_map::Entry;
    388    ///
    389    /// let mut map: BTreeMap<&str, u32> = BTreeMap::new();
    390    ///
    391    /// if let Entry::Vacant(o) = map.entry("poneyland") {
    392    ///     let entry = o.insert_entry(37);
    393    ///     assert_eq!(entry.get(), &37);
    394    /// }
    395    /// assert_eq!(map["poneyland"], 37);
    396    /// ```
    397    #[stable(feature = "btree_entry_insert", since = "1.92.0")]
    398    pub fn insert_entry(mut self, value: V) -> OccupiedEntry<'a, K, V, A> {
    399        let handle = match self.handle {
    400            None => {
    401                // SAFETY: There is no tree yet so no reference to it exists.
    402                let map = unsafe { self.dormant_map.reborrow() };
    403                let root = map.root.insert(NodeRef::new_leaf(self.alloc.clone()).forget_type());
    404                // SAFETY: We *just* created the root as a leaf, and we're
    405                // stacking the new handle on the original borrow lifetime.
    406                unsafe {
    407                    let mut leaf = root.borrow_mut().cast_to_leaf_unchecked();
    408                    leaf.push_with_handle(self.key, value)
    409                }
    410            }
    411            Some(handle) => handle.insert_recursing(self.key, value, self.alloc.clone(), |ins| {
    412                drop(ins.left);
    413                // SAFETY: Pushing a new root node doesn't invalidate
    414                // handles to existing nodes.
    415                let map = unsafe { self.dormant_map.reborrow() };
    416                let root = map.root.as_mut().unwrap(); // same as ins.left
    417                root.push_internal_level(self.alloc.clone()).push(ins.kv.0, ins.kv.1, ins.right)
    418            }),
    419        };
    420
    421        // SAFETY: modifying the length doesn't invalidate handles to existing nodes.
    422        unsafe { self.dormant_map.reborrow().length += 1 };
    423
    424        OccupiedEntry {
    425            handle: handle.forget_node_type(),
    426            dormant_map: self.dormant_map,
    427            alloc: self.alloc,
    428            _marker: PhantomData,
    429        }
    430    }
    431}
    432
    433impl<'a, K: Ord, V, A: Allocator + Clone> OccupiedEntry<'a, K, V, A> {
    434    /// Gets a reference to the key in the entry.
    435    ///
    436    /// # Examples
    437    ///
    438    /// ```
    439    /// use std::collections::BTreeMap;
    440    ///
    441    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
    442    /// map.entry("poneyland").or_insert(12);
    443    /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
    444    /// ```
    445    #[must_use]
    446    #[stable(feature = "map_entry_keys", since = "1.10.0")]
    447    pub fn key(&self) -> &K {
    448        self.handle.reborrow().into_kv().0
    449    }
    450
    451    /// Converts the entry into a reference to its key.
    452    pub(crate) fn into_key(self) -> &'a K {
    453        self.handle.into_kv_mut().0
    454    }
    455
    456    /// Take ownership of the key and value from the map.
    457    ///
    458    /// # Examples
    459    ///
    460    /// ```
    461    /// use std::collections::BTreeMap;
    462    /// use std::collections::btree_map::Entry;
    463    ///
    464    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
    465    /// map.entry("poneyland").or_insert(12);
    466    ///
    467    /// if let Entry::Occupied(o) = map.entry("poneyland") {
    468    ///     // We delete the entry from the map.
    469    ///     o.remove_entry();
    470    /// }
    471    ///
    472    /// // If now try to get the value, it will panic:
    473    /// // println!("{}", map["poneyland"]);
    474    /// ```
    475    #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")]
    476    pub fn remove_entry(self) -> (K, V) {
    477        self.remove_kv()
    478    }
    479
    480    /// Gets a reference to the value in the entry.
    481    ///
    482    /// # Examples
    483    ///
    484    /// ```
    485    /// use std::collections::BTreeMap;
    486    /// use std::collections::btree_map::Entry;
    487    ///
    488    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
    489    /// map.entry("poneyland").or_insert(12);
    490    ///
    491    /// if let Entry::Occupied(o) = map.entry("poneyland") {
    492    ///     assert_eq!(o.get(), &12);
    493    /// }
    494    /// ```
    495    #[must_use]
    496    #[stable(feature = "rust1", since = "1.0.0")]
    497    pub fn get(&self) -> &V {
    498        self.handle.reborrow().into_kv().1
    499    }
    500
    501    /// Gets a mutable reference to the value in the entry.
    502    ///
    503    /// If you need a reference to the `OccupiedEntry` that may outlive the
    504    /// destruction of the `Entry` value, see [`into_mut`].
    505    ///
    506    /// [`into_mut`]: OccupiedEntry::into_mut
    507    ///
    508    /// # Examples
    509    ///
    510    /// ```
    511    /// use std::collections::BTreeMap;
    512    /// use std::collections::btree_map::Entry;
    513    ///
    514    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
    515    /// map.entry("poneyland").or_insert(12);
    516    ///
    517    /// assert_eq!(map["poneyland"], 12);
    518    /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
    519    ///     *o.get_mut() += 10;
    520    ///     assert_eq!(*o.get(), 22);
    521    ///
    522    ///     // We can use the same Entry multiple times.
    523    ///     *o.get_mut() += 2;
    524    /// }
    525    /// assert_eq!(map["poneyland"], 24);
    526    /// ```
    527    #[stable(feature = "rust1", since = "1.0.0")]
    528    pub fn get_mut(&mut self) -> &mut V {
    529        self.handle.kv_mut().1
    530    }
    531
    532    /// Converts the entry into a mutable reference to its value.
    533    ///
    534    /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
    535    ///
    536    /// [`get_mut`]: OccupiedEntry::get_mut
    537    ///
    538    /// # Examples
    539    ///
    540    /// ```
    541    /// use std::collections::BTreeMap;
    542    /// use std::collections::btree_map::Entry;
    543    ///
    544    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
    545    /// map.entry("poneyland").or_insert(12);
    546    ///
    547    /// assert_eq!(map["poneyland"], 12);
    548    /// if let Entry::Occupied(o) = map.entry("poneyland") {
    549    ///     *o.into_mut() += 10;
    550    /// }
    551    /// assert_eq!(map["poneyland"], 22);
    552    /// ```
    553    #[must_use = "`self` will be dropped if the result is not used"]
    554    #[stable(feature = "rust1", since = "1.0.0")]
    555    pub fn into_mut(self) -> &'a mut V {
    556        self.handle.into_val_mut()
    557    }
    558
    559    /// Sets the value of the entry with the `OccupiedEntry`'s key,
    560    /// and returns the entry's old value.
    561    ///
    562    /// # Examples
    563    ///
    564    /// ```
    565    /// use std::collections::BTreeMap;
    566    /// use std::collections::btree_map::Entry;
    567    ///
    568    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
    569    /// map.entry("poneyland").or_insert(12);
    570    ///
    571    /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
    572    ///     assert_eq!(o.insert(15), 12);
    573    /// }
    574    /// assert_eq!(map["poneyland"], 15);
    575    /// ```
    576    #[stable(feature = "rust1", since = "1.0.0")]
    577    #[rustc_confusables("push", "put")]
    578    pub fn insert(&mut self, value: V) -> V {
    579        mem::replace(self.get_mut(), value)
    580    }
    581
    582    /// Takes the value of the entry out of the map, and returns it.
    583    ///
    584    /// # Examples
    585    ///
    586    /// ```
    587    /// use std::collections::BTreeMap;
    588    /// use std::collections::btree_map::Entry;
    589    ///
    590    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
    591    /// map.entry("poneyland").or_insert(12);
    592    ///
    593    /// if let Entry::Occupied(o) = map.entry("poneyland") {
    594    ///     assert_eq!(o.remove(), 12);
    595    /// }
    596    /// // If we try to get "poneyland"'s value, it'll panic:
    597    /// // println!("{}", map["poneyland"]);
    598    /// ```
    599    #[stable(feature = "rust1", since = "1.0.0")]
    600    #[rustc_confusables("delete", "take")]
    601    pub fn remove(self) -> V {
    602        self.remove_kv().1
    603    }
    604
    605    // Body of `remove_entry`, probably separate because the name reflects the returned pair.
    606    pub(super) fn remove_kv(self) -> (K, V) {
    607        let mut emptied_internal_root = false;
    608        let (old_kv, _) =
    609            self.handle.remove_kv_tracking(|| emptied_internal_root = true, self.alloc.clone());
    610        // SAFETY: we consumed the intermediate root borrow, `self.handle`.
    611        let map = unsafe { self.dormant_map.awaken() };
    612        map.length -= 1;
    613        if emptied_internal_root {
    614            let root = map.root.as_mut().unwrap();
    615            root.pop_internal_level(self.alloc);
    616        }
    617        old_kv
    618    }
    619}