sum_tree: Implement `Iterator::last` and lower bound of `Iterator::size_hint` (#49448)

Lukas Wirth created

Release Notes:

- N/A *or* Added/Fixed/Improved ...

Change summary

crates/sum_tree/src/cursor.rs | 17 +++++++++++++++--
crates/vim/src/state.rs       |  4 +---
2 files changed, 16 insertions(+), 5 deletions(-)

Detailed changes

crates/sum_tree/src/cursor.rs 🔗

@@ -586,9 +586,8 @@ impl<'a, T: Item> Iterator for Iter<'a, T> {
             descend = true;
         }
 
-        while !self.stack.is_empty() {
+        while let Some(entry) = self.stack.last_mut() {
             let new_subtree = {
-                let entry = self.stack.last_mut().unwrap();
                 match entry.tree.0.as_ref() {
                     Node::Internal { child_trees, .. } => {
                         if !descend {
@@ -625,6 +624,20 @@ impl<'a, T: Item> Iterator for Iter<'a, T> {
 
         None
     }
+
+    fn last(mut self) -> Option<Self::Item> {
+        self.stack.clear();
+        self.tree.rightmost_leaf().last()
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let lower_bound = match self.stack.last() {
+            Some(top) => top.tree.0.child_summaries().len() - top.index as usize,
+            None => self.tree.0.child_summaries().len(),
+        };
+
+        (lower_bound, None)
+    }
 }
 
 impl<'a, 'b, T: Item, D> Iterator for Cursor<'a, 'b, T, D>

crates/vim/src/state.rs 🔗

@@ -612,9 +612,7 @@ impl MarksState {
                 return Some(Mark::Local(anchors.get(name)?.clone()));
             }
 
-            let singleton = multi_buffer.read(cx).as_singleton()?;
-            let excerpt_id = *multi_buffer.read(cx).excerpt_ids().first()?;
-            let buffer_id = singleton.read(cx).remote_id();
+            let (excerpt_id, buffer_id, _) = multi_buffer.read(cx).read(cx).as_singleton()?;
             if let Some(anchors) = self.buffer_marks.get(&buffer_id) {
                 let text_anchors = anchors.get(name)?;
                 let anchors = text_anchors