Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #13946 - Veykril:inlay-hints, r=Veykril
Remove hover inlay tooltips, replace them with location links Turns out we re-implemented what clients can already figure out through the use of location-links. We might want lazy resolves tooltips later on still, but for now this simplifies things again.
bors 2023-01-14
parent 32be158 · parent f2444b2 · commit ce6955c
-rw-r--r--Cargo.lock1
-rw-r--r--crates/ide/Cargo.toml1
-rw-r--r--crates/ide/src/inlay_hints.rs117
-rw-r--r--crates/ide/src/inlay_hints/adjustment.rs49
-rw-r--r--crates/ide/src/inlay_hints/bind_pat.rs34
-rw-r--r--crates/ide/src/inlay_hints/binding_mode.rs26
-rw-r--r--crates/ide/src/inlay_hints/chaining.rs192
-rw-r--r--crates/ide/src/inlay_hints/closing_brace.rs9
-rw-r--r--crates/ide/src/inlay_hints/closure_ret.rs7
-rw-r--r--crates/ide/src/inlay_hints/discriminant.rs25
-rw-r--r--crates/ide/src/inlay_hints/fn_lifetime_fn.rs11
-rw-r--r--crates/ide/src/inlay_hints/implicit_static.rs5
-rw-r--r--crates/ide/src/inlay_hints/param_name.rs11
-rw-r--r--crates/ide/src/lib.rs3
-rw-r--r--crates/rust-analyzer/src/handlers.rs50
-rw-r--r--crates/rust-analyzer/src/lsp_ext.rs7
-rw-r--r--crates/rust-analyzer/src/to_proto.rs203
-rw-r--r--docs/dev/lsp-extensions.md2
18 files changed, 282 insertions, 471 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5f426d8856..13d8d40ddd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -645,6 +645,7 @@ dependencies = [
"profile",
"pulldown-cmark",
"pulldown-cmark-to-cmark",
+ "smallvec",
"stdx",
"syntax",
"test-utils",
diff --git a/crates/ide/Cargo.toml b/crates/ide/Cargo.toml
index 73f202630f..397383bc3a 100644
--- a/crates/ide/Cargo.toml
+++ b/crates/ide/Cargo.toml
@@ -20,6 +20,7 @@ pulldown-cmark-to-cmark = "10.0.4"
pulldown-cmark = { version = "0.9.1", default-features = false }
url = "2.3.1"
dot = "0.1.4"
+smallvec = "1.10.0"
stdx = { path = "../stdx", version = "0.0.0" }
syntax = { path = "../syntax", version = "0.0.0" }
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 48a7bbfecf..861bf1c66c 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -7,10 +7,11 @@ use either::Either;
use hir::{known, HasVisibility, HirDisplay, HirWrite, ModuleDef, ModuleDefId, Semantics};
use ide_db::{base_db::FileRange, famous_defs::FamousDefs, RootDatabase};
use itertools::Itertools;
+use smallvec::{smallvec, SmallVec};
use stdx::never;
use syntax::{
ast::{self, AstNode},
- match_ast, NodeOrToken, SyntaxNode, TextRange, TextSize,
+ match_ast, NodeOrToken, SyntaxNode, TextRange,
};
use crate::{navigation_target::TryToNav, FileId};
@@ -83,75 +84,108 @@ pub enum AdjustmentHintsMode {
PreferPostfix,
}
-#[derive(Clone, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum InlayKind {
- BindingModeHint,
- ChainingHint,
- ClosingBraceHint,
- ClosureReturnTypeHint,
- GenericParamListHint,
- AdjustmentHint,
- AdjustmentHintPostfix,
- LifetimeHint,
- ParameterHint,
- TypeHint,
- DiscriminantHint,
+ BindingMode,
+ Chaining,
+ ClosingBrace,
+ ClosureReturnType,
+ GenericParamList,
+ Adjustment,
+ AdjustmentPostfix,
+ Lifetime,
+ Parameter,
+ Type,
+ Discriminant,
OpeningParenthesis,
ClosingParenthesis,
}
#[derive(Debug)]
pub struct InlayHint {
+ /// The text range this inlay hint applies to.
pub range: TextRange,
+ /// The kind of this inlay hint. This is used to determine side and padding of the hint for
+ /// rendering purposes.
pub kind: InlayKind,
+ /// The actual label to show in the inlay hint.
pub label: InlayHintLabel,
- pub tooltip: Option<InlayTooltip>,
+}
+
+impl InlayHint {
+ fn closing_paren(range: TextRange) -> InlayHint {
+ InlayHint { range, kind: InlayKind::ClosingParenthesis, label: InlayHintLabel::from(")") }
+ }
+ fn opening_paren(range: TextRange) -> InlayHint {
+ InlayHint { range, kind: InlayKind::OpeningParenthesis, label: InlayHintLabel::from("(") }
+ }
}
#[derive(Debug)]
pub enum InlayTooltip {
String(String),
- HoverRanged(FileId, TextRange),
- HoverOffset(FileId, TextSize),
+ Markdown(String),
}
#[derive(Default)]
pub struct InlayHintLabel {
- pub parts: Vec<InlayHintLabelPart>,
+ pub parts: SmallVec<[InlayHintLabelPart; 1]>,
}
impl InlayHintLabel {
- pub fn as_simple_str(&self) -> Option<&str> {
- match &*self.parts {
- [part] => part.as_simple_str(),
- _ => None,
+ pub fn simple(
+ s: impl Into<String>,
+ tooltip: Option<InlayTooltip>,
+ linked_location: Option<FileRange>,
+ ) -> InlayHintLabel {
+ InlayHintLabel {
+ parts: smallvec![InlayHintLabelPart { text: s.into(), linked_location, tooltip }],
}
}
pub fn prepend_str(&mut self, s: &str) {
match &mut *self.parts {
- [part, ..] if part.as_simple_str().is_some() => part.text = format!("{s}{}", part.text),
- _ => self.parts.insert(0, InlayHintLabelPart { text: s.into(), linked_location: None }),
+ [InlayHintLabelPart { text, linked_location: None, tooltip: None }, ..] => {
+ text.insert_str(0, s)
+ }
+ _ => self.parts.insert(
+ 0,
+ InlayHintLabelPart { text: s.into(), linked_location: None, tooltip: None },
+ ),
}
}
pub fn append_str(&mut self, s: &str) {
match &mut *self.parts {
- [.., part] if part.as_simple_str().is_some() => part.text.push_str(s),
- _ => self.parts.push(InlayHintLabelPart { text: s.into(), linked_location: None }),
+ [.., InlayHintLabelPart { text, linked_location: None, tooltip: None }] => {
+ text.push_str(s)
+ }
+ _ => self.parts.push(InlayHintLabelPart {
+ text: s.into(),
+ linked_location: None,
+ tooltip: None,
+ }),
}
}
}
impl From<String> for InlayHintLabel {
fn from(s: String) -> Self {
- Self { parts: vec![InlayHintLabelPart { text: s, linked_location: None }] }
+ Self {
+ parts: smallvec![InlayHintLabelPart { text: s, linked_location: None, tooltip: None }],
+ }
}
}
impl From<&str> for InlayHintLabel {
fn from(s: &str) -> Self {
- Self { parts: vec![InlayHintLabelPart { text: s.into(), linked_location: None }] }
+ Self {
+ parts: smallvec![InlayHintLabelPart {
+ text: s.into(),
+ linked_location: None,
+ tooltip: None
+ }],
+ }
}
}
@@ -175,25 +209,25 @@ pub struct InlayHintLabelPart {
/// When setting this, no tooltip must be set on the containing hint, or VS Code will display
/// them both.
pub linked_location: Option<FileRange>,
-}
-
-impl InlayHintLabelPart {
- pub fn as_simple_str(&self) -> Option<&str> {
- match self {
- Self { text, linked_location: None } => Some(text),
- _ => None,
- }
- }
+ /// The tooltip to show when hovering over the inlay hint, this may invoke other actions like
+ /// hover requests to show.
+ pub tooltip: Option<InlayTooltip>,
}
impl fmt::Debug for InlayHintLabelPart {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self.as_simple_str() {
- Some(string) => string.fmt(f),
- None => f
+ match self {
+ Self { text, linked_location: None, tooltip: None } => text.fmt(f),
+ Self { text, linked_location, tooltip } => f
.debug_struct("InlayHintLabelPart")
- .field("text", &self.text)
- .field("linked_location", &self.linked_location)
+ .field("text", text)
+ .field("linked_location", linked_location)
+ .field(
+ "tooltip",
+ &tooltip.as_ref().map_or("", |it| match it {
+ InlayTooltip::String(it) | InlayTooltip::Markdown(it) => it,
+ }),
+ )
.finish(),
}
}
@@ -242,6 +276,7 @@ impl InlayHintLabelBuilder<'_> {
self.result.parts.push(InlayHintLabelPart {
text: take(&mut self.last_part),
linked_location: self.location.take(),
+ tooltip: None,
});
}
diff --git a/crates/ide/src/inlay_hints/adjustment.rs b/crates/ide/src/inlay_hints/adjustment.rs
index bdd7c05e00..581813f3b7 100644
--- a/crates/ide/src/inlay_hints/adjustment.rs
+++ b/crates/ide/src/inlay_hints/adjustment.rs
@@ -44,27 +44,12 @@ pub(super) fn hints(
mode_and_needs_parens_for_adjustment_hints(expr, config.adjustment_hints_mode);
if needs_outer_parens {
- acc.push(InlayHint {
- range: expr.syntax().text_range(),
- kind: InlayKind::OpeningParenthesis,
- label: "(".into(),
- tooltip: None,
- });
+ acc.push(InlayHint::opening_paren(expr.syntax().text_range()));
}
if postfix && needs_inner_parens {
- acc.push(InlayHint {
- range: expr.syntax().text_range(),
- kind: InlayKind::OpeningParenthesis,
- label: "(".into(),
- tooltip: None,
- });
- acc.push(InlayHint {
- range: expr.syntax().text_range(),
- kind: InlayKind::ClosingParenthesis,
- label: ")".into(),
- tooltip: None,
- });
+ acc.push(InlayHint::opening_paren(expr.syntax().text_range()));
+ acc.push(InlayHint::closing_paren(expr.syntax().text_range()));
}
let (mut tmp0, mut tmp1);
@@ -112,36 +97,16 @@ pub(super) fn hints(
};
acc.push(InlayHint {
range: expr.syntax().text_range(),
- kind: if postfix {
- InlayKind::AdjustmentHintPostfix
- } else {
- InlayKind::AdjustmentHint
- },
+ kind: if postfix { InlayKind::AdjustmentPostfix } else { InlayKind::Adjustment },
label: if postfix { format!(".{}", text.trim_end()).into() } else { text.into() },
- tooltip: None,
});
}
if !postfix && needs_inner_parens {
- acc.push(InlayHint {
- range: expr.syntax().text_range(),
- kind: InlayKind::OpeningParenthesis,
- label: "(".into(),
- tooltip: None,
- });
- acc.push(InlayHint {
- range: expr.syntax().text_range(),
- kind: InlayKind::ClosingParenthesis,
- label: ")".into(),
- tooltip: None,
- });
+ acc.push(InlayHint::opening_paren(expr.syntax().text_range()));
+ acc.push(InlayHint::closing_paren(expr.syntax().text_range()));
}
if needs_outer_parens {
- acc.push(InlayHint {
- range: expr.syntax().text_range(),
- kind: InlayKind::ClosingParenthesis,
- label: ")".into(),
- tooltip: None,
- });
+ acc.push(InlayHint::closing_paren(expr.syntax().text_range()));
}
Some(())
}
diff --git a/crates/ide/src/inlay_hints/bind_pat.rs b/crates/ide/src/inlay_hints/bind_pat.rs
index adec19c765..5227c651ff 100644
--- a/crates/ide/src/inlay_hints/bind_pat.rs
+++ b/crates/ide/src/inlay_hints/bind_pat.rs
@@ -12,9 +12,7 @@ use syntax::{
match_ast,
};
-use crate::{
- inlay_hints::closure_has_block_body, InlayHint, InlayHintsConfig, InlayKind, InlayTooltip,
-};
+use crate::{inlay_hints::closure_has_block_body, InlayHint, InlayHintsConfig, InlayKind};
use super::label_of_ty;
@@ -22,7 +20,7 @@ pub(super) fn hints(
acc: &mut Vec<InlayHint>,
famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>,
config: &InlayHintsConfig,
- file_id: FileId,
+ _file_id: FileId,
pat: &ast::IdentPat,
) -> Option<()> {
if !config.type_hints {
@@ -50,12 +48,8 @@ pub(super) fn hints(
Some(name) => name.syntax().text_range(),
None => pat.syntax().text_range(),
},
- kind: InlayKind::TypeHint,
+ kind: InlayKind::Type,
label,
- tooltip: pat
- .name()
- .map(|it| it.syntax().text_range())
- .map(|it| InlayTooltip::HoverRanged(file_id, it)),
});
Some(())
@@ -322,22 +316,14 @@ fn main(a: SliceIter<'_, Container>) {
[
InlayHint {
range: 484..554,
- kind: ChainingHint,
+ kind: Chaining,
label: [
"impl Iterator<Item = impl Iterator<Item = &&str>>",
],
- tooltip: Some(
- HoverRanged(
- FileId(
- 0,
- ),
- 484..554,
- ),
- ),
},
InlayHint {
range: 484..485,
- kind: ChainingHint,
+ kind: Chaining,
label: [
"",
InlayHintLabelPart {
@@ -350,6 +336,7 @@ fn main(a: SliceIter<'_, Container>) {
range: 289..298,
},
),
+ tooltip: "",
},
"<",
InlayHintLabelPart {
@@ -362,17 +349,10 @@ fn main(a: SliceIter<'_, Container>) {
range: 238..247,
},
),
+ tooltip: "",
},
">",
],
- tooltip: Some(
- HoverRanged(
- FileId(
- 0,
- ),
- 484..485,
- ),
- ),
},
]
"#]],
diff --git a/crates/ide/src/inlay_hints/binding_mode.rs b/crates/ide/src/inlay_hints/binding_mode.rs
index a0166d0048..11b9cd269b 100644
--- a/crates/ide/src/inlay_hints/binding_mode.rs
+++ b/crates/ide/src/inlay_hints/binding_mode.rs
@@ -7,7 +7,7 @@ use ide_db::RootDatabase;
use syntax::ast::{self, AstNode};
-use crate::{InlayHint, InlayHintsConfig, InlayKind, InlayTooltip};
+use crate::{InlayHint, InlayHintsConfig, InlayKind};
pub(super) fn hints(
acc: &mut Vec<InlayHint>,
@@ -40,12 +40,7 @@ pub(super) fn hints(
(true, false) => "&",
_ => return,
};
- acc.push(InlayHint {
- range,
- kind: InlayKind::BindingModeHint,
- label: r.to_string().into(),
- tooltip: Some(InlayTooltip::String("Inferred binding mode".into())),
- });
+ acc.push(InlayHint { range, kind: InlayKind::BindingMode, label: r.to_string().into() });
});
match pat {
ast::Pat::IdentPat(pat) if pat.ref_token().is_none() && pat.mut_token().is_none() => {
@@ -57,24 +52,13 @@ pub(super) fn hints(
};
acc.push(InlayHint {
range: pat.syntax().text_range(),
- kind: InlayKind::BindingModeHint,
+ kind: InlayKind::BindingMode,
label: bm.to_string().into(),
- tooltip: Some(InlayTooltip::String("Inferred binding mode".into())),
});
}
ast::Pat::OrPat(pat) if !pattern_adjustments.is_empty() && outer_paren_pat.is_none() => {
- acc.push(InlayHint {
- range: pat.syntax().text_range(),
- kind: InlayKind::OpeningParenthesis,
- label: "(".into(),
- tooltip: None,
- });
- acc.push(InlayHint {
- range: pat.syntax().text_range(),
- kind: InlayKind::ClosingParenthesis,
- label: ")".into(),
- tooltip: None,
- });
+ acc.push(InlayHint::opening_paren(pat.syntax().text_range()));
+ acc.push(InlayHint::closing_paren(pat.syntax().text_range()));
}
_ => (),
}
diff --git a/crates/ide/src/inlay_hints/chaining.rs b/crates/ide/src/inlay_hints/chaining.rs
index 8810d5d34d..e0045a53d7 100644
--- a/crates/ide/src/inlay_hints/chaining.rs
+++ b/crates/ide/src/inlay_hints/chaining.rs
@@ -5,7 +5,7 @@ use syntax::{
Direction, NodeOrToken, SyntaxKind, T,
};
-use crate::{FileId, InlayHint, InlayHintsConfig, InlayKind, InlayTooltip};
+use crate::{FileId, InlayHint, InlayHintsConfig, InlayKind};
use super::label_of_ty;
@@ -13,7 +13,7 @@ pub(super) fn hints(
acc: &mut Vec<InlayHint>,
famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>,
config: &InlayHintsConfig,
- file_id: FileId,
+ _file_id: FileId,
expr: &ast::Expr,
) -> Option<()> {
if !config.chaining_hints {
@@ -59,9 +59,8 @@ pub(super) fn hints(
}
acc.push(InlayHint {
range: expr.syntax().text_range(),
- kind: InlayKind::ChainingHint,
+ kind: InlayKind::Chaining,
label: label_of_ty(famous_defs, config, ty)?,
- tooltip: Some(InlayTooltip::HoverRanged(file_id, expr.syntax().text_range())),
});
}
}
@@ -111,7 +110,7 @@ fn main() {
[
InlayHint {
range: 147..172,
- kind: ChainingHint,
+ kind: Chaining,
label: [
"",
InlayHintLabelPart {
@@ -124,21 +123,14 @@ fn main() {
range: 63..64,
},
),
+ tooltip: "",
},
"",
],
- tooltip: Some(
- HoverRanged(
- FileId(
- 0,
- ),
- 147..172,
- ),
- ),
},
InlayHint {
range: 147..154,
- kind: ChainingHint,
+ kind: Chaining,
label: [
"",
InlayHintLabelPart {
@@ -151,17 +143,10 @@ fn main() {
range: 7..8,
},
),
+ tooltip: "",
},
"",
],
- tooltip: Some(
- HoverRanged(
- FileId(
- 0,
- ),
- 147..154,
- ),
- ),
},
]
"#]],
@@ -210,33 +195,17 @@ fn main() {
[
InlayHint {
range: 143..190,
- kind: ChainingHint,
+ kind: Chaining,
label: [
"C",
],
- tooltip: Some(
- HoverRanged(
- FileId(
- 0,
- ),
- 143..190,
- ),
- ),
},
InlayHint {
range: 143..179,
- kind: ChainingHint,
+ kind: Chaining,
label: [
"B",
],
- tooltip: Some(
- HoverRanged(
- FileId(
- 0,
- ),
- 143..179,
- ),
- ),
},
]
"#]],
@@ -269,7 +238,7 @@ fn main() {
[
InlayHint {
range: 143..190,
- kind: ChainingHint,
+ kind: Chaining,
label: [
"",
InlayHintLabelPart {
@@ -282,21 +251,14 @@ fn main() {
range: 51..52,
},
),
+ tooltip: "",
},
"",
],
- tooltip: Some(
- HoverRanged(
- FileId(
- 0,
- ),
- 143..190,
- ),
- ),
},
InlayHint {
range: 143..179,
- kind: ChainingHint,
+ kind: Chaining,
label: [
"",
InlayHintLabelPart {
@@ -309,17 +271,10 @@ fn main() {
range: 29..30,
},
),
+ tooltip: "",
},
"",
],
- tooltip: Some(
- HoverRanged(
- FileId(
- 0,
- ),
- 143..179,
- ),
- ),
},
]
"#]],
@@ -353,7 +308,7 @@ fn main() {
[
InlayHint {
range: 246..283,
- kind: ChainingHint,
+ kind: Chaining,
label: [
"",
InlayHintLabelPart {
@@ -366,6 +321,7 @@ fn main() {
range: 23..24,
},
),
+ tooltip: "",
},
"<",
InlayHintLabelPart {
@@ -378,21 +334,14 @@ fn main() {
range: 55..56,
},
),
+ tooltip: "",
},
"<i32, bool>>",
],
- tooltip: Some(
- HoverRanged(
- FileId(
- 0,
- ),
- 246..283,
- ),
- ),
},
InlayHint {
range: 246..265,
- kind: ChainingHint,
+ kind: Chaining,
label: [
"",
InlayHintLabelPart {
@@ -405,6 +354,7 @@ fn main() {
range: 7..8,
},
),
+ tooltip: "",
},
"<",
InlayHintLabelPart {
@@ -417,17 +367,10 @@ fn main() {
range: 55..56,
},
),
+ tooltip: "",
},
"<i32, bool>>",
],
- tooltip: Some(
- HoverRanged(
- FileId(
- 0,
- ),
- 246..265,
- ),
- ),
},
]
"#]],
@@ -463,52 +406,28 @@ fn main() {
[
InlayHint {
range: 174..241,
- kind: ChainingHint,
+ kind: Chaining,
label: [
"impl Iterator<Item = ()>",
],
- tooltip: Some(
- HoverRanged(
- FileId(
- 0,
- ),
- 174..241,
- ),
- ),
},
InlayHint {
range: 174..224,
- kind: ChainingHint,
+ kind: Chaining,
label: [
"impl Iterator<Item = ()>",
],
- tooltip: Some(
- HoverRanged(
- FileId(
- 0,
- ),
- 174..224,
- ),
- ),
},
InlayHint {
range: 174..206,
- kind: ChainingHint,
+ kind: Chaining,
label: [
"impl Iterator<Item = ()>",
],
- tooltip: Some(
- HoverRanged(
- FileId(
- 0,
- ),
- 174..206,
- ),
- ),
},
InlayHint {
range: 174..189,
- kind: ChainingHint,
+ kind: Chaining,
label: [
"&mut ",
InlayHintLabelPart {
@@ -521,17 +440,10 @@ fn main() {
range: 24..30,
},
),
+ tooltip: "",
},
"",
],
- tooltip: Some(
- HoverRanged(
- FileId(
- 0,
- ),
- 174..189,
- ),
- ),
},
]
"#]],
@@ -564,7 +476,7 @@ fn main() {
[
InlayHint {
range: 124..130,
- kind: TypeHint,
+ kind: Type,
label: [
"",
InlayHintLabelPart {
@@ -577,21 +489,14 @@ fn main() {
range: 7..13,
},
),
+ tooltip: "",
},
"",
],
- tooltip: Some(
- HoverRanged(
- FileId(
- 0,
- ),
- 124..130,
- ),
- ),
},
InlayHint {
range: 145..185,
- kind: ChainingHint,
+ kind: Chaining,
label: [
"",
InlayHintLabelPart {
@@ -604,21 +509,14 @@ fn main() {
range: 7..13,
},
),
+ tooltip: "",
},
"",
],
- tooltip: Some(
- HoverRanged(
- FileId(
- 0,
- ),
- 145..185,
- ),
- ),
},
InlayHint {
range: 145..168,
- kind: ChainingHint,
+ kind: Chaining,
label: [
"",
InlayHintLabelPart {
@@ -631,32 +529,28 @@ fn main() {
range: 7..13,
},
),
+ tooltip: "",
},
"",
],
- tooltip: Some(
- HoverRanged(
- FileId(
- 0,
- ),
- 145..168,
- ),
- ),
},
InlayHint {
range: 222..228,
- kind: ParameterHint,
+ kind: Parameter,
label: [
- "self",
- ],
- tooltip: Some(
- HoverOffset(
- FileId(
- 0,
+ InlayHintLabelPart {
+ text: "self",
+ linked_location: Some(
+ FileRange {
+ file_id: FileId(
+ 0,
+ ),
+ range: 42..46,
+ },
),
- 42,
- ),
- ),
+ tooltip: "",
+ },
+ ],
},
]
"#]],
diff --git a/crates/ide/src/inlay_hints/closing_brace.rs b/crates/ide/src/inlay_hints/closing_brace.rs
index e340c64c54..aae805f78d 100644
--- a/crates/ide/src/inlay_hints/closing_brace.rs
+++ b/crates/ide/src/inlay_hints/closing_brace.rs
@@ -10,9 +10,7 @@ use syntax::{
match_ast, SyntaxKind, SyntaxNode, T,
};
-use crate::{
- inlay_hints::InlayHintLabelPart, FileId, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind,
-};
+use crate::{FileId, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind};
pub(super) fn hints(
acc: &mut Vec<InlayHint>,
@@ -115,9 +113,8 @@ pub(super) fn hints(
.flatten();
acc.push(InlayHint {
range: closing_token.text_range(),
- kind: InlayKind::ClosingBraceHint,
- label: InlayHintLabel { parts: vec![InlayHintLabelPart { text: label, linked_location }] },
- tooltip: None, // provided by label part location
+ kind: InlayKind::ClosingBrace,
+ label: InlayHintLabel::simple(label, None, linked_location),
});
None
diff --git a/crates/ide/src/inlay_hints/closure_ret.rs b/crates/ide/src/inlay_hints/closure_ret.rs
index d9929beaac..f03a18b8e9 100644
--- a/crates/ide/src/inlay_hints/closure_ret.rs
+++ b/crates/ide/src/inlay_hints/closure_ret.rs
@@ -4,7 +4,7 @@ use syntax::ast::{self, AstNode};
use crate::{
inlay_hints::closure_has_block_body, ClosureReturnTypeHints, InlayHint, InlayHintsConfig,
- InlayKind, InlayTooltip,
+ InlayKind,
};
use super::label_of_ty;
@@ -13,7 +13,7 @@ pub(super) fn hints(
acc: &mut Vec<InlayHint>,
famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>,
config: &InlayHintsConfig,
- file_id: FileId,
+ _file_id: FileId,
closure: ast::ClosureExpr,
) -> Option<()> {
if config.closure_return_type_hints == ClosureReturnTypeHints::Never {
@@ -41,9 +41,8 @@ pub(super) fn hints(
}
acc.push(InlayHint {
range: param_list.syntax().text_range(),
- kind: InlayKind::ClosureReturnTypeHint,
+ kind: InlayKind::ClosureReturnType,
label: label_of_ty(famous_defs, config, ty)?,
- tooltip: Some(InlayTooltip::HoverRanged(file_id, param_list.syntax().text_range())),
});
Some(())
}
diff --git a/crates/ide/src/inlay_hints/discriminant.rs b/crates/ide/src/inlay_hints/discriminant.rs
index f32c4bdf28..310295cc37 100644
--- a/crates/ide/src/inlay_hints/discriminant.rs
+++ b/crates/ide/src/inlay_hints/discriminant.rs
@@ -7,7 +7,9 @@
use ide_db::{base_db::FileId, famous_defs::FamousDefs};
use syntax::ast::{self, AstNode, HasName};
-use crate::{DiscriminantHints, InlayHint, InlayHintsConfig, InlayKind, InlayTooltip};
+use crate::{
+ DiscriminantHints, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind, InlayTooltip,
+};
pub(super) fn hints(
acc: &mut Vec<InlayHint>,
@@ -41,15 +43,18 @@ pub(super) fn hints(
Some(field_list) => name.syntax().text_range().cover(field_list.syntax().text_range()),
None => name.syntax().text_range(),
},
- kind: InlayKind::DiscriminantHint,
- label: match &d {
- Ok(v) => format!("{}", v).into(),
- Err(_) => "?".into(),
- },
- tooltip: Some(InlayTooltip::String(match &d {
- Ok(_) => "enum variant discriminant".into(),
- Err(e) => format!("{e:?}").into(),
- })),
+ kind: InlayKind::Discriminant,
+ label: InlayHintLabel::simple(
+ match &d {
+ Ok(v) => format!("{}", v),
+ Err(_) => "?".into(),
+ },
+ Some(InlayTooltip::String(match &d {
+ Ok(_) => "enum variant discriminant".into(),
+ Err(e) => format!("{e:?}").into(),
+ })),
+ None,
+ ),
});
Some(())
diff --git a/crates/ide/src/inlay_hints/fn_lifetime_fn.rs b/crates/ide/src/inlay_hints/fn_lifetime_fn.rs
index 2aa5e3dc73..b7182085b3 100644
--- a/crates/ide/src/inlay_hints/fn_lifetime_fn.rs
+++ b/crates/ide/src/inlay_hints/fn_lifetime_fn.rs
@@ -10,7 +10,7 @@ use syntax::{
SyntaxToken,
};
-use crate::{InlayHint, InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints};
+use crate::{InlayHint, InlayHintsConfig, InlayKind, LifetimeElisionHints};
pub(super) fn hints(
acc: &mut Vec<InlayHint>,
@@ -23,9 +23,8 @@ pub(super) fn hints(
let mk_lt_hint = |t: SyntaxToken, label: String| InlayHint {
range: t.text_range(),
- kind: InlayKind::LifetimeHint,
+ kind: InlayKind::Lifetime,
label: label.into(),
- tooltip: Some(InlayTooltip::String("Elided lifetime".into())),
};
let param_list = func.param_list()?;
@@ -183,21 +182,19 @@ pub(super) fn hints(
let is_empty = gpl.generic_params().next().is_none();
acc.push(InlayHint {
range: angle_tok.text_range(),
- kind: InlayKind::LifetimeHint,
+ kind: InlayKind::Lifetime,
label: format!(
"{}{}",
allocated_lifetimes.iter().format(", "),
if is_empty { "" } else { ", " }
)
.into(),
- tooltip: Some(InlayTooltip::String("Elided lifetimes".into())),
});
}
(None, allocated_lifetimes) => acc.push(InlayHint {
range: func.name()?.syntax().text_range(),
- kind: InlayKind::GenericParamListHint,
+ kind: InlayKind::GenericParamList,
label: format!("<{}>", allocated_lifetimes.iter().format(", "),).into(),
- tooltip: Some(InlayTooltip::String("Elided lifetimes".into())),
}),
}
Some(())
diff --git a/crates/ide/src/inlay_hints/implicit_static.rs b/crates/ide/src/inlay_hints/implicit_static.rs
index 588a0e3b6a..1122ee2e39 100644
--- a/crates/ide/src/inlay_hints/implicit_static.rs
+++ b/crates/ide/src/inlay_hints/implicit_static.rs
@@ -8,7 +8,7 @@ use syntax::{
SyntaxKind,
};
-use crate::{InlayHint, InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints};
+use crate::{InlayHint, InlayHintsConfig, InlayKind, LifetimeElisionHints};
pub(super) fn hints(
acc: &mut Vec<InlayHint>,
@@ -32,9 +32,8 @@ pub(super) fn hints(
let t = ty.amp_token()?;
acc.push(InlayHint {
range: t.text_range(),
- kind: InlayKind::LifetimeHint,
+ kind: InlayKind::Lifetime,
label: "'static".to_owned().into(),
- tooltip: Some(InlayTooltip::String("Elided static lifetime".into())),
});
}
}
diff --git a/crates/ide/src/inlay_hints/param_name.rs b/crates/ide/src/inlay_hints/param_name.rs
index ecee67632e..9cdae63241 100644
--- a/crates/ide/src/inlay_hints/param_name.rs
+++ b/crates/ide/src/inlay_hints/param_name.rs
@@ -10,7 +10,7 @@ use ide_db::{base_db::FileRange, RootDatabase};
use stdx::to_lower_snake_case;
use syntax::ast::{self, AstNode, HasArgList, HasName, UnaryOp};
-use crate::{InlayHint, InlayHintsConfig, InlayKind, InlayTooltip};
+use crate::{InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind};
pub(super) fn hints(
acc: &mut Vec<InlayHint>,
@@ -43,21 +43,20 @@ pub(super) fn hints(
!should_hide_param_name_hint(sema, &callable, param_name, arg)
})
.map(|(param, param_name, _, FileRange { range, .. })| {
- let mut tooltip = None;
+ let mut linked_location = None;
if let Some(name) = param {
if let hir::CallableKind::Function(f) = callable.kind() {
// assert the file is cached so we can map out of macros
if let Some(_) = sema.source(f) {
- tooltip = sema.original_range_opt(name.syntax());
+ linked_location = sema.original_range_opt(name.syntax());
}
}
}
InlayHint {
range,
- kind: InlayKind::ParameterHint,
- label: param_name.into(),
- tooltip: tooltip.map(|it| InlayTooltip::HoverOffset(it.file_id, it.range.start())),
+ kind: InlayKind::Parameter,
+ label: InlayHintLabel::simple(param_name, None, linked_location),
}
});
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index 239456cb28..8424d82aa1 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -82,7 +82,8 @@ pub use crate::{
hover::{HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult},
inlay_hints::{
AdjustmentHints, AdjustmentHintsMode, ClosureReturnTypeHints, DiscriminantHints, InlayHint,
- InlayHintLabel, InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints,
+ InlayHintLabel, InlayHintLabelPart, InlayHintsConfig, InlayKind, InlayTooltip,
+ LifetimeElisionHints,
},
join_lines::JoinLinesConfig,
markup::Markup,
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 59bdd30612..033ef75cca 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -29,7 +29,6 @@ use project_model::{ManifestPath, ProjectWorkspace, TargetKind};
use serde_json::json;
use stdx::{format_to, never};
use syntax::{algo, ast, AstNode, TextRange, TextSize};
-use tracing::error;
use vfs::AbsPathBuf;
use crate::{
@@ -1360,55 +1359,10 @@ pub(crate) fn handle_inlay_hints(
}
pub(crate) fn handle_inlay_hints_resolve(
- snap: GlobalStateSnapshot,
- mut hint: InlayHint,
+ _snap: GlobalStateSnapshot,
+ hint: InlayHint,
) -> Result<InlayHint> {
let _p = profile::span("handle_inlay_hints_resolve");
- let data = match hint.data.take() {
- Some(it) => it,
- None => return Ok(hint),
- };
-
- let resolve_data: lsp_ext::InlayHintResolveData = serde_json::from_value(data)?;
-
- match snap.url_file_version(&resolve_data.text_document.uri) {
- Some(version) if version == resolve_data.text_document.version => {}
- Some(version) => {
- error!(
- "attempted inlayHints/resolve of '{}' at version {} while server version is {}",
- resolve_data.text_document.uri, resolve_data.text_document.version, version,
- );
- return Ok(hint);
- }
- None => {
- error!(
- "attempted inlayHints/resolve of unknown file '{}' at version {}",
- resolve_data.text_document.uri, resolve_data.text_document.version,
- );
- return Ok(hint);
- }
- }
- let file_range = from_proto::file_range_uri(
- &snap,
- &resolve_data.text_document.uri,
- match resolve_data.position {
- PositionOrRange::Position(pos) => Range::new(pos, pos),
- PositionOrRange::Range(range) => range,
- },
- )?;
- let info = match snap.analysis.hover(&snap.config.hover(), file_range)? {
- None => return Ok(hint),
- Some(info) => info,
- };
-
- let markup_kind =
- snap.config.hover().documentation.map_or(ide::HoverDocFormat::Markdown, |kind| kind);
-
- // FIXME: hover actions?
- hint.tooltip = Some(lsp_types::InlayHintTooltip::MarkupContent(to_proto::markup_content(
- info.info.markup,
- markup_kind,
- )));
Ok(hint)
}
diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs
index 65620b4209..b117acd1b0 100644
--- a/crates/rust-analyzer/src/lsp_ext.rs
+++ b/crates/rust-analyzer/src/lsp_ext.rs
@@ -3,11 +3,11 @@
use std::{collections::HashMap, path::PathBuf};
use lsp_types::request::Request;
+use lsp_types::PositionEncodingKind;
use lsp_types::{
notification::Notification, CodeActionKind, DocumentOnTypeFormattingParams,
PartialResultParams, Position, Range, TextDocumentIdentifier, WorkDoneProgressParams,
};
-use lsp_types::{PositionEncodingKind, VersionedTextDocumentIdentifier};
use serde::{Deserialize, Serialize};
pub enum AnalyzerStatus {}
@@ -568,10 +568,7 @@ pub struct CompletionResolveData {
}
#[derive(Debug, Serialize, Deserialize)]
-pub struct InlayHintResolveData {
- pub text_document: VersionedTextDocumentIdentifier,
- pub position: PositionOrRange,
-}
+pub struct InlayHintResolveData {}
#[derive(Debug, Serialize, Deserialize)]
pub struct CompletionImport {
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index e736b2ff9a..0f0642bb4b 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -9,9 +9,9 @@ use ide::{
Annotation, AnnotationKind, Assist, AssistKind, Cancellable, CompletionItem,
CompletionItemKind, CompletionRelevance, Documentation, FileId, FileRange, FileSystemEdit,
Fold, FoldKind, Highlight, HlMod, HlOperator, HlPunct, HlRange, HlTag, Indel, InlayHint,
- InlayHintLabel, InlayKind, Markup, NavigationTarget, ReferenceCategory, RenameError, Runnable,
- Severity, SignatureHelp, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange,
- TextSize,
+ InlayHintLabel, InlayHintLabelPart, InlayKind, Markup, NavigationTarget, ReferenceCategory,
+ RenameError, Runnable, Severity, SignatureHelp, SourceChange, StructureNodeKind, SymbolKind,
+ TextEdit, TextRange, TextSize,
};
use itertools::Itertools;
use serde_json::to_value;
@@ -431,137 +431,140 @@ pub(crate) fn inlay_hint(
mut inlay_hint: InlayHint,
) -> Cancellable<lsp_types::InlayHint> {
match inlay_hint.kind {
- InlayKind::ParameterHint if render_colons => inlay_hint.label.append_str(":"),
- InlayKind::TypeHint if render_colons => inlay_hint.label.prepend_str(": "),
- InlayKind::ClosureReturnTypeHint => inlay_hint.label.prepend_str(" -> "),
- InlayKind::DiscriminantHint => inlay_hint.label.prepend_str(" = "),
+ InlayKind::Parameter if render_colons => inlay_hint.label.append_str(":"),
+ InlayKind::Type if render_colons => inlay_hint.label.prepend_str(": "),
+ InlayKind::ClosureReturnType => inlay_hint.label.prepend_str(" -> "),
+ InlayKind::Discriminant => inlay_hint.label.prepend_str(" = "),
_ => {}
}
+ let (label, tooltip) = inlay_hint_label(snap, inlay_hint.label)?;
+
Ok(lsp_types::InlayHint {
position: match inlay_hint.kind {
// before annotated thing
InlayKind::OpeningParenthesis
- | InlayKind::ParameterHint
- | InlayKind::AdjustmentHint
- | InlayKind::BindingModeHint => position(line_index, inlay_hint.range.start()),
+ | InlayKind::Parameter
+ | InlayKind::Adjustment
+ | InlayKind::BindingMode => position(line_index, inlay_hint.range.start()),
// after annotated thing
- InlayKind::ClosureReturnTypeHint
- | InlayKind::TypeHint
- | InlayKind::DiscriminantHint
- | InlayKind::ChainingHint
- | InlayKind::GenericParamListHint
+ InlayKind::ClosureReturnType
+ | InlayKind::Type
+ | InlayKind::Discriminant
+ | InlayKind::Chaining
+ | InlayKind::GenericParamList
| InlayKind::ClosingParenthesis
- | InlayKind::AdjustmentHintPostfix
- | InlayKind::LifetimeHint
- | InlayKind::ClosingBraceHint => position(line_index, inlay_hint.range.end()),
+ | InlayKind::AdjustmentPostfix
+ | InlayKind::Lifetime
+ | InlayKind::ClosingBrace => position(line_index, inlay_hint.range.end()),
},
padding_left: Some(match inlay_hint.kind {
- InlayKind::TypeHint => !render_colons,
- InlayKind::ChainingHint | InlayKind::ClosingBraceHint => true,
+ InlayKind::Type => !render_colons,
+ InlayKind::Chaining | InlayKind::ClosingBrace => true,
InlayKind::ClosingParenthesis
- | InlayKind::DiscriminantHint
+ | InlayKind::Discriminant
| InlayKind::OpeningParenthesis
- | InlayKind::BindingModeHint
- | InlayKind::ClosureReturnTypeHint
- | InlayKind::GenericParamListHint
- | InlayKind::AdjustmentHint
- | InlayKind::AdjustmentHintPostfix
- | InlayKind::LifetimeHint
- | InlayKind::ParameterHint => false,
+ | InlayKind::BindingMode
+ | InlayKind::ClosureReturnType
+ | InlayKind::GenericParamList
+ | InlayKind::Adjustment
+ | InlayKind::AdjustmentPostfix
+ | InlayKind::Lifetime
+ | InlayKind::Parameter => false,
}),
padding_right: Some(match inlay_hint.kind {
InlayKind::ClosingParenthesis
| InlayKind::OpeningParenthesis
- | InlayKind::ChainingHint
- | InlayKind::ClosureReturnTypeHint
- | InlayKind::GenericParamListHint
- | InlayKind::AdjustmentHint
- | InlayKind::AdjustmentHintPostfix
- | InlayKind::TypeHint
- | InlayKind::DiscriminantHint
- | InlayKind::ClosingBraceHint => false,
- InlayKind::BindingModeHint => inlay_hint.label.as_simple_str() != Some("&"),
- InlayKind::ParameterHint | InlayKind::LifetimeHint => true,
+ | InlayKind::Chaining
+ | InlayKind::ClosureReturnType
+ | InlayKind::GenericParamList
+ | InlayKind::Adjustment
+ | InlayKind::AdjustmentPostfix
+ | InlayKind::Type
+ | InlayKind::Discriminant
+ | InlayKind::ClosingBrace => false,
+ InlayKind::BindingMode => {
+ matches!(&label, lsp_types::InlayHintLabel::String(s) if s != "&")
+ }
+ InlayKind::Parameter | InlayKind::Lifetime => true,
}),
kind: match inlay_hint.kind {
- InlayKind::ParameterHint => Some(lsp_types::InlayHintKind::PARAMETER),
- InlayKind::ClosureReturnTypeHint | InlayKind::TypeHint | InlayKind::ChainingHint => {
+ InlayKind::Parameter => Some(lsp_types::InlayHintKind::PARAMETER),
+ InlayKind::ClosureReturnType | InlayKind::Type | InlayKind::Chaining => {
Some(lsp_types::InlayHintKind::TYPE)
}
InlayKind::ClosingParenthesis
- | InlayKind::DiscriminantHint
+ | InlayKind::Discriminant
| InlayKind::OpeningParenthesis
- | InlayKind::BindingModeHint
- | InlayKind::GenericParamListHint
- | InlayKind::LifetimeHint
- | InlayKind::AdjustmentHint
- | InlayKind::AdjustmentHintPostfix
- | InlayKind::ClosingBraceHint => None,
+ | InlayKind::BindingMode
+ | InlayKind::GenericParamList
+ | InlayKind::Lifetime
+ | InlayKind::Adjustment
+ | InlayKind::AdjustmentPostfix
+ | InlayKind::ClosingBrace => None,
},
text_edits: None,
- data: (|| match inlay_hint.tooltip {
- Some(ide::InlayTooltip::HoverOffset(file_id, offset)) => {
- let uri = url(snap, file_id);
- let line_index = snap.file_line_index(file_id).ok()?;
-
- let text_document = lsp_types::VersionedTextDocumentIdentifier {
- version: snap.url_file_version(&uri)?,
- uri,
- };
- to_value(lsp_ext::InlayHintResolveData {
- text_document,
- position: lsp_ext::PositionOrRange::Position(position(&line_index, offset)),
- })
- .ok()
- }
- Some(ide::InlayTooltip::HoverRanged(file_id, text_range)) => {
- let uri = url(snap, file_id);
- let text_document = lsp_types::VersionedTextDocumentIdentifier {
- version: snap.url_file_version(&uri)?,
- uri,
- };
- let line_index = snap.file_line_index(file_id).ok()?;
- to_value(lsp_ext::InlayHintResolveData {
- text_document,
- position: lsp_ext::PositionOrRange::Range(range(&line_index, text_range)),
- })
- .ok()
- }
- _ => None,
- })(),
- tooltip: Some(match inlay_hint.tooltip {
- Some(ide::InlayTooltip::String(s)) => lsp_types::InlayHintTooltip::String(s),
- _ => lsp_types::InlayHintTooltip::String(inlay_hint.label.to_string()),
- }),
- label: inlay_hint_label(snap, inlay_hint.label)?,
+ data: None,
+ tooltip,
+ label,
})
}
fn inlay_hint_label(
snap: &GlobalStateSnapshot,
- label: InlayHintLabel,
-) -> Cancellable<lsp_types::InlayHintLabel> {
- Ok(match label.as_simple_str() {
- Some(s) => lsp_types::InlayHintLabel::String(s.into()),
- None => lsp_types::InlayHintLabel::LabelParts(
- label
+ mut label: InlayHintLabel,
+) -> Cancellable<(lsp_types::InlayHintLabel, Option<lsp_types::InlayHintTooltip>)> {
+ let res = match &*label.parts {
+ [InlayHintLabelPart { linked_location: None, .. }] => {
+ let InlayHintLabelPart { text, tooltip, .. } = label.parts.pop().unwrap();
+ (
+ lsp_types::InlayHintLabel::String(text),
+ match tooltip {
+ Some(ide::InlayTooltip::String(s)) => {
+ Some(lsp_types::InlayHintTooltip::String(s))
+ }
+ Some(ide::InlayTooltip::Markdown(s)) => {
+ Some(lsp_types::InlayHintTooltip::MarkupContent(lsp_types::MarkupContent {
+ kind: lsp_types::MarkupKind::Markdown,
+ value: s,
+ }))
+ }
+ None => None,
+ },
+ )
+ }
+ _ => {
+ let parts = label
.parts
.into_iter()
.map(|part| {
- Ok(lsp_types::InlayHintLabelPart {
- value: part.text,
- tooltip: None,
- location: part
- .linked_location
- .map(|range| location(snap, range))
- .transpose()?,
- command: None,
- })
+ part.linked_location.map(|range| location(snap, range)).transpose().map(
+ |location| lsp_types::InlayHintLabelPart {
+ value: part.text,
+ tooltip: match part.tooltip {
+ Some(ide::InlayTooltip::String(s)) => {
+ Some(lsp_types::InlayHintLabelPartTooltip::String(s))
+ }
+ Some(ide::InlayTooltip::Markdown(s)) => {
+ Some(lsp_types::InlayHintLabelPartTooltip::MarkupContent(
+ lsp_types::MarkupContent {
+ kind: lsp_types::MarkupKind::Markdown,
+ value: s,
+ },
+ ))
+ }
+ None => None,
+ },
+ location,
+ command: None,
+ },
+ )
})
- .collect::<Cancellable<Vec<_>>>()?,
- ),
- })
+ .collect::<Cancellable<_>>()?;
+ (lsp_types::InlayHintLabel::LabelParts(parts), None)
+ }
+ };
+ Ok(res)
}
static TOKEN_RESULT_COUNTER: AtomicU32 = AtomicU32::new(1);
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md
index a4780af1a2..0f24ddbbc0 100644
--- a/docs/dev/lsp-extensions.md
+++ b/docs/dev/lsp-extensions.md
@@ -1,5 +1,5 @@
<!---
-lsp_ext.rs hash: 45bd7985265725c5
+lsp_ext.rs hash: d296ce1226e3568d
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: