Skip to content

Commit 802d9d5

Browse files
committed
Keep already computed inlay hint properties instead of late resolving them
1 parent 284e0cd commit 802d9d5

File tree

5 files changed

+99
-92
lines changed

5 files changed

+99
-92
lines changed

src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -302,21 +302,21 @@ pub struct InlayHintsConfig {
302302
}
303303

304304
impl InlayHintsConfig {
305-
fn lazy_text_edit(&self, finish: impl FnOnce() -> TextEdit) -> Lazy<TextEdit> {
305+
fn lazy_text_edit(&self, finish: impl FnOnce() -> TextEdit) -> LazyProperty<TextEdit> {
306306
if self.fields_to_resolve.resolve_text_edits {
307-
Lazy::Lazy
307+
LazyProperty::Lazy
308308
} else {
309309
let edit = finish();
310310
never!(edit.is_empty(), "inlay hint produced an empty text edit");
311-
Lazy::Computed(edit)
311+
LazyProperty::Computed(edit)
312312
}
313313
}
314314

315-
fn lazy_tooltip(&self, finish: impl FnOnce() -> InlayTooltip) -> Lazy<InlayTooltip> {
315+
fn lazy_tooltip(&self, finish: impl FnOnce() -> InlayTooltip) -> LazyProperty<InlayTooltip> {
316316
if self.fields_to_resolve.resolve_hint_tooltip
317317
&& self.fields_to_resolve.resolve_label_tooltip
318318
{
319-
Lazy::Lazy
319+
LazyProperty::Lazy
320320
} else {
321321
let tooltip = finish();
322322
never!(
@@ -327,7 +327,7 @@ impl InlayHintsConfig {
327327
.is_empty(),
328328
"inlay hint produced an empty tooltip"
329329
);
330-
Lazy::Computed(tooltip)
330+
LazyProperty::Computed(tooltip)
331331
}
332332
}
333333

@@ -336,11 +336,11 @@ impl InlayHintsConfig {
336336
fn lazy_location_opt(
337337
&self,
338338
finish: impl FnOnce() -> Option<FileRange>,
339-
) -> Option<Lazy<FileRange>> {
339+
) -> Option<LazyProperty<FileRange>> {
340340
if self.fields_to_resolve.resolve_label_location {
341-
Some(Lazy::Lazy)
341+
Some(LazyProperty::Lazy)
342342
} else {
343-
finish().map(Lazy::Computed)
343+
finish().map(LazyProperty::Computed)
344344
}
345345
}
346346
}
@@ -455,23 +455,23 @@ pub struct InlayHint {
455455
/// The actual label to show in the inlay hint.
456456
pub label: InlayHintLabel,
457457
/// Text edit to apply when "accepting" this inlay hint.
458-
pub text_edit: Option<Lazy<TextEdit>>,
458+
pub text_edit: Option<LazyProperty<TextEdit>>,
459459
/// Range to recompute inlay hints when trying to resolve for this hint. If this is none, the
460460
/// hint does not support resolving.
461461
pub resolve_parent: Option<TextRange>,
462462
}
463463

464464
/// A type signaling that a value is either computed, or is available for computation.
465465
#[derive(Clone, Debug)]
466-
pub enum Lazy<T> {
466+
pub enum LazyProperty<T> {
467467
Computed(T),
468468
Lazy,
469469
}
470470

471-
impl<T> Lazy<T> {
471+
impl<T> LazyProperty<T> {
472472
pub fn computed(self) -> Option<T> {
473473
match self {
474-
Lazy::Computed(it) => Some(it),
474+
LazyProperty::Computed(it) => Some(it),
475475
_ => None,
476476
}
477477
}
@@ -522,8 +522,8 @@ pub struct InlayHintLabel {
522522
impl InlayHintLabel {
523523
pub fn simple(
524524
s: impl Into<String>,
525-
tooltip: Option<Lazy<InlayTooltip>>,
526-
linked_location: Option<Lazy<FileRange>>,
525+
tooltip: Option<LazyProperty<InlayTooltip>>,
526+
linked_location: Option<LazyProperty<FileRange>>,
527527
) -> InlayHintLabel {
528528
InlayHintLabel {
529529
parts: smallvec![InlayHintLabelPart { text: s.into(), linked_location, tooltip }],
@@ -607,10 +607,10 @@ pub struct InlayHintLabelPart {
607607
/// refers to (not necessarily the location itself).
608608
/// When setting this, no tooltip must be set on the containing hint, or VS Code will display
609609
/// them both.
610-
pub linked_location: Option<Lazy<FileRange>>,
610+
pub linked_location: Option<LazyProperty<FileRange>>,
611611
/// The tooltip to show when hovering over the inlay hint, this may invoke other actions like
612612
/// hover requests to show.
613-
pub tooltip: Option<Lazy<InlayTooltip>>,
613+
pub tooltip: Option<LazyProperty<InlayTooltip>>,
614614
}
615615

616616
impl std::hash::Hash for InlayHintLabelPart {
@@ -624,16 +624,20 @@ impl std::hash::Hash for InlayHintLabelPart {
624624
impl fmt::Debug for InlayHintLabelPart {
625625
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
626626
match self {
627-
Self { text, linked_location: None, tooltip: None | Some(Lazy::Lazy) } => text.fmt(f),
627+
Self { text, linked_location: None, tooltip: None | Some(LazyProperty::Lazy) } => {
628+
text.fmt(f)
629+
}
628630
Self { text, linked_location, tooltip } => f
629631
.debug_struct("InlayHintLabelPart")
630632
.field("text", text)
631633
.field("linked_location", linked_location)
632634
.field(
633635
"tooltip",
634636
&tooltip.as_ref().map_or("", |it| match it {
635-
Lazy::Computed(InlayTooltip::String(it) | InlayTooltip::Markdown(it)) => it,
636-
Lazy::Lazy => "",
637+
LazyProperty::Computed(
638+
InlayTooltip::String(it) | InlayTooltip::Markdown(it),
639+
) => it,
640+
LazyProperty::Lazy => "",
637641
}),
638642
)
639643
.finish(),
@@ -677,7 +681,7 @@ impl InlayHintLabelBuilder<'_> {
677681
if !text.is_empty() {
678682
self.result.parts.push(InlayHintLabelPart {
679683
text,
680-
linked_location: self.location.take().map(Lazy::Computed),
684+
linked_location: self.location.take().map(LazyProperty::Computed),
681685
tooltip: None,
682686
});
683687
}
@@ -797,7 +801,7 @@ fn ty_to_text_edit(
797801
ty: &hir::Type,
798802
offset_to_insert: TextSize,
799803
prefix: impl Into<String>,
800-
) -> Option<Lazy<TextEdit>> {
804+
) -> Option<LazyProperty<TextEdit>> {
801805
// FIXME: Limit the length and bail out on excess somehow?
802806
let rendered = sema
803807
.scope(node_for_hint)

src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ mod tests {
8383
fixture,
8484
inlay_hints::{
8585
tests::{check_expect, check_with_config, DISABLED_CONFIG, TEST_CONFIG},
86-
Lazy,
86+
LazyProperty,
8787
},
8888
InlayHintsConfig,
8989
};
@@ -102,7 +102,7 @@ mod tests {
102102
let (analysis, file_id) = fixture::file(ra_fixture);
103103
let mut inlay_hints = analysis.inlay_hints(&config, file_id, None).unwrap();
104104
inlay_hints.iter_mut().flat_map(|hint| &mut hint.label.parts).for_each(|hint| {
105-
if let Some(Lazy::Computed(loc)) = &mut hint.linked_location {
105+
if let Some(LazyProperty::Computed(loc)) = &mut hint.linked_location {
106106
loc.range = TextRange::empty(TextSize::from(0));
107107
}
108108
});

src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use syntax::{
1212
};
1313

1414
use crate::{
15-
inlay_hints::Lazy, InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind,
15+
inlay_hints::LazyProperty, InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind,
1616
};
1717

1818
pub(super) fn hints(
@@ -143,7 +143,7 @@ pub(super) fn hints(
143143
acc.push(InlayHint {
144144
range: closing_token.text_range(),
145145
kind: InlayKind::ClosingBrace,
146-
label: InlayHintLabel::simple(label, None, linked_location.map(Lazy::Computed)),
146+
label: InlayHintLabel::simple(label, None, linked_location.map(LazyProperty::Computed)),
147147
text_edit: None,
148148
position: InlayHintPosition::After,
149149
pad_left: true,

src/tools/rust-analyzer/crates/ide/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ pub use crate::{
9191
inlay_hints::{
9292
AdjustmentHints, AdjustmentHintsMode, ClosureReturnTypeHints, DiscriminantHints,
9393
GenericParameterHints, InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart,
94-
InlayHintPosition, InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints,
94+
InlayHintPosition, InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints, LazyProperty
9595
},
9696
join_lines::JoinLinesConfig,
9797
markup::Markup,

src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs

Lines changed: 68 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use ide::{
1111
Annotation, AnnotationKind, Assist, AssistKind, Cancellable, CompletionFieldsToResolve,
1212
CompletionItem, CompletionItemKind, CompletionRelevance, Documentation, FileId, FileRange,
1313
FileSystemEdit, Fold, FoldKind, Highlight, HlMod, HlOperator, HlPunct, HlRange, HlTag, Indel,
14-
InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart, InlayKind, Markup,
15-
NavigationTarget, ReferenceCategory, RenameError, Runnable, Severity, SignatureHelp,
14+
InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart, InlayKind, LazyProperty,
15+
Markup, NavigationTarget, ReferenceCategory, RenameError, Runnable, Severity, SignatureHelp,
1616
SnippetEdit, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize,
1717
};
1818
use ide_db::{assists, rust_doc::format_docs, FxHasher};
@@ -549,12 +549,11 @@ pub(crate) fn inlay_hint(
549549
) -> Cancellable<lsp_types::InlayHint> {
550550
let hint_needs_resolve = |hint: &InlayHint| -> Option<TextRange> {
551551
hint.resolve_parent.filter(|_| {
552-
hint.text_edit.is_some()
553-
|| hint
554-
.label
555-
.parts
556-
.iter()
557-
.any(|part| part.linked_location.is_some() || part.tooltip.is_some())
552+
hint.text_edit.as_ref().is_some_and(LazyProperty::is_lazy)
553+
|| hint.label.parts.iter().any(|part| {
554+
part.linked_location.as_ref().is_some_and(LazyProperty::is_lazy)
555+
|| part.tooltip.as_ref().is_some_and(LazyProperty::is_lazy)
556+
})
558557
})
559558
};
560559

@@ -569,22 +568,21 @@ pub(crate) fn inlay_hint(
569568
});
570569

571570
let mut something_to_resolve = false;
572-
let text_edits = if snap
573-
.config
574-
.visual_studio_code_version()
575-
.is_none_or(|version| VersionReq::parse(">=1.86.0").unwrap().matches(version))
576-
&& resolve_range_and_hash.is_some()
577-
&& fields_to_resolve.resolve_text_edits
578-
{
579-
something_to_resolve |= inlay_hint.text_edit.is_some();
580-
None
581-
} else {
582-
inlay_hint
583-
.text_edit
584-
.take()
585-
.and_then(|it| it.computed())
586-
.map(|it| text_edit_vec(line_index, it))
587-
};
571+
let text_edits = inlay_hint
572+
.text_edit
573+
.take()
574+
.and_then(|it| match it {
575+
LazyProperty::Computed(it) => Some(it),
576+
LazyProperty::Lazy => {
577+
something_to_resolve |=
578+
snap.config.visual_studio_code_version().is_none_or(|version| {
579+
VersionReq::parse(">=1.86.0").unwrap().matches(version)
580+
}) && resolve_range_and_hash.is_some()
581+
&& fields_to_resolve.resolve_text_edits;
582+
None
583+
}
584+
})
585+
.map(|it| text_edit_vec(line_index, it));
588586
let (label, tooltip) = inlay_hint_label(
589587
snap,
590588
fields_to_resolve,
@@ -637,22 +635,23 @@ fn inlay_hint_label(
637635
let (label, tooltip) = match &*label.parts {
638636
[InlayHintLabelPart { linked_location: None, .. }] => {
639637
let InlayHintLabelPart { text, tooltip, .. } = label.parts.pop().unwrap();
640-
let hint_tooltip = if needs_resolve && fields_to_resolve.resolve_hint_tooltip {
641-
*something_to_resolve |= tooltip.is_some();
642-
None
643-
} else {
644-
match tooltip.and_then(|it| it.computed()) {
645-
Some(ide::InlayTooltip::String(s)) => {
646-
Some(lsp_types::InlayHintTooltip::String(s))
647-
}
648-
Some(ide::InlayTooltip::Markdown(s)) => {
649-
Some(lsp_types::InlayHintTooltip::MarkupContent(lsp_types::MarkupContent {
650-
kind: lsp_types::MarkupKind::Markdown,
651-
value: s,
652-
}))
653-
}
654-
None => None,
638+
let tooltip = tooltip.and_then(|it| match it {
639+
LazyProperty::Computed(it) => Some(it),
640+
LazyProperty::Lazy => {
641+
*something_to_resolve |=
642+
needs_resolve && fields_to_resolve.resolve_hint_tooltip;
643+
None
655644
}
645+
});
646+
let hint_tooltip = match tooltip {
647+
Some(ide::InlayTooltip::String(s)) => Some(lsp_types::InlayHintTooltip::String(s)),
648+
Some(ide::InlayTooltip::Markdown(s)) => {
649+
Some(lsp_types::InlayHintTooltip::MarkupContent(lsp_types::MarkupContent {
650+
kind: lsp_types::MarkupKind::Markdown,
651+
value: s,
652+
}))
653+
}
654+
None => None,
656655
};
657656
(lsp_types::InlayHintLabel::String(text), hint_tooltip)
658657
}
@@ -661,34 +660,38 @@ fn inlay_hint_label(
661660
.parts
662661
.into_iter()
663662
.map(|part| {
664-
let tooltip = if needs_resolve && fields_to_resolve.resolve_label_tooltip {
665-
*something_to_resolve |= part.tooltip.is_some();
666-
None
667-
} else {
668-
match part.tooltip.and_then(|it| it.computed()) {
669-
Some(ide::InlayTooltip::String(s)) => {
670-
Some(lsp_types::InlayHintLabelPartTooltip::String(s))
671-
}
672-
Some(ide::InlayTooltip::Markdown(s)) => {
673-
Some(lsp_types::InlayHintLabelPartTooltip::MarkupContent(
674-
lsp_types::MarkupContent {
675-
kind: lsp_types::MarkupKind::Markdown,
676-
value: s,
677-
},
678-
))
679-
}
680-
None => None,
663+
let tooltip = part.tooltip.and_then(|it| match it {
664+
LazyProperty::Computed(it) => Some(it),
665+
LazyProperty::Lazy => {
666+
*something_to_resolve |= fields_to_resolve.resolve_label_tooltip;
667+
None
681668
}
669+
});
670+
let tooltip = match tooltip {
671+
Some(ide::InlayTooltip::String(s)) => {
672+
Some(lsp_types::InlayHintLabelPartTooltip::String(s))
673+
}
674+
Some(ide::InlayTooltip::Markdown(s)) => {
675+
Some(lsp_types::InlayHintLabelPartTooltip::MarkupContent(
676+
lsp_types::MarkupContent {
677+
kind: lsp_types::MarkupKind::Markdown,
678+
value: s,
679+
},
680+
))
681+
}
682+
None => None,
682683
};
683-
let location = if needs_resolve && fields_to_resolve.resolve_label_location {
684-
*something_to_resolve |= part.linked_location.is_some();
685-
None
686-
} else {
687-
part.linked_location
688-
.and_then(|it| it.computed())
689-
.map(|range| location(snap, range))
690-
.transpose()?
691-
};
684+
let location = part
685+
.linked_location
686+
.and_then(|it| match it {
687+
LazyProperty::Computed(it) => Some(it),
688+
LazyProperty::Lazy => {
689+
*something_to_resolve |= fields_to_resolve.resolve_label_location;
690+
None
691+
}
692+
})
693+
.map(|range| location(snap, range))
694+
.transpose()?;
692695
Ok(lsp_types::InlayHintLabelPart {
693696
value: part.text,
694697
tooltip,

0 commit comments

Comments
 (0)