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 c13458e3816448057030391b0673a8f731803aa8..ba6f71822b3cf6adb748f8dab12f503b7c1ca850 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 07faf8446749085ed24795451c241c0a5747335f..9a9be1d1591e5b9f5303a0706ce0ded5afba3f83 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 a8a03d3e5b3f7f72d58f3a12d7b265832f1b2e10..9f5a17bfccfbc88bf4e00fa8d30030958dfe7e6c 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 f33d7af8b6ede6f1ae62109f1390acee51975693..2350c110eee4c8e3f2e838f04ee9fc04292209da 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>(