Provide resolve data only when it can actually be resolved

This commit is contained in:
Kirill Bulatov 2023-09-02 21:33:44 +03:00
parent caf018507a
commit 7b3dba5d77
13 changed files with 82 additions and 35 deletions

View File

@ -153,11 +153,13 @@ pub struct InlayHint {
pub label: InlayHintLabel, pub label: InlayHintLabel,
/// Text edit to apply when "accepting" this inlay hint. /// Text edit to apply when "accepting" this inlay hint.
pub text_edit: Option<TextEdit>, pub text_edit: Option<TextEdit>,
pub needs_resolve: bool,
} }
impl InlayHint { impl InlayHint {
fn closing_paren_after(kind: InlayKind, range: TextRange) -> InlayHint { fn closing_paren_after(kind: InlayKind, range: TextRange) -> InlayHint {
InlayHint { InlayHint {
needs_resolve: false,
range, range,
kind, kind,
label: InlayHintLabel::from(")"), label: InlayHintLabel::from(")"),
@ -169,6 +171,7 @@ impl InlayHint {
} }
fn opening_paren_before(kind: InlayKind, range: TextRange) -> InlayHint { fn opening_paren_before(kind: InlayKind, range: TextRange) -> InlayHint {
InlayHint { InlayHint {
needs_resolve: false,
range, range,
kind, kind,
label: InlayHintLabel::from("("), label: InlayHintLabel::from("("),
@ -226,6 +229,10 @@ impl InlayHintLabel {
}), }),
} }
} }
pub fn needs_resolve(&self) -> bool {
self.parts.iter().any(|part| part.linked_location.is_some() || part.tooltip.is_some())
}
} }
impl From<String> for InlayHintLabel { impl From<String> for InlayHintLabel {

View File

@ -137,21 +137,23 @@ pub(super) fn hints(
} }
_ => continue, _ => continue,
}; };
let label = InlayHintLabel::simple(
if postfix { format!(".{}", text.trim_end()) } else { text.to_owned() },
Some(InlayTooltip::Markdown(format!(
"`{}` → `{}` ({coercion} coercion)",
source.display(sema.db),
target.display(sema.db),
))),
None,
);
acc.push(InlayHint { acc.push(InlayHint {
needs_resolve: label.needs_resolve(),
range: expr.syntax().text_range(), range: expr.syntax().text_range(),
pad_left: false, pad_left: false,
pad_right: false, pad_right: false,
position: if postfix { InlayHintPosition::After } else { InlayHintPosition::Before }, position: if postfix { InlayHintPosition::After } else { InlayHintPosition::Before },
kind: InlayKind::Adjustment, kind: InlayKind::Adjustment,
label: InlayHintLabel::simple( label,
if postfix { format!(".{}", text.trim_end()) } else { text.to_owned() },
Some(InlayTooltip::Markdown(format!(
"`{}` → `{}` ({coercion} coercion)",
source.display(sema.db),
target.display(sema.db),
))),
None,
),
text_edit: None, text_edit: None,
}); });
} }

View File

