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::{AllocatorClone, 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_ext", issue = "163177", implied_by = "allocator_api")] A: AllocatorClone = 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: AllocatorClone> 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_ext", issue = "163177", implied_by = "allocator_api")] A: AllocatorClone = 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: AllocatorClone> 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_ext", issue = "163177", implied_by = "allocator_api")] A: AllocatorClone = 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: AllocatorClone> 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, key, and the value that was not inserted.
101#[unstable(feature = "map_try_insert", issue = "82766")]
102#[non_exhaustive]
103pub struct OccupiedError<
104 'a,
105 K: 'a,
106 V: 'a,
107 #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] A: AllocatorClone = Global,
108> {
109 /// The entry in the map that was already occupied.
110 pub entry: OccupiedEntry<'a, K, V, A>,
111 /// The key which was not inserted, because the entry was already occupied.
112 pub key: K,
113 /// The value which was not inserted, because the entry was already occupied.
114 pub value: V,
115}
116
117#[unstable(feature = "map_try_insert", issue = "82766")]
118impl<K: Debug + Ord, V: Debug, A: AllocatorClone> Debug for OccupiedError<'_, K, V, A> {
119 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120 f.debug_struct("OccupiedError")
121 .field("key", self.entry.key())
122 .field("uninserted_key", &self.key)
123 .field("old_value", self.entry.get())
124 .field("new_value", &self.value)
125 .finish()
126 }
127}
128
129impl<'a, K: Ord, V, A: AllocatorClone> Entry<'a, K, V, A> {
130 /// Ensures a value is in the entry by inserting the default if empty, and returns
131 /// a mutable reference to the value in the entry.
132 ///
133 /// # Examples
134 ///
135 /// ```
136 /// use std::collections::BTreeMap;
137 ///
138 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
139 /// map.entry("poneyland").or_insert(12);
140 ///
141 /// assert_eq!(map["poneyland"], 12);
142 /// ```
143 #[stable(feature = "rust1", since = "1.0.0")]
144 pub fn or_insert(self, default: V) -> &'a mut V {
145 match self {
146 Occupied(entry) => entry.into_mut(),
147 Vacant(entry) => entry.insert(default),
148 }
149 }
150
151 /// Ensures a value is in the entry by inserting the result of the default function if empty,
152 /// and returns a mutable reference to the value in the entry.
153 ///
154 /// # Examples
155 ///
156 /// ```
157 /// use std::collections::BTreeMap;
158 ///
159 /// let mut map: BTreeMap<&str, String> = BTreeMap::new();
160 /// let s = "hoho".to_string();
161 ///
162 /// map.entry("poneyland").or_insert_with(|| s);
163 ///
164 /// assert_eq!(map["poneyland"], "hoho".to_string());
165 /// ```
166 #[stable(feature = "rust1", since = "1.0.0")]
167 pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
168 self.or_try_insert_with(|| Result::<_, !>::Ok(default())).unwrap()
169 }
170
171 /// Ensures a value is in the entry by inserting the result of a fallible default function
172 /// if empty, and returns a mutable reference to the value in the entry.
173 ///
174 /// This method works identically to [`or_insert_with`] except that the default function
175 /// should return a `Result` and, in the case of an error, the error is propagated.
176 ///
177 /// [`or_insert_with`]: Self::or_insert_with
178 ///
179 /// # Examples
180 ///
181 /// ```
182 /// #![feature(try_entry)]
183 /// # fn main() -> Result<(), std::num::ParseIntError> {
184 /// use std::collections::BTreeMap;
185 ///
186 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
187 /// let value = "42";
188 ///
189 /// map.entry("poneyland").or_try_insert_with(|| value.parse())?;
190 ///
191 /// assert_eq!(map["poneyland"], 42);
192 /// # Ok(())
193 /// # }
194 /// ```
195 #[inline]
196 #[unstable(feature = "try_entry", issue = "157354")]
197 pub fn or_try_insert_with<F: FnOnce() -> Result<V, E>, E>(
198 self,
199 default: F,
200 ) -> Result<&'a mut V, E> {
201 match self {
202 Occupied(entry) => Ok(entry.into_mut()),
203 Vacant(entry) => Ok(entry.insert(default()?)),
204 }
205 }
206
207 /// Ensures a value is in the entry by inserting, if empty, the result of the default function.
208 ///
209 /// This method allows for generating key-derived values for insertion by providing the default
210 /// function a reference to the key that was moved during the `.entry(key)` method call.
211 ///
212 /// The reference to the moved key is provided so that cloning or copying the key is
213 /// unnecessary, unlike with `.or_insert_with(|| ... )`.
214 ///
215 /// # Examples
216 ///
217 /// ```
218 /// use std::collections::BTreeMap;
219 ///
220 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
221 ///
222 /// map.entry("poneyland").or_insert_with_key(|key| key.chars().count());
223 ///
224 /// assert_eq!(map["poneyland"], 9);
225 /// ```
226 #[inline]
227 #[stable(feature = "or_insert_with_key", since = "1.50.0")]
228 pub fn or_insert_with_key<F: FnOnce(&K) -> V>(self, default: F) -> &'a mut V {
229 self.or_try_insert_with_key(|k| Result::<_, !>::Ok(default(k))).into_ok()
230 }
231
232 /// Ensures a value is in the entry by inserting, if empty, the result of the default function.
233 /// This method allows for generating key-derived values for insertion by providing the default
234 /// function a reference to the key that was moved during the `entry(key)` method call.
235 ///
236 /// This method works identically to [`or_insert_with_key`] except that the default function
237 /// should return a `Result` and, in the case of an error, the error is propagated.
238 ///
239 /// [`or_insert_with_key`]: Self::or_insert_with_key
240 ///
241 /// # Examples
242 ///
243 /// ```
244 /// #![feature(try_entry)]
245 /// # fn main() -> Result<(), std::num::ParseIntError> {
246 /// use std::collections::BTreeMap;
247 ///
248 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
249 ///
250 /// map.entry("42").or_try_insert_with_key(|key| key.parse())?;
251 ///
252 /// assert_eq!(map["42"], 42);
253 /// # Ok(())
254 /// # }
255 /// ```
256 #[inline]
257 #[unstable(feature = "try_entry", issue = "157354")]
258 pub fn or_try_insert_with_key<F: FnOnce(&K) -> Result<V, E>, E>(
259 self,
260 default: F,
261 ) -> Result<&'a mut V, E> {
262 match self {
263 Occupied(entry) => Ok(entry.into_mut()),
264 Vacant(entry) => {
265 let value = default(entry.key())?;
266 Ok(entry.insert(value))
267 }
268 }
269 }
270
271 /// Returns a reference to this entry's key.
272 ///
273 /// # Examples
274 ///
275 /// ```
276 /// use std::collections::BTreeMap;
277 ///
278 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
279 /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
280 /// ```
281 #[stable(feature = "map_entry_keys", since = "1.10.0")]
282 pub fn key(&self) -> &K {
283 match *self {
284 Occupied(ref entry) => entry.key(),
285 Vacant(ref entry) => entry.key(),
286 }
287 }
288
289 /// Provides in-place mutable access to an occupied entry before any
290 /// potential inserts into the map.
291 ///
292 /// # Examples
293 ///
294 /// ```
295 /// use std::collections::BTreeMap;
296 ///
297 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
298 ///
299 /// map.entry("poneyland")
300 /// .and_modify(|e| { *e += 1 })
301 /// .or_insert(42);
302 /// assert_eq!(map["poneyland"], 42);
303 ///
304 /// map.entry("poneyland")
305 /// .and_modify(|e| { *e += 1 })
306 /// .or_insert(42);
307 /// assert_eq!(map["poneyland"], 43);
308 /// ```
309 #[stable(feature = "entry_and_modify", since = "1.26.0")]
310 pub fn and_modify<F>(self, f: F) -> Self
311 where
312 F: FnOnce(&mut V),
313 {
314 match self {
315 Occupied(mut entry) => {
316 f(entry.get_mut());
317 Occupied(entry)
318 }
319 Vacant(entry) => Vacant(entry),
320 }
321 }
322
323 /// Sets the value of the entry, and returns an `OccupiedEntry`.
324 ///
325 /// # Examples
326 ///
327 /// ```
328 /// use std::collections::BTreeMap;
329 ///
330 /// let mut map: BTreeMap<&str, String> = BTreeMap::new();
331 /// let entry = map.entry("poneyland").insert_entry("hoho".to_string());
332 ///
333 /// assert_eq!(entry.key(), &"poneyland");
334 /// assert_eq!(entry.get(), &"hoho");
335 /// ```
336 #[inline]
337 #[stable(feature = "btree_entry_insert", since = "1.92.0")]
338 pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, A> {
339 match self {
340 Occupied(mut entry) => {
341 entry.insert(value);
342 entry
343 }
344 Vacant(entry) => entry.insert_entry(value),
345 }
346 }
347}
348
349impl<'a, K: Ord, V: Default, A: AllocatorClone> Entry<'a, K, V, A> {
350 #[stable(feature = "entry_or_default", since = "1.28.0")]
351 /// Ensures a value is in the entry by inserting the default value if empty,
352 /// and returns a mutable reference to the value in the entry.
353 ///
354 /// # Examples
355 ///
356 /// ```
357 /// use std::collections::BTreeMap;
358 ///
359 /// let mut map: BTreeMap<&str, Option<usize>> = BTreeMap::new();
360 /// map.entry("poneyland").or_default();
361 ///
362 /// assert_eq!(map["poneyland"], None);
363 /// ```
364 pub fn or_default(self) -> &'a mut V {
365 match self {
366 Occupied(entry) => entry.into_mut(),
367 Vacant(entry) => entry.insert(Default::default()),
368 }
369 }
370}
371
372impl<'a, K: Ord, V, A: AllocatorClone> VacantEntry<'a, K, V, A> {
373 /// Gets a reference to the key that would be used when inserting a value
374 /// through the VacantEntry.
375 ///
376 /// # Examples
377 ///
378 /// ```
379 /// use std::collections::BTreeMap;
380 ///
381 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
382 /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
383 /// ```
384 #[stable(feature = "map_entry_keys", since = "1.10.0")]
385 pub fn key(&self) -> &K {
386 &self.key
387 }
388
389 /// Take ownership of the key.
390 ///
391 /// # Examples
392 ///
393 /// ```
394 /// use std::collections::BTreeMap;
395 /// use std::collections::btree_map::Entry;
396 ///
397 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
398 ///
399 /// if let Entry::Vacant(v) = map.entry("poneyland") {
400 /// v.into_key();
401 /// }
402 /// ```
403 #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")]
404 pub fn into_key(self) -> K {
405 self.key
406 }
407
408 /// Sets the value of the entry with the `VacantEntry`'s key,
409 /// and returns a mutable reference to it.
410 ///
411 /// # Examples
412 ///
413 /// ```
414 /// use std::collections::BTreeMap;
415 /// use std::collections::btree_map::Entry;
416 ///
417 /// let mut map: BTreeMap<&str, u32> = BTreeMap::new();
418 ///
419 /// if let Entry::Vacant(o) = map.entry("poneyland") {
420 /// o.insert(37);
421 /// }
422 /// assert_eq!(map["poneyland"], 37);
423 /// ```
424 #[stable(feature = "rust1", since = "1.0.0")]
425 #[rustc_confusables("push", "put")]
426 pub fn insert(self, value: V) -> &'a mut V {
427 self.insert_entry(value).into_mut()
428 }
429
430 /// Sets the value of the entry with the `VacantEntry`'s key,
431 /// and returns an `OccupiedEntry`.
432 ///
433 /// # Examples
434 ///
435 /// ```
436 /// use std::collections::BTreeMap;
437 /// use std::collections::btree_map::Entry;
438 ///
439 /// let mut map: BTreeMap<&str, u32> = BTreeMap::new();
440 ///
441 /// if let Entry::Vacant(o) = map.entry("poneyland") {
442 /// let entry = o.insert_entry(37);
443 /// assert_eq!(entry.get(), &37);
444 /// }
445 /// assert_eq!(map["poneyland"], 37);
446 /// ```
447 #[stable(feature = "btree_entry_insert", since = "1.92.0")]
448 pub fn insert_entry(mut self, value: V) -> OccupiedEntry<'a, K, V, A> {
449 let handle = match self.handle {
450 None => {
451 // SAFETY: There is no tree yet so no reference to it exists.
452 let map = unsafe { self.dormant_map.reborrow() };
453 let root = map.root.insert(NodeRef::new_leaf(self.alloc.clone()).forget_type());
454 // SAFETY: We *just* created the root as a leaf, and we're
455 // stacking the new handle on the original borrow lifetime.
456 unsafe {
457 let mut leaf = root.borrow_mut().cast_to_leaf_unchecked();
458 leaf.push_with_handle(self.key, value)
459 }
460 }
461 Some(handle) => handle.insert_recursing(self.key, value, self.alloc.clone(), |ins| {
462 drop(ins.left);
463 // SAFETY: Pushing a new root node doesn't invalidate
464 // handles to existing nodes.
465 let map = unsafe { self.dormant_map.reborrow() };
466 let root = map.root.as_mut().unwrap(); // same as ins.left
467 root.push_internal_level(self.alloc.clone()).push(ins.kv.0, ins.kv.1, ins.right)
468 }),
469 };
470
471 // SAFETY: modifying the length doesn't invalidate handles to existing nodes.
472 unsafe { self.dormant_map.reborrow().length += 1 };
473
474 OccupiedEntry {
475 handle: handle.forget_node_type(),
476 dormant_map: self.dormant_map,
477 alloc: self.alloc,
478 _marker: PhantomData,
479 }
480 }
481}
482
483impl<'a, K: Ord, V, A: AllocatorClone> OccupiedEntry<'a, K, V, A> {
484 /// Gets a reference to the key in the entry.
485 ///
486 /// # Examples
487 ///
488 /// ```
489 /// use std::collections::BTreeMap;
490 ///
491 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
492 /// map.entry("poneyland").or_insert(12);
493 /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
494 /// ```
495 #[must_use]
496 #[stable(feature = "map_entry_keys", since = "1.10.0")]
497 pub fn key(&self) -> &K {
498 self.handle.reborrow().into_kv().0
499 }
500
501 /// Converts the entry into a reference to its key.
502 pub(crate) fn into_key(self) -> &'a K {
503 self.handle.into_kv_mut().0
504 }
505
506 /// Take ownership of the key and value from the map.
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 /// if let Entry::Occupied(o) = map.entry("poneyland") {
518 /// // We delete the entry from the map.
519 /// o.remove_entry();
520 /// }
521 ///
522 /// // If now try to get the value, it will panic:
523 /// // println!("{}", map["poneyland"]);
524 /// ```
525 #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")]
526 pub fn remove_entry(self) -> (K, V) {
527 self.remove_kv()
528 }
529
530 /// Gets a reference to the value in the entry.
531 ///
532 /// # Examples
533 ///
534 /// ```
535 /// use std::collections::BTreeMap;
536 /// use std::collections::btree_map::Entry;
537 ///
538 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
539 /// map.entry("poneyland").or_insert(12);
540 ///
541 /// if let Entry::Occupied(o) = map.entry("poneyland") {
542 /// assert_eq!(o.get(), &12);
543 /// }
544 /// ```
545 #[must_use]
546 #[stable(feature = "rust1", since = "1.0.0")]
547 pub fn get(&self) -> &V {
548 self.handle.reborrow().into_kv().1
549 }
550
551 /// Gets a mutable reference to the value in the entry.
552 ///
553 /// If you need a reference to the `OccupiedEntry` that may outlive the
554 /// destruction of the `Entry` value, see [`into_mut`].
555 ///
556 /// [`into_mut`]: OccupiedEntry::into_mut
557 ///
558 /// # Examples
559 ///
560 /// ```
561 /// use std::collections::BTreeMap;
562 /// use std::collections::btree_map::Entry;
563 ///
564 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
565 /// map.entry("poneyland").or_insert(12);
566 ///
567 /// assert_eq!(map["poneyland"], 12);
568 /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
569 /// *o.get_mut() += 10;
570 /// assert_eq!(*o.get(), 22);
571 ///
572 /// // We can use the same Entry multiple times.
573 /// *o.get_mut() += 2;
574 /// }
575 /// assert_eq!(map["poneyland"], 24);
576 /// ```
577 #[stable(feature = "rust1", since = "1.0.0")]
578 pub fn get_mut(&mut self) -> &mut V {
579 self.handle.kv_mut().1
580 }
581
582 /// Converts the entry into a mutable reference to its value.
583 ///
584 /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
585 ///
586 /// [`get_mut`]: OccupiedEntry::get_mut
587 ///
588 /// # Examples
589 ///
590 /// ```
591 /// use std::collections::BTreeMap;
592 /// use std::collections::btree_map::Entry;
593 ///
594 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
595 /// map.entry("poneyland").or_insert(12);
596 ///
597 /// assert_eq!(map["poneyland"], 12);
598 /// if let Entry::Occupied(o) = map.entry("poneyland") {
599 /// *o.into_mut() += 10;
600 /// }
601 /// assert_eq!(map["poneyland"], 22);
602 /// ```
603 #[must_use = "`self` will be dropped if the result is not used"]
604 #[stable(feature = "rust1", since = "1.0.0")]
605 pub fn into_mut(self) -> &'a mut V {
606 self.handle.into_val_mut()
607 }
608
609 /// Sets the value of the entry with the `OccupiedEntry`'s key,
610 /// and returns the entry's old value.
611 ///
612 /// # Examples
613 ///
614 /// ```
615 /// use std::collections::BTreeMap;
616 /// use std::collections::btree_map::Entry;
617 ///
618 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
619 /// map.entry("poneyland").or_insert(12);
620 ///
621 /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
622 /// assert_eq!(o.insert(15), 12);
623 /// }
624 /// assert_eq!(map["poneyland"], 15);
625 /// ```
626 #[stable(feature = "rust1", since = "1.0.0")]
627 #[rustc_confusables("push", "put")]
628 pub fn insert(&mut self, value: V) -> V {
629 mem::replace(self.get_mut(), value)
630 }
631
632 /// Takes the value of the entry out of the map, and returns it.
633 ///
634 /// # Examples
635 ///
636 /// ```
637 /// use std::collections::BTreeMap;
638 /// use std::collections::btree_map::Entry;
639 ///
640 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
641 /// map.entry("poneyland").or_insert(12);
642 ///
643 /// if let Entry::Occupied(o) = map.entry("poneyland") {
644 /// assert_eq!(o.remove(), 12);
645 /// }
646 /// // If we try to get "poneyland"'s value, it'll panic:
647 /// // println!("{}", map["poneyland"]);
648 /// ```
649 #[stable(feature = "rust1", since = "1.0.0")]
650 #[rustc_confusables("delete", "take")]
651 pub fn remove(self) -> V {
652 self.remove_kv().1
653 }
654
655 // Body of `remove_entry`, probably separate because the name reflects the returned pair.
656 pub(super) fn remove_kv(self) -> (K, V) {
657 let mut emptied_internal_root = false;
658 let (old_kv, _) =
659 self.handle.remove_kv_tracking(|| emptied_internal_root = true, self.alloc.clone());
660 // SAFETY: we consumed the intermediate root borrow, `self.handle`.
661 let map = unsafe { self.dormant_map.awaken() };
662 map.length -= 1;
663 if emptied_internal_root {
664 let root = map.root.as_mut().unwrap();
665 root.pop_internal_level(self.alloc);
666 }
667 old_kv
668 }
669}