From e0b64773d9f216368d67ba929301a8617f35e0d3 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 17 Nov 2025 15:53:18 +0200 Subject: [PATCH] Properly sanitize out inlay hints from remote hosts (#42878) Part of https://github.com/zed-industries/zed/issues/42671 Release Notes: - Fixed remote hosts causing duplicate hints to be displayed --- crates/collab/src/tests/editor_tests.rs | 32 +++++++++++++++++-------- crates/project/src/lsp_store.rs | 11 +++++++++ 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/crates/collab/src/tests/editor_tests.rs b/crates/collab/src/tests/editor_tests.rs index bdc024aaca7242ab0fe261e3b673bf4d0efe23b1..5880d998925743d4cdd822574b647b53194e2116 100644 --- a/crates/collab/src/tests/editor_tests.rs +++ b/crates/collab/src/tests/editor_tests.rs @@ -2169,16 +2169,28 @@ async fn test_inlay_hint_refresh_is_forwarded( } else { "initial hint" }; - Ok(Some(vec![lsp::InlayHint { - position: lsp::Position::new(0, character), - label: lsp::InlayHintLabel::String(label.to_string()), - kind: None, - text_edits: None, - tooltip: None, - padding_left: None, - padding_right: None, - data: None, - }])) + Ok(Some(vec![ + lsp::InlayHint { + position: lsp::Position::new(0, character), + label: lsp::InlayHintLabel::String(label.to_string()), + kind: None, + text_edits: None, + tooltip: None, + padding_left: None, + padding_right: None, + data: None, + }, + lsp::InlayHint { + position: lsp::Position::new(1090, 1090), + label: lsp::InlayHintLabel::String("out-of-bounds hint".to_string()), + kind: None, + text_edits: None, + tooltip: None, + padding_left: None, + padding_right: None, + data: None, + }, + ])) } }) .next() diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index cae4d64c67d3261f59d87273a38865992da18284..069c12c75c44e790028f27abdc12ffd6d2b613ab 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -6881,6 +6881,7 @@ impl LspStore { })) .await; + let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?; let mut has_errors = false; let inlay_hints = inlay_hints .into_iter() @@ -6892,6 +6893,16 @@ impl LspStore { None } }) + .map(|(server_id, mut new_hints)| { + new_hints.retain(|hint| { + hint.position.is_valid(&buffer_snapshot) + && range.start.is_valid(&buffer_snapshot) + && range.end.is_valid(&buffer_snapshot) + && hint.position.cmp(&range.start, &buffer_snapshot).is_ge() + && hint.position.cmp(&range.end, &buffer_snapshot).is_lt() + }); + (server_id, new_hints) + }) .collect::>(); anyhow::ensure!( !has_errors || !inlay_hints.is_empty(),