diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 2fc3629252..505217cdc1 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -307,6 +307,25 @@ impl InlayHintsConfig { Lazy::Computed(edit) } } + + fn lazy_tooltip(&self, finish: impl FnOnce() -> InlayTooltip) -> Lazy { + if self.fields_to_resolve.resolve_hint_tooltip + && self.fields_to_resolve.resolve_label_tooltip + { + Lazy::Lazy + } else { + let tooltip = finish(); + never!( + match &tooltip { + InlayTooltip::String(s) => s, + InlayTooltip::Markdown(s) => s, + } + .is_empty(), + "inlay hint produced an empty tooltip" + ); + Lazy::Computed(tooltip) + } + } } #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -486,7 +505,7 @@ pub struct InlayHintLabel { impl InlayHintLabel { pub fn simple( s: impl Into, - tooltip: Option, + tooltip: Option>, linked_location: Option, ) -> InlayHintLabel { InlayHintLabel { @@ -564,7 +583,6 @@ 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 @@ -575,13 +593,21 @@ pub struct InlayHintLabelPart { pub linked_location: Option, /// The tooltip to show when hovering over the inlay hint, this may invoke other actions like /// hover requests to show. - pub tooltip: Option, + pub tooltip: Option>, +} + +impl std::hash::Hash for InlayHintLabelPart { + fn hash(&self, state: &mut H) { + self.text.hash(state); + self.linked_location.hash(state); + self.tooltip.is_some().hash(state); + } } impl fmt::Debug for InlayHintLabelPart { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Self { text, linked_location: None, tooltip: None } => text.fmt(f), + Self { text, linked_location: None, tooltip: None | Some(Lazy::Lazy) } => text.fmt(f), Self { text, linked_location, tooltip } => f .debug_struct("InlayHintLabelPart") .field("text", text) @@ -589,7 +615,8 @@ impl fmt::Debug for InlayHintLabelPart { .field( "tooltip", &tooltip.as_ref().map_or("", |it| match it { - InlayTooltip::String(it) | InlayTooltip::Markdown(it) => it, + Lazy::Computed(InlayTooltip::String(it) | InlayTooltip::Markdown(it)) => it, + Lazy::Lazy => "", }), ) .finish(), diff --git a/crates/ide/src/inlay_hints/adjustment.rs b/crates/ide/src/inlay_hints/adjustment.rs index 013e008bf9..2acd4021cc 100644 --- a/crates/ide/src/inlay_hints/adjustment.rs +++ b/crates/ide/src/inlay_hints/adjustment.rs @@ -162,11 +162,13 @@ pub(super) fn hints( let label = InlayHintLabelPart { text: if postfix { format!(".{}", text.trim_end()) } else { text.to_owned() }, linked_location: None, - tooltip: Some(InlayTooltip::Markdown(format!( - "`{}` → `{}` ({coercion} coercion)", - source.display(sema.db, file_id.edition()), - target.display(sema.db, file_id.edition()), - ))), + tooltip: Some(config.lazy_tooltip(|| { + InlayTooltip::Markdown(format!( + "`{}` → `{}` ({coercion} coercion)", + source.display(sema.db, file_id.edition()), + target.display(sema.db, file_id.edition()), + )) + })), }; if postfix { &mut post } else { &mut pre }.label.append_part(label); } diff --git a/crates/ide/src/inlay_hints/discriminant.rs b/crates/ide/src/inlay_hints/discriminant.rs index 5a147adabc..f1e1955d14 100644 --- a/crates/ide/src/inlay_hints/discriminant.rs +++ b/crates/ide/src/inlay_hints/discriminant.rs @@ -76,9 +76,11 @@ fn variant_hints( } Err(_) => format!("{eq_} ?"), }, - Some(InlayTooltip::String(match &d { - Ok(_) => "enum variant discriminant".into(), - Err(e) => format!("{e:?}"), + Some(config.lazy_tooltip(|| { + InlayTooltip::String(match &d { + Ok(_) => "enum variant discriminant".into(), + Err(e) => format!("{e:?}"), + }) })), None, ); diff --git a/crates/ide/src/inlay_hints/implicit_drop.rs b/crates/ide/src/inlay_hints/implicit_drop.rs index dd4b3efeec..1358d3722f 100644 --- a/crates/ide/src/inlay_hints/implicit_drop.rs +++ b/crates/ide/src/inlay_hints/implicit_drop.rs @@ -108,7 +108,7 @@ pub(super) fn hints( } let mut label = InlayHintLabel::simple( name, - Some(crate::InlayTooltip::String("moz".into())), + Some(config.lazy_tooltip(|| crate::InlayTooltip::String("moz".into()))), binding_source, ); label.prepend_str("drop("); diff --git a/crates/rust-analyzer/src/lsp/to_proto.rs b/crates/rust-analyzer/src/lsp/to_proto.rs index a3b54f532c..a5516e7f9d 100644 --- a/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/crates/rust-analyzer/src/lsp/to_proto.rs @@ -641,7 +641,7 @@ fn inlay_hint_label( *something_to_resolve |= tooltip.is_some(); None } else { - match tooltip { + match tooltip.and_then(|it| it.computed()) { Some(ide::InlayTooltip::String(s)) => { Some(lsp_types::InlayHintTooltip::String(s)) } @@ -665,7 +665,7 @@ fn inlay_hint_label( *something_to_resolve |= part.tooltip.is_some(); None } else { - match part.tooltip { + match part.tooltip.and_then(|it| it.computed()) { Some(ide::InlayTooltip::String(s)) => { Some(lsp_types::InlayHintLabelPartTooltip::String(s)) }