From 4f0a44896a1aa2a66163d467d627ce14194f7122 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Thu, 23 Oct 2025 15:51:07 +0300 Subject: [PATCH] Fix anchor-related panic when gathering applicable inlay chunks (#41002) Before, inlay chunks were retrieved from the cache based on actualized anchor ranges, but using an old buffer snapshot. Now, update all chunks and snapshot to the actual before returning the applicable ones. Follow-up of https://github.com/zed-industries/zed/pull/40183 Release Notes: - N/A --- crates/editor/src/editor.rs | 15 +++++++-------- crates/editor/src/inlays/inlay_hints.rs | 6 +++++- crates/editor/src/proposed_changes_editor.rs | 6 +++--- crates/project/src/lsp_store.rs | 19 ++++++++----------- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index c13458e381..ba6f71822b 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -22603,9 +22603,9 @@ pub trait SemanticsProvider { fn applicable_inlay_chunks( &self, - buffer_id: BufferId, + buffer: &Entity, ranges: &[Range], - cx: &App, + cx: &mut App, ) -> Vec>; fn invalidate_inlay_hints(&self, for_buffers: &HashSet, cx: &mut App); @@ -23112,14 +23112,13 @@ impl SemanticsProvider for Entity { fn applicable_inlay_chunks( &self, - buffer_id: BufferId, + buffer: &Entity, ranges: &[Range], - cx: &App, + cx: &mut App, ) -> Vec> { - self.read(cx) - .lsp_store() - .read(cx) - .applicable_inlay_chunks(buffer_id, ranges) + self.read(cx).lsp_store().update(cx, |lsp_store, cx| { + lsp_store.applicable_inlay_chunks(buffer, ranges, cx) + }) } fn invalidate_inlay_hints(&self, for_buffers: &HashSet, cx: &mut App) { diff --git a/crates/editor/src/inlays/inlay_hints.rs b/crates/editor/src/inlays/inlay_hints.rs index 07faf84467..9a9be1d159 100644 --- a/crates/editor/src/inlays/inlay_hints.rs +++ b/crates/editor/src/inlays/inlay_hints.rs @@ -330,6 +330,7 @@ impl Editor { } }; + let multi_buffer = self.buffer().clone(); let Some(inlay_hints) = self.inlay_hints.as_mut() else { return; }; @@ -365,6 +366,9 @@ impl Editor { let all_affected_buffers = Arc::new(Mutex::new(all_affected_buffers)); for (buffer_id, visible_excerpts) in buffers_to_query { + let Some(buffer) = multi_buffer.read(cx).buffer(buffer_id) else { + continue; + }; let fetched_tasks = inlay_hints.hint_chunk_fetched.entry(buffer_id).or_default(); if visible_excerpts .buffer_version @@ -376,7 +380,7 @@ impl Editor { } let applicable_chunks = - semantics_provider.applicable_inlay_chunks(buffer_id, &visible_excerpts.ranges, cx); + semantics_provider.applicable_inlay_chunks(&buffer, &visible_excerpts.ranges, cx); match inlay_hints .hint_refresh_tasks diff --git a/crates/editor/src/proposed_changes_editor.rs b/crates/editor/src/proposed_changes_editor.rs index a8a03d3e5b..9f5a17bfcc 100644 --- a/crates/editor/src/proposed_changes_editor.rs +++ b/crates/editor/src/proposed_changes_editor.rs @@ -436,11 +436,11 @@ impl SemanticsProvider for BranchBufferSemanticsProvider { fn applicable_inlay_chunks( &self, - buffer_id: BufferId, + buffer: &Entity, ranges: &[Range], - cx: &App, + cx: &mut App, ) -> Vec> { - self.0.applicable_inlay_chunks(buffer_id, ranges, cx) + self.0.applicable_inlay_chunks(buffer, ranges, cx) } fn invalidate_inlay_hints(&self, for_buffers: &HashSet, cx: &mut App) { diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index f33d7af8b6..2350c110ee 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -6499,19 +6499,16 @@ impl LspStore { } pub fn applicable_inlay_chunks( - &self, - buffer_id: BufferId, + &mut self, + buffer: &Entity, ranges: &[Range], + cx: &mut Context, ) -> Vec> { - self.lsp_data - .get(&buffer_id) - .map(|data| { - data.inlay_hints - .applicable_chunks(ranges) - .map(|chunk| chunk.start..chunk.end) - .collect() - }) - .unwrap_or_default() + self.latest_lsp_data(buffer, cx) + .inlay_hints + .applicable_chunks(ranges) + .map(|chunk| chunk.start..chunk.end) + .collect() } pub fn invalidate_inlay_hints<'a>(