diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 8061ee5ee2..78c177ccbe 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -153,11 +153,13 @@ pub struct InlayHint { pub label: InlayHintLabel, /// Text edit to apply when "accepting" this inlay hint. pub text_edit: Option, + pub needs_resolve: bool, } impl InlayHint { fn closing_paren_after(kind: InlayKind, range: TextRange) -> InlayHint { InlayHint { + needs_resolve: false, range, kind, label: InlayHintLabel::from(")"), @@ -169,6 +171,7 @@ impl InlayHint { } fn opening_paren_before(kind: InlayKind, range: TextRange) -> InlayHint { InlayHint { + needs_resolve: false, range, kind, 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 for InlayHintLabel { diff --git a/crates/ide/src/inlay_hints/adjustment.rs b/crates/ide/src/inlay_hints/adjustment.rs index 6d6bd315eb..631807d99a 100644 --- a/crates/ide/src/inlay_hints/adjustment.rs +++ b/crates/ide/src/inlay_hints/adjustment.rs @@ -137,21 +137,23 @@ pub(super) fn hints( } _ => 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 { + needs_resolve: label.needs_resolve(), range: expr.syntax().text_range(), pad_left: false, pad_right: false, position: if postfix { InlayHintPosition::After } else { InlayHintPosition::Before }, kind: InlayKind::Adjustment, - 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, - ), + label, text_edit: None, }); } diff --git a/crates/ide/src/inlay_hints/bind_pat.rs b/crates/ide/src/inlay_hints/bind_pat.rs index 07b9f9cc1f..680035c721 100644 --- a/crates/ide/src/inlay_hints/bind_pat.rs +++ b/crates/ide/src/inlay_hints/bind_pat.rs @@ -99,6 +99,7 @@ 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, diff --git a/crates/ide/src/inlay_hints/binding_mode.rs b/crates/ide/src/inlay_hints/binding_mode.rs index 343cf17e50..35504ffa78 100644 --- a/crates/ide/src/inlay_hints/binding_mode.rs +++ b/crates/ide/src/inlay_hints/binding_mode.rs @@ -50,9 +50,10 @@ pub(super) fn hints( _ => return, }; acc.push(InlayHint { + needs_resolve: false, range, kind: InlayKind::BindingMode, - label: r.to_string().into(), + label: r.into(), text_edit: None, position: InlayHintPosition::Before, pad_left: false, @@ -68,9 +69,10 @@ 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.to_string().into(), + label: bm.into(), text_edit: None, position: InlayHintPosition::Before, pad_left: false, diff --git a/crates/ide/src/inlay_hints/chaining.rs b/crates/ide/src/inlay_hints/chaining.rs index b621a8dda7..af5f5c3270 100644 --- a/crates/ide/src/inlay_hints/chaining.rs +++ b/crates/ide/src/inlay_hints/chaining.rs @@ -57,10 +57,12 @@ 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: label_of_ty(famous_defs, config, &ty)?, + label, text_edit: None, position: InlayHintPosition::After, pad_left: true, @@ -128,6 +130,7 @@ fn main() { "", ], text_edit: None, + needs_resolve: true, }, InlayHint { range: 147..154, @@ -152,6 +155,7 @@ fn main() { "", ], text_edit: None, + needs_resolve: true, }, ] "#]], @@ -221,6 +225,7 @@ fn main() { "", ], text_edit: None, + needs_resolve: true, }, InlayHint { range: 143..179, @@ -245,6 +250,7 @@ fn main() { "", ], text_edit: None, + needs_resolve: true, }, ] "#]], @@ -298,6 +304,7 @@ fn main() { "", ], text_edit: None, + needs_resolve: true, }, InlayHint { range: 143..179, @@ -322,6 +329,7 @@ fn main() { "", ], text_edit: None, + needs_resolve: true, }, ] "#]], @@ -389,6 +397,7 @@ fn main() { ">", ], text_edit: None, + needs_resolve: true, }, InlayHint { range: 246..265, @@ -426,6 +435,7 @@ fn main() { ">", ], text_edit: None, + needs_resolve: true, }, ] "#]], @@ -495,6 +505,7 @@ fn main() { " = ()>", ], text_edit: None, + needs_resolve: true, }, InlayHint { range: 174..224, @@ -532,6 +543,7 @@ fn main() { " = ()>", ], text_edit: None, + needs_resolve: true, }, InlayHint { range: 174..206, @@ -569,6 +581,7 @@ fn main() { " = ()>", ], text_edit: None, + needs_resolve: true, }, InlayHint { range: 174..189, @@ -593,6 +606,7 @@ fn main() { "", ], text_edit: None, + needs_resolve: true, }, ] "#]], @@ -655,6 +669,7 @@ fn main() { ], }, ), + needs_resolve: true, }, InlayHint { range: 145..185, @@ -679,6 +694,7 @@ fn main() { "", ], text_edit: None, + needs_resolve: true, }, InlayHint { range: 145..168, @@ -703,6 +719,7 @@ fn main() { "", ], text_edit: None, + needs_resolve: true, }, InlayHint { range: 222..228, @@ -725,6 +742,7 @@ fn main() { }, ], text_edit: None, + needs_resolve: true, }, ] "#]], diff --git a/crates/ide/src/inlay_hints/closing_brace.rs b/crates/ide/src/inlay_hints/closing_brace.rs index 2cefd5acdc..2b68538c19 100644 --- a/crates/ide/src/inlay_hints/closing_brace.rs +++ b/crates/ide/src/inlay_hints/closing_brace.rs @@ -109,6 +109,7 @@ 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 9d5defcbb7..d691303c18 100644 --- a/crates/ide/src/inlay_hints/closure_captures.rs +++ b/crates/ide/src/inlay_hints/closure_captures.rs @@ -31,9 +31,10 @@ 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::simple("move", None, None), + label: InlayHintLabel::from("move"), text_edit: None, position: InlayHintPosition::After, pad_left: false, @@ -43,6 +44,7 @@ pub(super) fn hints( } }; acc.push(InlayHint { + needs_resolve: false, range: move_kw_range, kind: InlayKind::ClosureCapture, label: InlayHintLabel::from("("), @@ -59,23 +61,25 @@ pub(super) fn hints( // force cache the source file, otherwise sema lookup will potentially panic _ = 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 { + needs_resolve: label.needs_resolve(), range: move_kw_range, kind: InlayKind::ClosureCapture, - 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)), - ), + label, text_edit: None, position: InlayHintPosition::After, pad_left: false, @@ -84,9 +88,10 @@ pub(super) fn hints( if idx != last { acc.push(InlayHint { + needs_resolve: false, range: move_kw_range, kind: InlayKind::ClosureCapture, - label: InlayHintLabel::simple(", ", None, None), + label: InlayHintLabel::from(", "), text_edit: None, position: InlayHintPosition::After, pad_left: false, @@ -95,6 +100,7 @@ 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 3b41db0f13..204967cd7c 100644 --- a/crates/ide/src/inlay_hints/closure_ret.rs +++ b/crates/ide/src/inlay_hints/closure_ret.rs @@ -64,6 +64,7 @@ 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 c4d2ac75cf..26dc6fa8b9 100644 --- a/crates/ide/src/inlay_hints/discriminant.rs +++ b/crates/ide/src/inlay_hints/discriminant.rs @@ -79,6 +79,7 @@ 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 5fce11b785..7b05e32ad8 100644 --- a/crates/ide/src/inlay_hints/fn_lifetime_fn.rs +++ b/crates/ide/src/inlay_hints/fn_lifetime_fn.rs @@ -22,6 +22,7 @@ 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(), @@ -185,6 +186,7 @@ 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,6 +202,7 @@ 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_static.rs b/crates/ide/src/inlay_hints/implicit_static.rs index fc297a8d82..f18e6421cb 100644 --- a/crates/ide/src/inlay_hints/implicit_static.rs +++ b/crates/ide/src/inlay_hints/implicit_static.rs @@ -31,9 +31,10 @@ 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".to_owned().into(), + label: "'static".into(), text_edit: None, position: InlayHintPosition::After, pad_left: false, diff --git a/crates/ide/src/inlay_hints/param_name.rs b/crates/ide/src/inlay_hints/param_name.rs index c4f43f4117..b4260d8250 100644 --- a/crates/ide/src/inlay_hints/param_name.rs +++ b/crates/ide/src/inlay_hints/param_name.rs @@ -57,6 +57,7 @@ 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/rust-analyzer/src/lsp/to_proto.rs b/crates/rust-analyzer/src/lsp/to_proto.rs index 4f9a026aa1..753ae167df 100644 --- a/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/crates/rust-analyzer/src/lsp/to_proto.rs @@ -442,13 +442,15 @@ pub(crate) fn inlay_hint( file_id: FileId, inlay_hint: InlayHint, ) -> Cancellable { - let (label, tooltip) = inlay_hint_label(snap, fields_to_resolve, inlay_hint.label)?; - let data = if fields_to_resolve.can_resolve() { + let needs_resolve = inlay_hint.needs_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()) } else { None }; - let text_edits = if fields_to_resolve.resolve_text_edits { + let text_edits = if needs_resolve && fields_to_resolve.resolve_text_edits { None } else { 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( snap: &GlobalStateSnapshot, fields_to_resolve: &InlayFieldsToResolve, + needs_resolve: bool, mut label: InlayHintLabel, ) -> Cancellable<(lsp_types::InlayHintLabel, Option)> { let res = match &*label.parts { [InlayHintLabelPart { linked_location: None, .. }] => { 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 } else { match tooltip { @@ -504,7 +507,7 @@ fn inlay_hint_label( .parts .into_iter() .map(|part| { - let tooltip = if fields_to_resolve.resolve_label_tooltip { + let tooltip = if needs_resolve && fields_to_resolve.resolve_label_tooltip { None } else { match part.tooltip { @@ -522,7 +525,7 @@ fn inlay_hint_label( None => None, } }; - let location = if fields_to_resolve.resolve_label_location { + let location = if needs_resolve && fields_to_resolve.resolve_label_location { None } else { part.linked_location.map(|range| location(snap, range)).transpose()?