Skip to content

Commit 09d65ac

Browse files
Show inlay hints for type placeholders
With the extra InferenceResult that maps type placeholders to their inferred type, we can now easily display inlay hints for them.
1 parent 596ce07 commit 09d65ac

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

crates/ide/src/inlay_hints.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ mod implicit_static;
3939
mod implied_dyn_trait;
4040
mod lifetime;
4141
mod param_name;
42+
mod placeholders;
4243
mod range_exclusive;
4344

4445
// Feature: Inlay Hints
@@ -288,6 +289,10 @@ fn hints(
288289
implied_dyn_trait::hints(hints, famous_defs, config, Either::Right(dyn_));
289290
Some(())
290291
},
292+
ast::Type::InferType(placeholder) => {
293+
placeholders::type_hints(hints, famous_defs, config, display_target, placeholder);
294+
Some(())
295+
},
291296
_ => Some(()),
292297
},
293298
ast::GenericParamList(it) => bounds::hints(hints, famous_defs, config, it),
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
//! Implementation of type placeholder inlay hints:
2+
//! ```no_run
3+
//! let a = Vec<_> = vec![4];
4+
//! //^ = i32
5+
//! ```
6+
7+
use hir::DisplayTarget;
8+
use ide_db::famous_defs::FamousDefs;
9+
use syntax::{
10+
AstNode,
11+
ast::{InferType, Type},
12+
};
13+
14+
use crate::{InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind, inlay_hints::label_of_ty};
15+
16+
pub(super) fn type_hints(
17+
acc: &mut Vec<InlayHint>,
18+
famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>,
19+
config: &InlayHintsConfig,
20+
display_target: DisplayTarget,
21+
placeholder: InferType,
22+
) -> Option<()> {
23+
if !config.type_hints {
24+
return None;
25+
}
26+
27+
let syntax = placeholder.syntax();
28+
let range = syntax.text_range();
29+
30+
let ty = sema.resolve_type(&Type::InferType(placeholder))?;
31+
32+
let mut label = label_of_ty(famous_defs, config, &ty, display_target)?;
33+
label.prepend_str("= ");
34+
35+
acc.push(InlayHint {
36+
range,
37+
kind: InlayKind::Type,
38+
label,
39+
text_edit: None,
40+
position: InlayHintPosition::After,
41+
pad_left: true,
42+
pad_right: false,
43+
resolve_parent: None,
44+
});
45+
Some(())
46+
}
47+
48+
#[cfg(test)]
49+
mod tests {
50+
use crate::{
51+
InlayHintsConfig,
52+
inlay_hints::tests::{DISABLED_CONFIG, check_with_config},
53+
};
54+
55+
#[track_caller]
56+
fn check_type_infer(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
57+
check_with_config(InlayHintsConfig { type_hints: true, ..DISABLED_CONFIG }, ra_fixture);
58+
}
59+
60+
#[test]
61+
fn inferred_types() {
62+
check_type_infer(
63+
r#"
64+
struct S<T>(T);
65+
66+
fn foo() {
67+
let t: (_, _, [_; _]) = (1_u32, S(2), [false] as _);
68+
//^ = u32
69+
//^ = S<i32>
70+
//^ = bool
71+
//^ = [bool; 1]
72+
}
73+
"#,
74+
);
75+
}
76+
}

0 commit comments

Comments
 (0)