Release Notes: - Fixed a panic when an excerpt removed has an edit suggestion inlay in it ---------
Unified · Split
| @@ -49,8 +49,8 @@ use language::{ · 48 unmodified lines | |||
| 49 | }; | 49 | }; |
| 50 | use lsp::DiagnosticSeverity; | 50 | use lsp::DiagnosticSeverity; |
| 51 | use multi_buffer::{ | 51 | use 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 | }; |
| 55 | use serde::Deserialize; | 55 | use serde::Deserialize; |
| 56 | use std::{ | 56 | use 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 = buffer | 594 | let language = buffer |
| @@ -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), |
| @@ -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 | } |
| @@ -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; |
| @@ -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 | ||