multi_buffer: Work around another panic bug in path_key (#42920)

Lukas Wirth created

Fixes ZED-346 for now until I find the time to dig into this bug
properly

Release Notes:

- Fixed a panic in the diagnostics pane

Change summary

crates/diagnostics/src/diagnostics.rs | 6 ++++--
crates/multi_buffer/src/path_key.rs   | 8 +++++---
2 files changed, 9 insertions(+), 5 deletions(-)

Detailed changes

crates/diagnostics/src/diagnostics.rs 🔗

@@ -491,7 +491,7 @@ impl ProjectDiagnosticsEditor {
         cx: &mut Context<Self>,
     ) -> Task<Result<()>> {
         let was_empty = self.multibuffer.read(cx).is_empty();
-        let mut buffer_snapshot = buffer.read(cx).snapshot();
+        let buffer_snapshot = buffer.read(cx).snapshot();
         let buffer_id = buffer_snapshot.remote_id();
 
         let max_severity = if self.include_warnings {
@@ -602,7 +602,6 @@ impl ProjectDiagnosticsEditor {
                     cx,
                 )
                 .await;
-                buffer_snapshot = cx.update(|_, cx| buffer.read(cx).snapshot())?;
                 let initial_range = buffer_snapshot.anchor_after(b.initial_range.start)
                     ..buffer_snapshot.anchor_before(b.initial_range.end);
                 let excerpt_range = ExcerptRange {
@@ -1010,11 +1009,14 @@ async fn heuristic_syntactic_expand(
     snapshot: BufferSnapshot,
     cx: &mut AsyncApp,
 ) -> Option<RangeInclusive<BufferRow>> {
+    let start = snapshot.clip_point(input_range.start, Bias::Right);
+    let end = snapshot.clip_point(input_range.end, Bias::Left);
     let input_row_count = input_range.end.row - input_range.start.row;
     if input_row_count > max_row_count {
         return None;
     }
 
+    let input_range = start..end;
     // If the outline node contains the diagnostic and is small enough, just use that.
     let outline_range = snapshot.outline_range_containing(input_range.clone());
     if let Some(outline_range) = outline_range.clone() {

crates/multi_buffer/src/path_key.rs 🔗

@@ -288,7 +288,6 @@ impl MultiBuffer {
             .get(&path)
             .cloned()
             .unwrap_or_default();
-

         let mut new_iter = new.into_iter().peekable();
         let mut existing_iter = existing.into_iter().peekable();
 
@@ -413,14 +412,17 @@ impl MultiBuffer {
         // todo(lw): There is a logic bug somewhere that causes the to_remove vector to be not ordered correctly
         to_remove.sort_by_cached_key(|&id| snapshot.excerpt_locator_for_id(id));
         self.remove_excerpts(to_remove, cx);
+

         if excerpt_ids.is_empty() {
             self.excerpts_by_path.remove(&path);
         } else {
             for excerpt_id in &excerpt_ids {
                 self.paths_by_excerpt.insert(*excerpt_id, path.clone());
             }
-            self.excerpts_by_path

-                .insert(path, excerpt_ids.iter().dedup().cloned().collect());

+            let snapshot = &*self.snapshot.get_mut();

+            let mut excerpt_ids: Vec<_> = excerpt_ids.iter().dedup().cloned().collect();

+            excerpt_ids.sort_by_cached_key(|&id| snapshot.excerpt_locator_for_id(id));

+            self.excerpts_by_path.insert(path, excerpt_ids);

         }
 
         (excerpt_ids, added_a_new_excerpt)