ide/inlay_hints/
placeholders.rs

1//! Implementation of type placeholder inlay hints:
2//! ```no_run
3//! let a = Vec<_> = vec![4];
4//!           //^ = i32
5//! ```
6
7use hir::DisplayTarget;
8use ide_db::famous_defs::FamousDefs;
9use syntax::{
10    AstNode,
11    ast::{InferType, Type},
12};
13
14use crate::{InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind, inlay_hints::label_of_ty};
15
16pub(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 || config.hide_inferred_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)]
49mod 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#"
64struct S<T>(T);
65
66fn 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
77    #[test]
78    fn hide_inferred_types() {
79        check_with_config(
80            InlayHintsConfig {
81                type_hints: true,
82                hide_inferred_type_hints: true,
83                ..DISABLED_CONFIG
84            },
85            r#"
86struct S<T>(T);
87
88fn foo() {
89    let t: (_, _, [_; _]) = (1_u32, S(2), [false] as _);
90}
91        "#,
92        );
93    }
94}