@ -99,6 +99,7 @@ pub(super) fn hints(
None => pat.syntax().text_range(), None => pat.syntax().text_range(),
}; };
acc.push(InlayHint { acc.push(InlayHint {
needs_resolve: label.needs_resolve() || text_edit.is_some(),
range: match type_ascriptable { range: match type_ascriptable {
Some(Some(t)) => text_range.cover(t.text_range()), Some(Some(t)) => text_range.cover(t.text_range()),
_ => text_range, _ => text_range,

View File

@ -50,9 +50,10 @@ pub(super) fn hints(
_ => return, _ => return,
}; };
acc.push(InlayHint { acc.push(InlayHint {
needs_resolve: false,
range, range,
kind: InlayKind::BindingMode, kind: InlayKind::BindingMode,
label: r.to_string().into(), label: r.into(),
text_edit: None, text_edit: None,
position: InlayHintPosition::Before, position: InlayHintPosition::Before,
pad_left: false, pad_left: false,
@ -68,9 +69,10 @@ pub(super) fn hints(
hir::BindingMode::Ref(Mutability::Shared) => "ref", hir::BindingMode::Ref(Mutability::Shared) => "ref",
}; };
acc.push(InlayHint { acc.push(InlayHint {
needs_resolve: false,
range: pat.syntax().text_range(), range: pat.syntax().text_range(),
kind: InlayKind::BindingMode, kind: InlayKind::BindingMode,
label: bm.to_string().into(), label: bm.into(),
text_edit: None, text_edit: None,
position: InlayHintPosition::Before, position: InlayHintPosition::Before,
pad_left: false, pad_left: false,

View File

@ -57,10 +57,12 @@ pub(super) fn hints(
} }
} }
} }
let label = label_of_ty(famous_defs, config, &ty)?;
acc.push(InlayHint { acc.push(InlayHint {
needs_resolve: label.needs_resolve(),
range: expr.syntax().text_range(), range: expr.syntax().text_range(),
kind: InlayKind::Chaining, kind: InlayKind::Chaining,
label: label_of_ty(famous_defs, config, &ty)?, label,
text_edit: None, text_edit: None,
position: InlayHintPosition::After, position: InlayHintPosition::After,
pad_left: true, pad_left: true,
@ -128,6 +130,7 @@ fn main() {
"", "",
], ],
text_edit: None, text_edit: None,
needs_resolve: true,
}, },
InlayHint { InlayHint {
range: 147..154, range: 147..154,
@ -152,6 +155,7 @@ fn main() {
"", "",
], ],
text_edit: None, text_edit: None,
needs_resolve: true,
}, },
] ]
"#]], "#]],
@ -221,6 +225,7 @@ fn main() {
"", "",
], ],
text_edit: None, text_edit: None,
needs_resolve: true,
}, },
InlayHint { InlayHint {
range: 143..179, range: 143..179,
@ -245,6 +250,7 @@ fn main() {
"", "",
], ],
text_edit: None, text_edit: None,
needs_resolve: true,
}, },
] ]
"#]], "#]],
@ -298,6 +304,7 @@ fn main() {
"", "",
], ],
text_edit: None, text_edit: None,
needs_resolve: true,
}, },
InlayHint { InlayHint {
range: 143..179, range: 143..179,
@ -322,6 +329,7 @@ fn main() {
"", "",
], ],
text_edit: None, text_edit: None,
needs_resolve: true,
}, },
] ]
"#]], "#]],
@ -389,6 +397,7 @@ fn main() {
"<i32, bool>>", "<i32, bool>>",
], ],
text_edit: None, text_edit: None,
needs_resolve: true,
}, },
InlayHint { InlayHint {
range: 246..265, range: 246..265,
@ -426,6 +435,7 @@ fn main() {
"<i32, bool>>", "<i32, bool>>",
], ],
text_edit: None, text_edit: None,
needs_resolve: true,
}, },
] ]
"#]], "#]],
@ -495,6 +505,7 @@ fn main() {
" = ()>", " = ()>",
], ],
text_edit: None, text_edit: None,
needs_resolve: true,
}, },
InlayHint { InlayHint {
range: 174..224, range: 174..224,
@ -532,6 +543,7 @@ fn main() {
" = ()>", " = ()>",
], ],
text_edit: None, text_edit: None,
needs_resolve: true,
}, },
InlayHint { InlayHint {
range: 174..206, range: 174..206,
@ -569,6 +581,7 @@ fn main() {
" = ()>", " = ()>",
], ],
text_edit: None, text_edit: None,
needs_resolve: true,
}, },
InlayHint { InlayHint {
range: 174..189, range: 174..189,
@ -593,6 +606,7 @@ fn main() {
"", "",
], ],
text_edit: None, text_edit: None,
needs_resolve: true,
}, },
] ]
"#]], "#]],
@ -655,6 +669,7 @@ fn main() {
], ],
}, },
), ),
needs_resolve: true,
}, },
InlayHint { InlayHint {
range: 145..185, range: 145..185,
@ -679,6 +694,7 @@ fn main() {
"", "",
], ],
text_edit: None, text_edit: None,
needs_resolve: true,
}, },
InlayHint { InlayHint {
range: 145..168, range: 145..168,
@ -703,6 +719,7 @@ fn main() {
"", "",
], ],
text_edit: None, text_edit: None,
needs_resolve: true,
}, },
InlayHint { InlayHint {
range: 222..228, range: 222..228,
@ -725,6 +742,7 @@ fn main() {
}, },
], ],
text_edit: None, text_edit: None,
needs_resolve: true,
}, },
] ]
"#]], "#]],

