From adb7607189e04a20e67fe089d23d418826177186 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Tue, 30 Jan 2024 17:51:20 +0000 Subject: [PATCH] Fix BTreeMap's Cursor::remove_{next,prev} These would incorrectly leave `current` as `None` after a failed attempt to remove an element (due to the cursor already being at the start/end). --- library/alloc/src/collections/btree/map.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index b585e2082f1..6e0b79b9640 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -3198,9 +3198,15 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMutKey<'a, K, V, A> { #[unstable(feature = "btree_cursors", issue = "107540")] pub fn remove_next(&mut self) -> Option<(K, V)> { let current = self.current.take()?; + if current.reborrow().next_kv().is_err() { + self.current = Some(current); + return None; + } let mut emptied_internal_root = false; let (kv, pos) = current .next_kv() + // This should be unwrap(), but that doesn't work because NodeRef + // doesn't implement Debug. The condition is checked above. .ok()? .remove_kv_tracking(|| emptied_internal_root = true, self.alloc.clone()); self.current = Some(pos); @@ -3221,9 +3227,15 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMutKey<'a, K, V, A> { #[unstable(feature = "btree_cursors", issue = "107540")] pub fn remove_prev(&mut self) -> Option<(K, V)> { let current = self.current.take()?; + if current.reborrow().next_back_kv().is_err() { + self.current = Some(current); + return None; + } let mut emptied_internal_root = false; let (kv, pos) = current .next_back_kv() + // This should be unwrap(), but that doesn't work because NodeRef + // doesn't implement Debug. The condition is checked above. .ok()? .remove_kv_tracking(|| emptied_internal_root = true, self.alloc.clone()); self.current = Some(pos);