History

Fix more panics when removing excerpts (#28836)

Release Notes: - Fixed a panic when an excerpt removed has an edit suggestion inlay in it ---------

Kirill Bulatov committed 1 year ago

Commit 486a9e41 parent 0d8f77b5 files · +26 −8Browse files

Unified · Split

5 files
  1. crates/editor/src/display_map.rs +17 −2
  2. crates/editor/src/editor.rs +4 −1
  3. crates/editor/src/inlay_hint_cache.rs +3 −3
  4. crates/multi_buffer/src/anchor.rs +1 −1
  5. crates/multi_buffer/src/multi_buffer.rs +1 −1
crates/editor/src/display_map.rs+17−2
@@ -49,8 +49,8 @@ use language::{ · 48 unmodified lines
49};49};
50use lsp::DiagnosticSeverity;50use lsp::DiagnosticSeverity;
51use multi_buffer::{51use multi_buffer::{
52 Anchor, AnchorRangeExt, MultiBuffer, MultiBufferPoint, MultiBufferRow, MultiBufferSnapshot,52 Anchor, AnchorRangeExt, ExcerptId, MultiBuffer, MultiBufferPoint, MultiBufferRow,
53 RowInfo, ToOffset, ToPoint,53 MultiBufferSnapshot, RowInfo, ToOffset, ToPoint,
54};54};
55use serde::Deserialize;55use serde::Deserialize;
56use std::{56use std::{
@@ -574,6 +574,21 @@ impl DisplayMap { · 517 unmodified lines
574 self.block_map.read(snapshot, edits);574 self.block_map.read(snapshot, edits);
575 }575 }
576 576
577 pub fn remove_inlays_for_excerpts(&mut self, excerpts_removed: &[ExcerptId]) {
578 let to_remove = self
579 .inlay_map
580 .current_inlays()
581 .filter_map(|inlay| {
582 if excerpts_removed.contains(&inlay.position.excerpt_id) {
583 Some(inlay.id)
584 } else {
585 None
586 }
587 })
588 .collect::<Vec<_>>();
589 self.inlay_map.splice(&to_remove, Vec::new());
590 }
591
577 fn tab_size(buffer: &Entity<MultiBuffer>, cx: &App) -> NonZeroU32 {592 fn tab_size(buffer: &Entity<MultiBuffer>, cx: &App) -> NonZeroU32 {
578 let buffer = buffer.read(cx).as_singleton().map(|buffer| buffer.read(cx));593 let buffer = buffer.read(cx).as_singleton().map(|buffer| buffer.read(cx));
579 let language = buffer594 let language = buffer
crates/editor/src/editor.rs+4−1
@@ -4170,10 +4170,13 @@ impl Editor { · 4169 unmodified lines
4170 if let Some(InlaySplice {4170 if let Some(InlaySplice {
4171 to_remove,4171 to_remove,
4172 to_insert,4172 to_insert,
4173 }) = self.inlay_hint_cache.remove_excerpts(excerpts_removed)4173 }) = self.inlay_hint_cache.remove_excerpts(&excerpts_removed)
4174 {4174 {
4175 self.splice_inlays(&to_remove, to_insert, cx);4175 self.splice_inlays(&to_remove, to_insert, cx);
4176 }4176 }
4177 self.display_map.update(cx, |display_map, _| {
4178 display_map.remove_inlays_for_excerpts(&excerpts_removed)
4179 });
4177 return;4180 return;
4178 }4181 }
4179 InlayHintRefreshReason::NewLinesShown => (InvalidationStrategy::None, None),4182 InlayHintRefreshReason::NewLinesShown => (InvalidationStrategy::None, None),
crates/editor/src/inlay_hint_cache.rs+3−3
@@ -555,12 +555,12 @@ impl InlayHintCache { · 554 unmodified lines
555 /// Completely forget of certain excerpts that were removed from the multibuffer.555 /// Completely forget of certain excerpts that were removed from the multibuffer.
556 pub(super) fn remove_excerpts(556 pub(super) fn remove_excerpts(
557 &mut self,557 &mut self,
558 excerpts_removed: Vec<ExcerptId>,558 excerpts_removed: &[ExcerptId],
559 ) -> Option<InlaySplice> {559 ) -> Option<InlaySplice> {
560 let mut to_remove = Vec::new();560 let mut to_remove = Vec::new();
561 for excerpt_to_remove in excerpts_removed {561 for excerpt_to_remove in excerpts_removed {
562 self.update_tasks.remove(&excerpt_to_remove);562 self.update_tasks.remove(excerpt_to_remove);
563 if let Some(cached_hints) = self.hints.remove(&excerpt_to_remove) {563 if let Some(cached_hints) = self.hints.remove(excerpt_to_remove) {
564 let cached_hints = cached_hints.read();564 let cached_hints = cached_hints.read();
565 to_remove.extend(cached_hints.ordered_hints.iter().copied());565 to_remove.extend(cached_hints.ordered_hints.iter().copied());
566 }566 }
crates/multi_buffer/src/anchor.rs+1−1
@@ -71,7 +71,7 @@ impl Anchor { · 70 unmodified lines
71 if self_excerpt_id == ExcerptId::min() || self_excerpt_id == ExcerptId::max() {71 if self_excerpt_id == ExcerptId::min() || self_excerpt_id == ExcerptId::max() {
72 return Ordering::Equal;72 return Ordering::Equal;
73 }73 }
74 if let Some(excerpt) = snapshot.excerpt(self.excerpt_id) {74 if let Some(excerpt) = snapshot.excerpt(self_excerpt_id) {
75 let text_cmp = self.text_anchor.cmp(&other.text_anchor, &excerpt.buffer);75 let text_cmp = self.text_anchor.cmp(&other.text_anchor, &excerpt.buffer);
76 if text_cmp.is_ne() {76 if text_cmp.is_ne() {
77 return text_cmp;77 return text_cmp;
crates/multi_buffer/src/multi_buffer.rs+1−1
@@ -6041,7 +6041,7 @@ impl MultiBufferSnapshot { · 6040 unmodified lines
6041 return &entry.locator;6041 return &entry.locator;
6042 }6042 }
6043 }6043 }
6044 panic!("invalid excerpt id {:?}", id)6044 panic!("invalid excerpt id {id:?}")
6045 }6045 }
6046 }6046 }
6047 6047