Skip to content

Commit 9876c83

Browse files
committed
feat: Closure capture inlay hints
1 parent 0dd94d3 commit 9876c83

File tree

9 files changed

+71
-14
lines changed

9 files changed

+71
-14
lines changed

crates/hir-ty/src/infer/closure.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ impl HirPlace {
148148
}
149149

150150
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
151-
pub(crate) enum CaptureKind {
151+
pub enum CaptureKind {
152152
ByRef(BorrowKind),
153153
ByValue,
154154
}
@@ -166,6 +166,10 @@ impl CapturedItem {
166166
self.place.local
167167
}
168168

169+
pub fn kind(&self) -> CaptureKind {
170+
self.kind
171+
}
172+
169173
pub fn display_kind(&self) -> &'static str {
170174
match self.kind {
171175
CaptureKind::ByRef(k) => match k {

crates/hir-ty/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,9 @@ pub use autoderef::autoderef;
6161
pub use builder::{ParamKind, TyBuilder};
6262
pub use chalk_ext::*;
6363
pub use infer::{
64-
closure::CapturedItem, could_coerce, could_unify, Adjust, Adjustment, AutoBorrow, BindingMode,
65-
InferenceDiagnostic, InferenceResult, OverloadedDeref, PointerCast,
64+
closure::{CaptureKind, CapturedItem},
65+
could_coerce, could_unify, Adjust, Adjustment, AutoBorrow, BindingMode, InferenceDiagnostic,
66+
InferenceResult, OverloadedDeref, PointerCast,
6667
};
6768
pub use interner::Interner;
6869
pub use lower::{

crates/hir/src/lib.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2611,6 +2611,10 @@ impl LocalSource {
26112611
self.source.file_id.original_file(db.upcast())
26122612
}
26132613

2614+
pub fn file(&self) -> HirFileId {
2615+
self.source.file_id
2616+
}
2617+
26142618
pub fn name(&self) -> Option<ast::Name> {
26152619
self.source.value.name()
26162620
}
@@ -3232,6 +3236,21 @@ impl ClosureCapture {
32323236
Local { parent: self.owner, binding_id: self.capture.local() }
32333237
}
32343238

3239+
pub fn kind(&self) -> CaptureKind {
3240+
match self.capture.kind() {
3241+
hir_ty::CaptureKind::ByRef(
3242+
hir_ty::mir::BorrowKind::Shallow | hir_ty::mir::BorrowKind::Shared,
3243+
) => CaptureKind::SharedRef,
3244+
hir_ty::CaptureKind::ByRef(hir_ty::mir::BorrowKind::Unique) => {
3245+
CaptureKind::UniqueSharedRef
3246+
}
3247+
hir_ty::CaptureKind::ByRef(hir_ty::mir::BorrowKind::Mut { .. }) => {
3248+
CaptureKind::MutableRef
3249+
}
3250+
hir_ty::CaptureKind::ByValue => CaptureKind::Move,
3251+
}
3252+
}
3253+
32353254
pub fn display_kind(&self) -> &'static str {
32363255
self.capture.display_kind()
32373256
}
@@ -3241,6 +3260,13 @@ impl ClosureCapture {
32413260
}
32423261
}
32433262

3263+
pub enum CaptureKind {
3264+
SharedRef,
3265+
UniqueSharedRef,
3266+
MutableRef,
3267+
Move,
3268+
}
3269+
32443270
#[derive(Clone, PartialEq, Eq, Debug)]
32453271
pub struct Type {
32463272
env: Arc<TraitEnvironment>,

crates/ide/src/inlay_hints.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,17 @@ use text_edit::TextEdit;
2020

2121
use crate::{navigation_target::TryToNav, FileId};
2222

23-
mod closing_brace;
24-
mod implicit_static;
25-
mod fn_lifetime_fn;
26-
mod closure_ret;
2723
mod adjustment;
28-
mod chaining;
29-
mod param_name;
30-
mod binding_mode;
3124
mod bind_pat;
25+
mod binding_mode;
26+
mod chaining;
27+
mod closing_brace;
28+
mod closure_ret;
29+
mod closure_captures;
3230
mod discriminant;
31+
mod fn_lifetime_fn;
32+
mod implicit_static;
33+
mod param_name;
3334

3435
#[derive(Clone, Debug, PartialEq, Eq)]
3536
pub struct InlayHintsConfig {
@@ -42,6 +43,7 @@ pub struct InlayHintsConfig {
4243
pub adjustment_hints_mode: AdjustmentHintsMode,
4344
pub adjustment_hints_hide_outside_unsafe: bool,
4445
pub closure_return_type_hints: ClosureReturnTypeHints,
46+
pub closure_capture_hints: bool,
4547
pub binding_mode_hints: bool,
4648
pub lifetime_elision_hints: LifetimeElisionHints,
4749
pub param_names_for_lifetime_elision_hints: bool,
@@ -88,6 +90,8 @@ pub enum AdjustmentHintsMode {
8890
PreferPostfix,
8991
}
9092

93+
// FIXME: Clean up this mess, the kinds are mainly used for setting different rendering properties in the lsp layer
94+
// We should probably turns this into such a property holding struct. Or clean this up in some other form.
9195
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
9296
pub enum InlayKind {
9397
BindingMode,
@@ -98,6 +102,7 @@ pub enum InlayKind {
98102
Adjustment,
99103
AdjustmentPostfix,
100104
Lifetime,
105+
ClosureCapture,
101106
Parameter,
102107
Type,
103108
Discriminant,
@@ -444,10 +449,10 @@ fn hints(
444449
ast::Expr::MethodCallExpr(it) => {
445450
param_name::hints(hints, sema, config, ast::Expr::from(it))
446451
}
447-
ast::Expr::ClosureExpr(it) => closure_ret::hints(hints, famous_defs, config, file_id, it),
448-
// We could show reborrows for all expressions, but usually that is just noise to the user
449-
// and the main point here is to show why "moving" a mutable reference doesn't necessarily move it
450-
// ast::Expr::PathExpr(_) => reborrow_hints(hints, sema, config, &expr),
452+
ast::Expr::ClosureExpr(it) => {
453+
closure_captures::hints(hints, famous_defs, config, file_id, it.clone());
454+
closure_ret::hints(hints, famous_defs, config, file_id, it)
455+
},
451456
_ => None,
452457
}
453458
},
@@ -535,6 +540,7 @@ mod tests {
535540
chaining_hints: false,
536541
lifetime_elision_hints: LifetimeElisionHints::Never,
537542
closure_return_type_hints: ClosureReturnTypeHints::Never,
543+
closure_capture_hints: false,
538544
adjustment_hints: AdjustmentHints::Never,
539545
adjustment_hints_mode: AdjustmentHintsMode::Prefix,
540546
adjustment_hints_hide_outside_unsafe: false,

crates/ide/src/static_index.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ impl StaticIndex<'_> {
122122
param_names_for_lifetime_elision_hints: false,
123123
binding_mode_hints: false,
124124
max_length: Some(25),
125+
closure_capture_hints: false,
125126
closing_brace_hints_min_lines: Some(25),
126127
},
127128
file_id,

crates/rust-analyzer/src/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,8 @@ config_data! {
338338
/// Minimum number of lines required before the `}` until the hint is shown (set to 0 or 1
339339
/// to always show them).
340340
inlayHints_closingBraceHints_minLines: usize = "25",
341+
/// Whether to show inlay hints for closure captures.
342+
inlayHints_closureCaptureHints_enable: bool = "false",
341343
/// Whether to show inlay type hints for return types of closures.
342344
inlayHints_closureReturnTypeHints_enable: ClosureReturnTypeHintsDef = "\"never\"",
343345
/// Closure notation in type and chaining inlay hints.
@@ -1312,6 +1314,7 @@ impl Config {
13121314
ClosureStyle::WithId => hir::ClosureStyle::ClosureWithId,
13131315
ClosureStyle::Hide => hir::ClosureStyle::Hide,
13141316
},
1317+
closure_capture_hints: self.data.inlayHints_closureCaptureHints_enable,
13151318
adjustment_hints: match self.data.inlayHints_expressionAdjustmentHints_enable {
13161319
AdjustmentHintsDef::Always => ide::AdjustmentHints::Always,
13171320
AdjustmentHintsDef::Never => match self.data.inlayHints_reborrowHints_enable {

crates/rust-analyzer/src/to_proto.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@ pub(crate) fn inlay_hint(
456456
| InlayKind::BindingMode => position(line_index, inlay_hint.range.start()),
457457
// after annotated thing
458458
InlayKind::ClosureReturnType
459+
| InlayKind::ClosureCapture
459460
| InlayKind::Type
460461
| InlayKind::Discriminant
461462
| InlayKind::Chaining
@@ -469,6 +470,7 @@ pub(crate) fn inlay_hint(
469470
InlayKind::Type => !render_colons,
470471
InlayKind::Chaining | InlayKind::ClosingBrace => true,
471472
InlayKind::ClosingParenthesis
473+
| InlayKind::ClosureCapture
472474
| InlayKind::Discriminant
473475
| InlayKind::OpeningParenthesis
474476
| InlayKind::BindingMode
@@ -490,6 +492,9 @@ pub(crate) fn inlay_hint(
490492
| InlayKind::Type
491493
| InlayKind::Discriminant
492494
| InlayKind::ClosingBrace => false,
495+
InlayKind::ClosureCapture => {
496+
matches!(&label, lsp_types::InlayHintLabel::String(s) if s == ")")
497+
}
493498
InlayKind::BindingMode => {
494499
matches!(&label, lsp_types::InlayHintLabel::String(s) if s != "&")
495500
}
@@ -501,6 +506,7 @@ pub(crate) fn inlay_hint(
501506
Some(lsp_types::InlayHintKind::TYPE)
502507
}
503508
InlayKind::ClosingParenthesis
509+
| InlayKind::ClosureCapture
504510
| InlayKind::Discriminant
505511
| InlayKind::OpeningParenthesis
506512
| InlayKind::BindingMode

docs/user/generated_config.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,11 @@ Whether to show inlay hints after a closing `}` to indicate what item it belongs
474474
Minimum number of lines required before the `}` until the hint is shown (set to 0 or 1
475475
to always show them).
476476
--
477+
[[rust-analyzer.inlayHints.closureCaptureHints.enable]]rust-analyzer.inlayHints.closureCaptureHints.enable (default: `false`)::
478+
+
479+
--
480+
Whether to show inlay hints for closure captures.
481+
--
477482
[[rust-analyzer.inlayHints.closureReturnTypeHints.enable]]rust-analyzer.inlayHints.closureReturnTypeHints.enable (default: `"never"`)::
478483
+
479484
--

editors/code/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,11 @@
10321032
"type": "integer",
10331033
"minimum": 0
10341034
},
1035+
"rust-analyzer.inlayHints.closureCaptureHints.enable": {
1036+
"markdownDescription": "Whether to show inlay hints for closure captures.",
1037+
"default": false,
1038+
"type": "boolean"
1039+
},
10351040
"rust-analyzer.inlayHints.closureReturnTypeHints.enable": {
10361041
"markdownDescription": "Whether to show inlay type hints for return types of closures.",
10371042
"default": "never",

0 commit comments

Comments
 (0)