Skip to content

Commit 4c0d5e9

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 89c8475 commit 4c0d5e9

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
@@ -40,6 +40,7 @@ mod implicit_static;
4040
mod implied_dyn_trait;
4141
mod lifetime;
4242
mod param_name;
43+
mod placeholders;
4344
mod ra_fixture;
4445
mod range_exclusive;
4546

@@ -291,6 +292,10 @@ fn hints(
291292
implied_dyn_trait::hints(hints, famous_defs, config, Either::Right(dyn_));
292293
Some(())
293294
},
295+
ast::Type::InferType(placeholder) => {
296+
placeholders::type_hints(hints, famous_defs, config, display_target, placeholder);
297+
Some(())
298+
},
294299
_ => Some(()),
295300
},
296301
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)