Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #16822 - Veykril:inlays, r=Veykril
fix: Make inlay hint resolving work better for inlays targetting the same position
bors 2024-03-18
parent f6e2895 · parent 4a93368 · commit f40c7d8
-rw-r--r--crates/ide/src/inlay_hints.rs96
-rw-r--r--crates/ide/src/inlay_hints/adjustment.rs1
-rw-r--r--crates/ide/src/inlay_hints/bind_pat.rs9
-rw-r--r--crates/ide/src/inlay_hints/binding_mode.rs2
-rw-r--r--crates/ide/src/inlay_hints/chaining.rs1
-rw-r--r--crates/ide/src/inlay_hints/closing_brace.rs1
-rw-r--r--crates/ide/src/inlay_hints/closure_captures.rs5
-rw-r--r--crates/ide/src/inlay_hints/closure_ret.rs1
-rw-r--r--crates/ide/src/inlay_hints/discriminant.rs1
-rw-r--r--crates/ide/src/inlay_hints/fn_lifetime_fn.rs3
-rw-r--r--crates/ide/src/inlay_hints/implicit_drop.rs1
-rw-r--r--crates/ide/src/inlay_hints/implicit_static.rs1
-rw-r--r--crates/ide/src/inlay_hints/param_name.rs1
-rw-r--r--crates/ide/src/inlay_hints/range_exclusive.rs1
-rw-r--r--crates/ide/src/lib.rs13
-rw-r--r--crates/rust-analyzer/src/handlers/request.rs11
-rw-r--r--crates/rust-analyzer/src/lsp/ext.rs1
-rw-r--r--crates/rust-analyzer/src/lsp/to_proto.rs48
-rw-r--r--docs/dev/lsp-extensions.md8
19 files changed, 114 insertions, 91 deletions
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 8311e770b4..dda38ce77e 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -1,5 +1,6 @@
use std::{
fmt::{self, Write},
+ hash::{BuildHasher, BuildHasherDefault},
mem::take,
};
@@ -8,7 +9,7 @@ use hir::{
known, ClosureStyle, HasVisibility, HirDisplay, HirDisplayError, HirWrite, ModuleDef,
ModuleDefId, Semantics,
};
-use ide_db::{base_db::FileRange, famous_defs::FamousDefs, RootDatabase};
+use ide_db::{base_db::FileRange, famous_defs::FamousDefs, FxHasher, RootDatabase};
use itertools::Itertools;
use smallvec::{smallvec, SmallVec};
use stdx::never;
@@ -116,7 +117,7 @@ pub enum AdjustmentHintsMode {
PreferPostfix,
}
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum InlayKind {
Adjustment,
BindingMode,
@@ -132,7 +133,7 @@ pub enum InlayKind {
RangeExclusive,
}
-#[derive(Debug)]
+#[derive(Debug, Hash)]
pub enum InlayHintPosition {
Before,
After,
@@ -151,13 +152,23 @@ pub struct InlayHint {
pub label: InlayHintLabel,
/// Text edit to apply when "accepting" this inlay hint.
pub text_edit: Option<TextEdit>,
- pub needs_resolve: bool,
+}
+
+impl std::hash::Hash for InlayHint {
+ fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ self.range.hash(state);
+ self.position.hash(state);
+ self.pad_left.hash(state);
+ self.pad_right.hash(state);
+ self.kind.hash(state);
+ self.label.hash(state);
+ self.text_edit.is_some().hash(state);
+ }
}
impl InlayHint {
fn closing_paren_after(kind: InlayKind, range: TextRange) -> InlayHint {
InlayHint {
- needs_resolve: false,
range,
kind,
label: InlayHintLabel::from(")"),
@@ -167,9 +178,9 @@ impl InlayHint {
pad_right: false,
}
}
+
fn opening_paren_before(kind: InlayKind, range: TextRange) -> InlayHint {
InlayHint {
- needs_resolve: false,
range,
kind,
label: InlayHintLabel::from("("),
@@ -179,15 +190,19 @@ impl InlayHint {
pad_right: false,
}
}
+
+ pub fn needs_resolve(&self) -> bool {
+ self.text_edit.is_some() || self.label.needs_resolve()
+ }
}
-#[derive(Debug)]
+#[derive(Debug, Hash)]
pub enum InlayTooltip {
String(String),
Markdown(String),
}
-#[derive(Default)]
+#[derive(Default, Hash)]
pub struct InlayHintLabel {
pub parts: SmallVec<[InlayHintLabelPart; 1]>,
}
@@ -265,6 +280,7 @@ impl fmt::Debug for InlayHintLabel {
}
}
+#[derive(Hash)]
pub struct InlayHintLabelPart {
pub text: String,
/// Source location represented by this label part. The client will use this to fetch the part's
@@ -313,9 +329,7 @@ impl fmt::Write for InlayHintLabelBuilder<'_> {
impl HirWrite for InlayHintLabelBuilder<'_> {
fn start_location_link(&mut self, def: ModuleDefId) {
- if self.location.is_some() {
- never!("location link is already started");
- }
+ never!(self.location.is_some(), "location link is already started");
self.make_new_part();
let Some(location) = ModuleDef::from(def).try_to_nav(self.db) else { return };
let location = location.call_site();
@@ -425,11 +439,6 @@ fn ty_to_text_edit(
Some(builder.finish())
}
-pub enum RangeLimit {
- Fixed(TextRange),
- NearestParent(TextSize),
-}
-
// Feature: Inlay Hints
//
// rust-analyzer shows additional information inline with the source code.
@@ -451,7 +460,7 @@ pub enum RangeLimit {
pub(crate) fn inlay_hints(
db: &RootDatabase,
file_id: FileId,
- range_limit: Option<RangeLimit>,
+ range_limit: Option<TextRange>,
config: &InlayHintsConfig,
) -> Vec<InlayHint> {
let _p = tracing::span!(tracing::Level::INFO, "inlay_hints").entered();
@@ -466,31 +475,13 @@ pub(crate) fn inlay_hints(
let hints = |node| hints(&mut acc, &famous_defs, config, file_id, node);
match range_limit {
- Some(RangeLimit::Fixed(range)) => match file.covering_element(range) {
+ Some(range) => match file.covering_element(range) {
NodeOrToken::Token(_) => return acc,
NodeOrToken::Node(n) => n
.descendants()
.filter(|descendant| range.intersect(descendant.text_range()).is_some())
.for_each(hints),
},
- Some(RangeLimit::NearestParent(position)) => {
- match file.token_at_offset(position).left_biased() {
- Some(token) => {
- if let Some(parent_block) =
- token.parent_ancestors().find_map(ast::BlockExpr::cast)
- {
- parent_block.syntax().descendants().for_each(hints)
- } else if let Some(parent_item) =
- token.parent_ancestors().find_map(ast::Item::cast)
- {
- parent_item.syntax().descendants().for_each(hints)
- } else {
- return acc;
- }
- }
- None => return acc,
- }
- }
None => file.descendants().for_each(hints),
};
}
@@ -498,6 +489,39 @@ pub(crate) fn inlay_hints(
acc
}
+pub(crate) fn inlay_hints_resolve(
+ db: &RootDatabase,
+ file_id: FileId,
+ position: TextSize,
+ hash: u64,
+ config: &InlayHintsConfig,
+) -> Option<InlayHint> {
+ let _p = tracing::span!(tracing::Level::INFO, "inlay_hints").entered();
+ let sema = Semantics::new(db);
+ let file = sema.parse(file_id);
+ let file = file.syntax();
+
+ let scope = sema.scope(file)?;
+ let famous_defs = FamousDefs(&sema, scope.krate());
+ let mut acc = Vec::new();
+
+ let hints = |node| hints(&mut acc, &famous_defs, config, file_id, node);
+ match file.token_at_offset(position).left_biased() {
+ Some(token) => {
+ if let Some(parent_block) = token.parent_ancestors().find_map(ast::BlockExpr::cast) {
+ parent_block.syntax().descendants().for_each(hints)
+ } else if let Some(parent_item) = token.parent_ancestors().find_map(ast::Item::cast) {
+ parent_item.syntax().descendants().for_each(hints)
+ } else {
+ return None;
+ }
+ }
+ None => return None,
+ }
+
+ acc.into_iter().find(|hint| BuildHasherDefault::<FxHasher>::default().hash_one(hint) == hash)
+}
+
fn hints(
hints: &mut Vec<InlayHint>,
famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>,
diff --git a/crates/ide/src/inlay_hints/adjustment.rs b/crates/ide/src/inlay_hints/adjustment.rs
index 631807d99a..20128a286f 100644
--- a/crates/ide/src/inlay_hints/adjustment.rs
+++ b/crates/ide/src/inlay_hints/adjustment.rs
@@ -147,7 +147,6 @@ pub(super) fn hints(
None,
);
acc.push(InlayHint {
- needs_resolve: label.needs_resolve(),
range: expr.syntax().text_range(),
pad_left: false,
pad_right: false,
diff --git a/crates/ide/src/inlay_hints/bind_pat.rs b/crates/ide/src/inlay_hints/bind_pat.rs
index 45b51e3557..07b9f9cc1f 100644
--- a/crates/ide/src/inlay_hints/bind_pat.rs
+++ b/crates/ide/src/inlay_hints/bind_pat.rs
@@ -99,7 +99,6 @@ pub(super) fn hints(
None => pat.syntax().text_range(),
};
acc.push(InlayHint {
- needs_resolve: label.needs_resolve() || text_edit.is_some(),
range: match type_ascriptable {
Some(Some(t)) => text_range.cover(t.text_range()),
_ => text_range,
@@ -177,11 +176,7 @@ mod tests {
use syntax::{TextRange, TextSize};
use test_utils::extract_annotations;
- use crate::{
- fixture,
- inlay_hints::{InlayHintsConfig, RangeLimit},
- ClosureReturnTypeHints,
- };
+ use crate::{fixture, inlay_hints::InlayHintsConfig, ClosureReturnTypeHints};
use crate::inlay_hints::tests::{
check, check_edit, check_no_edit, check_with_config, DISABLED_CONFIG, TEST_CONFIG,
@@ -404,7 +399,7 @@ fn main() {
.inlay_hints(
&InlayHintsConfig { type_hints: true, ..DISABLED_CONFIG },
file_id,
- Some(RangeLimit::Fixed(TextRange::new(TextSize::from(500), TextSize::from(600)))),
+ Some(TextRange::new(TextSize::from(500), TextSize::from(600))),
)
.unwrap();
let actual =
diff --git a/crates/ide/src/inlay_hints/binding_mode.rs b/crates/ide/src/inlay_hints/binding_mode.rs
index 35504ffa78..f27390ee89 100644
--- a/crates/ide/src/inlay_hints/binding_mode.rs
+++ b/crates/ide/src/inlay_hints/binding_mode.rs
@@ -50,7 +50,6 @@ pub(super) fn hints(
_ => return,
};
acc.push(InlayHint {
- needs_resolve: false,
range,
kind: InlayKind::BindingMode,
label: r.into(),
@@ -69,7 +68,6 @@ pub(super) fn hints(
hir::BindingMode::Ref(Mutability::Shared) => "ref",
};
acc.push(InlayHint {
- needs_resolve: false,
range: pat.syntax().text_range(),
kind: InlayKind::BindingMode,
label: bm.into(),
diff --git a/crates/ide/src/inlay_hints/chaining.rs b/crates/ide/src/inlay_hints/chaining.rs
index b6063978e9..d86487d4b4 100644
--- a/crates/ide/src/inlay_hints/chaining.rs
+++ b/crates/ide/src/inlay_hints/chaining.rs
@@ -59,7 +59,6 @@ pub(super) fn hints(
}
let label = label_of_ty(famous_defs, config, &ty)?;
acc.push(InlayHint {
- needs_resolve: label.needs_resolve(),
range: expr.syntax().text_range(),
kind: InlayKind::Chaining,
label,
diff --git a/crates/ide/src/inlay_hints/closing_brace.rs b/crates/ide/src/inlay_hints/closing_brace.rs
index 2b68538c19..2cefd5acdc 100644
--- a/crates/ide/src/inlay_hints/closing_brace.rs
+++ b/crates/ide/src/inlay_hints/closing_brace.rs
@@ -109,7 +109,6 @@ pub(super) fn hints(
let linked_location = name_range.map(|range| FileRange { file_id, range });
acc.push(InlayHint {
- needs_resolve: linked_location.is_some(),
range: closing_token.text_range(),
kind: InlayKind::ClosingBrace,
label: InlayHintLabel::simple(label, None, linked_location),
diff --git a/crates/ide/src/inlay_hints/closure_captures.rs b/crates/ide/src/inlay_hints/closure_captures.rs
index 2f8b959516..f1b524e088 100644
--- a/crates/ide/src/inlay_hints/closure_captures.rs
+++ b/crates/ide/src/inlay_hints/closure_captures.rs
@@ -32,7 +32,6 @@ pub(super) fn hints(
let range = closure.syntax().first_token()?.prev_token()?.text_range();
let range = TextRange::new(range.end() - TextSize::from(1), range.end());
acc.push(InlayHint {
- needs_resolve: false,
range,
kind: InlayKind::ClosureCapture,
label: InlayHintLabel::from("move"),
@@ -45,7 +44,6 @@ pub(super) fn hints(
}
};
acc.push(InlayHint {
- needs_resolve: false,
range: move_kw_range,
kind: InlayKind::ClosureCapture,
label: InlayHintLabel::from("("),
@@ -79,7 +77,6 @@ pub(super) fn hints(
}),
);
acc.push(InlayHint {
- needs_resolve: label.needs_resolve(),
range: move_kw_range,
kind: InlayKind::ClosureCapture,
label,
@@ -91,7 +88,6 @@ pub(super) fn hints(
if idx != last {
acc.push(InlayHint {
- needs_resolve: false,
range: move_kw_range,
kind: InlayKind::ClosureCapture,
label: InlayHintLabel::from(", "),
@@ -103,7 +99,6 @@ pub(super) fn hints(
}
}
acc.push(InlayHint {
- needs_resolve: false,
range: move_kw_range,
kind: InlayKind::ClosureCapture,
label: InlayHintLabel::from(")"),
diff --git a/crates/ide/src/inlay_hints/closure_ret.rs b/crates/ide/src/inlay_hints/closure_ret.rs
index 204967cd7c..3b41db0f13 100644
--- a/crates/ide/src/inlay_hints/closure_ret.rs
+++ b/crates/ide/src/inlay_hints/closure_ret.rs
@@ -64,7 +64,6 @@ pub(super) fn hints(
};
acc.push(InlayHint {
- needs_resolve: label.needs_resolve() || text_edit.is_some(),
range: param_list.syntax().text_range(),
kind: InlayKind::Type,
label,
diff --git a/crates/ide/src/inlay_hints/discriminant.rs b/crates/ide/src/inlay_hints/discriminant.rs
index 06cce147d2..202954100f 100644
--- a/crates/ide/src/inlay_hints/discriminant.rs
+++ b/crates/ide/src/inlay_hints/discriminant.rs
@@ -79,7 +79,6 @@ fn variant_hints(
None,
);
acc.push(InlayHint {
- needs_resolve: label.needs_resolve(),
range: match eq_token {
Some(t) => range.cover(t.text_range()),
_ => range,
diff --git a/crates/ide/src/inlay_hints/fn_lifetime_fn.rs b/crates/ide/src/inlay_hints/fn_lifetime_fn.rs
index 6e5f23bed0..d3666754e2 100644
--- a/crates/ide/src/inlay_hints/fn_lifetime_fn.rs
+++ b/crates/ide/src/inlay_hints/fn_lifetime_fn.rs
@@ -22,7 +22,6 @@ pub(super) fn hints(
}
let mk_lt_hint = |t: SyntaxToken, label: String| InlayHint {
- needs_resolve: false,
range: t.text_range(),
kind: InlayKind::Lifetime,
label: label.into(),
@@ -184,7 +183,6 @@ pub(super) fn hints(
let angle_tok = gpl.l_angle_token()?;
let is_empty = gpl.generic_params().next().is_none();
acc.push(InlayHint {
- needs_resolve: false,
range: angle_tok.text_range(),
kind: InlayKind::Lifetime,
label: format!(
@@ -200,7 +198,6 @@ pub(super) fn hints(
});
}
(None, allocated_lifetimes) => acc.push(InlayHint {
- needs_resolve: false,
range: func.name()?.syntax().text_range(),
kind: InlayKind::GenericParamList,
label: format!("<{}>", allocated_lifetimes.iter().format(", "),).into(),
diff --git a/crates/ide/src/inlay_hints/implicit_drop.rs b/crates/ide/src/inlay_hints/implicit_drop.rs
index 5ba4e514e1..31f0c79037 100644
--- a/crates/ide/src/inlay_hints/implicit_drop.rs
+++ b/crates/ide/src/inlay_hints/implicit_drop.rs
@@ -105,7 +105,6 @@ pub(super) fn hints(
pad_left: true,
pad_right: true,
kind: InlayKind::Drop,
- needs_resolve: label.needs_resolve(),
label,
text_edit: None,
})
diff --git a/crates/ide/src/inlay_hints/implicit_static.rs b/crates/ide/src/inlay_hints/implicit_static.rs
index f18e6421cb..42223ddf58 100644
--- a/crates/ide/src/inlay_hints/implicit_static.rs
+++ b/crates/ide/src/inlay_hints/implicit_static.rs
@@ -31,7 +31,6 @@ pub(super) fn hints(
if ty.lifetime().is_none() {
let t = ty.amp_token()?;
acc.push(InlayHint {
- needs_resolve: false,
range: t.text_range(),
kind: InlayKind::Lifetime,
label: "'static".into(),
diff --git a/crates/ide/src/inlay_hints/param_name.rs b/crates/ide/src/inlay_hints/param_name.rs
index 418fc002a8..96e845b2f3 100644
--- a/crates/ide/src/inlay_hints/param_name.rs
+++ b/crates/ide/src/inlay_hints/param_name.rs
@@ -57,7 +57,6 @@ pub(super) fn hints(
let label =
InlayHintLabel::simple(format!("{param_name}{colon}"), None, linked_location);
InlayHint {
- needs_resolve: label.needs_resolve(),
range,
kind: InlayKind::Parameter,
label,
diff --git a/crates/ide/src/inlay_hints/range_exclusive.rs b/crates/ide/src/inlay_hints/range_exclusive.rs
index c4b0c199fc..bfb9283885 100644
--- a/crates/ide/src/inlay_hints/range_exclusive.rs
+++ b/crates/ide/src/inlay_hints/range_exclusive.rs
@@ -30,7 +30,6 @@ fn inlay_hint(token: SyntaxToken) -> InlayHint {
kind: crate::InlayKind::RangeExclusive,
label: crate::InlayHintLabel::from("<"),
text_edit: None,
- needs_resolve: false,
}
}
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index 6955e14a10..1c57f4f8f6 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -90,7 +90,7 @@ pub use crate::{
inlay_hints::{
AdjustmentHints, AdjustmentHintsMode, ClosureReturnTypeHints, DiscriminantHints,
InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart, InlayHintPosition,
- InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints, RangeLimit,
+ InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints,
},
join_lines::JoinLinesConfig,
markup::Markup,
@@ -415,10 +415,19 @@ impl Analysis {
&self,
config: &InlayHintsConfig,
file_id: FileId,
- range: Option<RangeLimit>,
+ range: Option<TextRange>,
) -> Cancellable<Vec<InlayHint>> {
self.with_db(|db| inlay_hints::inlay_hints(db, file_id, range, config))
}
+ pub fn inlay_hints_resolve(
+ &self,
+ config: &InlayHintsConfig,
+ file_id: FileId,
+ position: TextSize,
+ hash: u64,
+ ) -> Cancellable<Option<InlayHint>> {
+ self.with_db(|db| inlay_hints::inlay_hints_resolve(db, file_id, position, hash, config))
+ }
/// Returns the set of folding ranges.
pub fn folding_ranges(&self, file_id: FileId) -> Cancellable<Vec<Fold>> {
diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs
index 1d98457add..9d6eda3e5e 100644
--- a/crates/rust-analyzer/src/handlers/request.rs
+++ b/crates/rust-analyzer/src/handlers/request.rs
@@ -12,8 +12,8 @@ use anyhow::Context;
use ide::{
AnnotationConfig, AssistKind, AssistResolveStrategy, Cancellable, FilePosition, FileRange,
- HoverAction, HoverGotoTypeData, InlayFieldsToResolve, Query, RangeInfo, RangeLimit,
- ReferenceCategory, Runnable, RunnableKind, SingleResolve, SourceChange, TextEdit,
+ HoverAction, HoverGotoTypeData, InlayFieldsToResolve, Query, RangeInfo, ReferenceCategory,
+ Runnable, RunnableKind, SingleResolve, SourceChange, TextEdit,
};
use ide_db::SymbolKind;
use itertools::Itertools;
@@ -1465,7 +1465,7 @@ pub(crate) fn handle_inlay_hints(
let inlay_hints_config = snap.config.inlay_hints();
Ok(Some(
snap.analysis
- .inlay_hints(&inlay_hints_config, file_id, Some(RangeLimit::Fixed(range)))?
+ .inlay_hints(&inlay_hints_config, file_id, Some(range))?
.into_iter()
.map(|it| {
to_proto::inlay_hint(
@@ -1499,10 +1499,11 @@ pub(crate) fn handle_inlay_hints_resolve(
let hint_position = from_proto::offset(&line_index, original_hint.position)?;
let mut forced_resolve_inlay_hints_config = snap.config.inlay_hints();
forced_resolve_inlay_hints_config.fields_to_resolve = InlayFieldsToResolve::empty();
- let resolve_hints = snap.analysis.inlay_hints(
+ let resolve_hints = snap.analysis.inlay_hints_resolve(
&forced_resolve_inlay_hints_config,
file_id,
- Some(RangeLimit::NearestParent(hint_position)),
+ hint_position,
+ resolve_data.hash,
)?;
let mut resolved_hints = resolve_hints
diff --git a/crates/rust-analyzer/src/lsp/ext.rs b/crates/rust-analyzer/src/lsp/ext.rs
index 710ce7f8ac..5d3d75efcb 100644
--- a/crates/rust-analyzer/src/lsp/ext.rs
+++ b/crates/rust-analyzer/src/lsp/ext.rs
@@ -800,6 +800,7 @@ pub struct CompletionResolveData {
#[derive(Debug, Serialize, Deserialize)]
pub struct InlayHintResolveData {
pub file_id: u32,
+ pub hash: u64,
}
#[derive(Debug, Serialize, Deserialize)]
diff --git a/crates/rust-analyzer/src/lsp/to_proto.rs b/crates/rust-analyzer/src/lsp/to_proto.rs
index e77d0c13bf..dcff0ea747 100644
--- a/crates/rust-analyzer/src/lsp/to_proto.rs
+++ b/crates/rust-analyzer/src/lsp/to_proto.rs
@@ -13,7 +13,7 @@ use ide::{
NavigationTarget, ReferenceCategory, RenameError, Runnable, Severity, SignatureHelp,
SnippetEdit, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize,
};
-use ide_db::rust_doc::format_docs;
+use ide_db::{rust_doc::format_docs, FxHasher};
use itertools::Itertools;
use semver::VersionReq;
use serde_json::to_value;
@@ -444,30 +444,42 @@ pub(crate) fn inlay_hint(
fields_to_resolve: &InlayFieldsToResolve,
line_index: &LineIndex,
file_id: FileId,
- inlay_hint: InlayHint,
+ mut inlay_hint: InlayHint,
) -> Cancellable<lsp_types::InlayHint> {
- let needs_resolve = inlay_hint.needs_resolve;
- let (label, tooltip, mut something_to_resolve) =
- inlay_hint_label(snap, fields_to_resolve, needs_resolve, inlay_hint.label)?;
+ let resolve_hash = inlay_hint.needs_resolve().then(|| {
+ std::hash::BuildHasher::hash_one(
+ &std::hash::BuildHasherDefault::<FxHasher>::default(),
+ &inlay_hint,
+ )
+ });
+ let mut something_to_resolve = false;
let text_edits = if snap
.config
.visual_studio_code_version()
// https://github.com/microsoft/vscode/issues/193124
.map_or(true, |version| VersionReq::parse(">=1.86.0").unwrap().matches(version))
- && needs_resolve
+ && resolve_hash.is_some()
&& fields_to_resolve.resolve_text_edits
{
something_to_resolve |= inlay_hint.text_edit.is_some();
None
} else {
- inlay_hint.text_edit.map(|it| text_edit_vec(line_index, it))
+ inlay_hint.text_edit.take().map(|it| text_edit_vec(line_index, it))
};
-
- let data = if needs_resolve && something_to_resolve {
- Some(to_value(lsp_ext::InlayHintResolveData { file_id: file_id.index() }).unwrap())
- } else {
- None
+ let (label, tooltip) = inlay_hint_label(
+ snap,
+ fields_to_resolve,
+ &mut something_to_resolve,
+ resolve_hash.is_some(),
+ inlay_hint.label,
+ )?;
+
+ let data = match resolve_hash {
+ Some(hash) if something_to_resolve => Some(
+ to_value(lsp_ext::InlayHintResolveData { file_id: file_id.index(), hash }).unwrap(),
+ ),
+ _ => None,
};
Ok(lsp_types::InlayHint {
@@ -492,15 +504,15 @@ pub(crate) fn inlay_hint(
fn inlay_hint_label(
snap: &GlobalStateSnapshot,
fields_to_resolve: &InlayFieldsToResolve,
+ something_to_resolve: &mut bool,
needs_resolve: bool,
mut label: InlayHintLabel,
-) -> Cancellable<(lsp_types::InlayHintLabel, Option<lsp_types::InlayHintTooltip>, bool)> {
- let mut something_to_resolve = false;
+) -> Cancellable<(lsp_types::InlayHintLabel, Option<lsp_types::InlayHintTooltip>)> {
let (label, tooltip) = match &*label.parts {
[InlayHintLabelPart { linked_location: None, .. }] => {
let InlayHintLabelPart { text, tooltip, .. } = label.parts.pop().unwrap();
let hint_tooltip = if needs_resolve && fields_to_resolve.resolve_hint_tooltip {
- something_to_resolve |= tooltip.is_some();
+ *something_to_resolve |= tooltip.is_some();
None
} else {
match tooltip {
@@ -524,7 +536,7 @@ fn inlay_hint_label(
.into_iter()
.map(|part| {
let tooltip = if needs_resolve && fields_to_resolve.resolve_label_tooltip {
- something_to_resolve |= part.tooltip.is_some();
+ *something_to_resolve |= part.tooltip.is_some();
None
} else {
match part.tooltip {
@@ -543,7 +555,7 @@ fn inlay_hint_label(
}
};
let location = if needs_resolve && fields_to_resolve.resolve_label_location {
- something_to_resolve |= part.linked_location.is_some();
+ *something_to_resolve |= part.linked_location.is_some();
None
} else {
part.linked_location.map(|range| location(snap, range)).transpose()?
@@ -559,7 +571,7 @@ fn inlay_hint_label(
(lsp_types::InlayHintLabel::LabelParts(parts), None)
}
};
- Ok((label, tooltip, something_to_resolve))
+ Ok((label, tooltip))
}
static TOKEN_RESULT_COUNTER: AtomicU32 = AtomicU32::new(1);
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md
index cf9ad5fe04..8db66687aa 100644
--- a/docs/dev/lsp-extensions.md
+++ b/docs/dev/lsp-extensions.md
@@ -1,5 +1,5 @@
<!---
-lsp/ext.rs hash: 61f485497d6e8e88
+lsp/ext.rs hash: d5febcbf63650753
If you need to change the above hash to make the test pass, please check if you
need to adjust this doc as well and ping this issue:
@@ -417,7 +417,7 @@ interface TestItem {
// A human readable name for this test
label: string;
// The kind of this test item. Based on the kind,
- // an icon is chosen by the editor.
+ // an icon is chosen by the editor.
kind: "package" | "module" | "test";
// True if this test may have children not available eagerly
canResolveChildren: boolean;
@@ -492,9 +492,9 @@ a `experimental/endRunTest` when is done.
**Notification:** `ChangeTestStateParams`
```typescript
-type TestState = { tag: "passed" }
+type TestState = { tag: "passed" }
| {
- tag: "failed";
+ tag: "failed";
// The standard error of the test, containing the panic message. Clients should
// render it similar to a terminal, and e.g. handle ansi colors.
message: string;