View File

@ -109,6 +109,7 @@ pub(super) fn hints(
let linked_location = name_range.map(|range| FileRange { file_id, range }); let linked_location = name_range.map(|range| FileRange { file_id, range });
acc.push(InlayHint { acc.push(InlayHint {
needs_resolve: linked_location.is_some(),
range: closing_token.text_range(), range: closing_token.text_range(),
kind: InlayKind::ClosingBrace, kind: InlayKind::ClosingBrace,
label: InlayHintLabel::simple(label, None, linked_location), label: InlayHintLabel::simple(label, None, linked_location),

View File

@ -31,9 +31,10 @@ pub(super) fn hints(
let range = closure.syntax().first_token()?.prev_token()?.text_range(); let range = closure.syntax().first_token()?.prev_token()?.text_range();
let range = TextRange::new(range.end() - TextSize::from(1), range.end()); let range = TextRange::new(range.end() - TextSize::from(1), range.end());
acc.push(InlayHint { acc.push(InlayHint {
needs_resolve: false,
range, range,
kind: InlayKind::ClosureCapture, kind: InlayKind::ClosureCapture,
label: InlayHintLabel::simple("move", None, None), label: InlayHintLabel::from("move"),
text_edit: None, text_edit: None,
position: InlayHintPosition::After, position: InlayHintPosition::After,
pad_left: false, pad_left: false,
@ -43,6 +44,7 @@ pub(super) fn hints(
} }
}; };
acc.push(InlayHint { acc.push(InlayHint {
needs_resolve: false,
range: move_kw_range, range: move_kw_range,
kind: InlayKind::ClosureCapture, kind: InlayKind::ClosureCapture,
label: InlayHintLabel::from("("), label: InlayHintLabel::from("("),
@ -59,23 +61,25 @@ pub(super) fn hints(
// force cache the source file, otherwise sema lookup will potentially panic // force cache the source file, otherwise sema lookup will potentially panic
_ = sema.parse_or_expand(source.file()); _ = sema.parse_or_expand(source.file());
let label = InlayHintLabel::simple(
format!(
"{}{}",
match capture.kind() {
hir::CaptureKind::SharedRef => "&",
hir::CaptureKind::UniqueSharedRef => "&unique ",
hir::CaptureKind::MutableRef => "&mut ",
hir::CaptureKind::Move => "",
},
capture.display_place(sema.db)
),
None,
source.name().and_then(|name| name.syntax().original_file_range_opt(sema.db)),
);
acc.push(InlayHint { acc.push(InlayHint {
needs_resolve: label.needs_resolve(),
range: move_kw_range, range: move_kw_range,
kind: InlayKind::ClosureCapture, kind: InlayKind::ClosureCapture,
label: InlayHintLabel::simple( label,
format!(
"{}{}",
match capture.kind() {
hir::CaptureKind::SharedRef => "&",
hir::CaptureKind::UniqueSharedRef => "&unique ",
hir::CaptureKind::MutableRef => "&mut ",
hir::CaptureKind::Move => "",
},
capture.display_place(sema.db)
),
None,
source.name().and_then(|name| name.syntax().original_file_range_opt(sema.db)),
),
text_edit: None, text_edit: None,
position: InlayHintPosition::After, position: InlayHintPosition::After,
pad_left: false, pad_left: false,
@ -84,9 +88,10 @@ pub(super) fn hints(
if idx != last { if idx != last {
acc.push(InlayHint { acc.push(InlayHint {
needs_resolve: false,
range: move_kw_range, range: move_kw_range,
kind: InlayKind::ClosureCapture, kind: InlayKind::ClosureCapture,
label: InlayHintLabel::simple(", ", None, None), label: InlayHintLabel::from(", "),
text_edit: None, text_edit: None,
position: InlayHintPosition::After, position: InlayHintPosition::After,
pad_left: false, pad_left: false,
@ -95,6 +100,7 @@ pub(super) fn hints(
} }
} }
acc.push(InlayHint { acc.push(InlayHint {
needs_resolve: false,
range: move_kw_range, range: move_kw_range,
kind: InlayKind::ClosureCapture, kind: InlayKind::ClosureCapture,
label: InlayHintLabel::from(")"), label: InlayHintLabel::from(")"),

View File

@ -64,6 +64,7 @@ pub(super) fn hints(
}; };
acc.push(InlayHint { acc.push(InlayHint {
needs_resolve: label.needs_resolve() || text_edit.is_some(),
range: param_list.syntax().text_range(), range: param_list.syntax().text_range(),
kind: InlayKind::Type, kind: InlayKind::Type,
label, label,

View File

@ -79,6 +79,7 @@ fn variant_hints(
None, None,
); );
acc.push(InlayHint { acc.push(InlayHint {
needs_resolve: label.needs_resolve(),
range: match eq_token { range: match eq_token {
Some(t) => range.cover(t.text_range()), Some(t) => range.cover(t.text_range()),
_ => range, _ => range,

View File

@ -22,6 +22,7 @@ pub(super) fn hints(
} }
let mk_lt_hint = |t: SyntaxToken, label: String| InlayHint { let mk_lt_hint = |t: SyntaxToken, label: String| InlayHint {
needs_resolve: false,
range: t.text_range(), range: t.text_range(),
kind: InlayKind::Lifetime, kind: InlayKind::Lifetime,
label: label.into(), label: label.into(),
@ -185,6 +186,7 @@ pub(super) fn hints(
let angle_tok = gpl.l_angle_token()?; let angle_tok = gpl.l_angle_token()?;
let is_empty = gpl.generic_params().next().is_none(); let is_empty = gpl.generic_params().next().is_none();
acc.push(InlayHint { acc.push(InlayHint {
needs_resolve: false,
range: angle_tok.text_range(), range: angle_tok.text_range(),
kind: InlayKind::Lifetime, kind: InlayKind::Lifetime,
label: format!( label: format!(
@ -200,6 +202,7 @@ pub(super) fn hints(
}); });
} }
(None, allocated_lifetimes) => acc.push(InlayHint { (None, allocated_lifetimes) => acc.push(InlayHint {
needs_resolve: false,
range: func.name()?.syntax().text_range(), range: func.name()?.syntax().text_range(),
kind: InlayKind::GenericParamList, kind: InlayKind::GenericParamList,
label: format!("<{}>", allocated_lifetimes.iter().format(", "),).into(), label: format!("<{}>", allocated_lifetimes.iter().format(", "),).into(),

View File

@ -31,9 +31,10 @@ pub(super) fn hints(
if ty.lifetime().is_none() { if ty.lifetime().is_none() {
let t = ty.amp_token()?; let t = ty.amp_token()?;
acc.push(InlayHint { acc.push(InlayHint {
needs_resolve: false,
range: t.text_range(), range: t.text_range(),
kind: InlayKind::Lifetime, kind: InlayKind::Lifetime,
label: "'static".to_owned().into(), label: "'static".into(),
text_edit: None, text_edit: None,
position: InlayHintPosition::After, position: InlayHintPosition::After,
pad_left: false, pad_left: false,

View File

@ -57,6 +57,7 @@ pub(super) fn hints(
let label = let label =
InlayHintLabel::simple(format!("{param_name}{colon}"), None, linked_location); InlayHintLabel::simple(format!("{param_name}{colon}"), None, linked_location);
InlayHint { InlayHint {
needs_resolve: label.needs_resolve(),
range, range,
kind: InlayKind::Parameter, kind: InlayKind::Parameter,
label, label,

View File

@ -442,13 +442,15 @@ pub(crate) fn inlay_hint(
file_id: FileId, file_id: FileId,
inlay_hint: InlayHint, inlay_hint: InlayHint,
) -> Cancellable<lsp_types::InlayHint> { ) -> Cancellable<lsp_types::InlayHint> {
let (label, tooltip) = inlay_hint_label(snap, fields_to_resolve, inlay_hint.label)?; let needs_resolve = inlay_hint.needs_resolve;
let data = if fields_to_resolve.can_resolve() { let (label, tooltip) =
inlay_hint_label(snap, fields_to_resolve, needs_resolve, inlay_hint.label)?;
let data = if needs_resolve && fields_to_resolve.can_resolve() {
Some(to_value(lsp_ext::InlayHintResolveData { file_id: file_id.0 }).unwrap()) Some(to_value(lsp_ext::InlayHintResolveData { file_id: file_id.0 }).unwrap())
} else { } else {
None None
}; };
let text_edits = if fields_to_resolve.resolve_text_edits { let text_edits = if needs_resolve && fields_to_resolve.resolve_text_edits {
None None
} else { } else {
inlay_hint.text_edit.map(|it| text_edit_vec(line_index, it)) inlay_hint.text_edit.map(|it| text_edit_vec(line_index, it))
@ -476,12 +478,13 @@ pub(crate) fn inlay_hint(
fn inlay_hint_label( fn inlay_hint_label(
snap: &GlobalStateSnapshot, snap: &GlobalStateSnapshot,
fields_to_resolve: &InlayFieldsToResolve, fields_to_resolve: &InlayFieldsToResolve,
needs_resolve: bool,
mut label: InlayHintLabel, mut label: InlayHintLabel,
) -> Cancellable<(lsp_types::InlayHintLabel, Option<lsp_types::InlayHintTooltip>)> { ) -> Cancellable<(lsp_types::InlayHintLabel, Option<lsp_types::InlayHintTooltip>)> {
let res = match &*label.parts { let res = match &*label.parts {
[InlayHintLabelPart { linked_location: None, .. }] => { [InlayHintLabelPart { linked_location: None, .. }] => {
let InlayHintLabelPart { text, tooltip, .. } = label.parts.pop().unwrap(); let InlayHintLabelPart { text, tooltip, .. } = label.parts.pop().unwrap();
let hint_tooltip = if fields_to_resolve.resolve_hint_tooltip { let hint_tooltip = if needs_resolve && fields_to_resolve.resolve_hint_tooltip {
None None
} else { } else {
match tooltip { match tooltip {
@ -504,7 +507,7 @@ fn inlay_hint_label(
.parts .parts
.into_iter() .into_iter()
.map(|part| { .map(|part| {
let tooltip = if fields_to_resolve.resolve_label_tooltip { let tooltip = if needs_resolve && fields_to_resolve.resolve_label_tooltip {
None None
} else { } else {
match part.tooltip { match part.tooltip {
@ -522,7 +525,7 @@ fn inlay_hint_label(
None => None, None => None,
} }
}; };
let location = if fields_to_resolve.resolve_label_location { let location = if needs_resolve && fields_to_resolve.resolve_label_location {
None None
} else { } else {
part.linked_location.map(|range| location(snap, range)).transpose()? part.linked_location.map(|range| location(snap, range)).transpose()?