Unnamed repository; edit this file 'description' to name the repository.
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.
| -rw-r--r-- | crates/ide/src/inlay_hints.rs | 5 | ||||
| -rw-r--r-- | crates/ide/src/inlay_hints/placeholders.rs | 76 |
2 files changed, 81 insertions, 0 deletions
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 2b4fe54fc3..6dd9e84a57 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -40,6 +40,7 @@ mod implicit_static; mod implied_dyn_trait; mod lifetime; mod param_name; +mod placeholders; mod ra_fixture; mod range_exclusive; @@ -291,6 +292,10 @@ fn hints( implied_dyn_trait::hints(hints, famous_defs, config, Either::Right(dyn_)); Some(()) }, + ast::Type::InferType(placeholder) => { + placeholders::type_hints(hints, famous_defs, config, display_target, placeholder); + Some(()) + }, _ => Some(()), }, ast::GenericParamList(it) => bounds::hints(hints, famous_defs, config, it), diff --git a/crates/ide/src/inlay_hints/placeholders.rs b/crates/ide/src/inlay_hints/placeholders.rs new file mode 100644 index 0000000000..96d2c17c03 --- /dev/null +++ b/crates/ide/src/inlay_hints/placeholders.rs @@ -0,0 +1,76 @@ +//! Implementation of type placeholder inlay hints: +//! ```no_run +//! let a = Vec<_> = vec![4]; +//! //^ = i32 +//! ``` + +use hir::DisplayTarget; +use ide_db::famous_defs::FamousDefs; +use syntax::{ + AstNode, + ast::{InferType, Type}, +}; + +use crate::{InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind, inlay_hints::label_of_ty}; + +pub(super) fn type_hints( + acc: &mut Vec<InlayHint>, + famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>, + config: &InlayHintsConfig<'_>, + display_target: DisplayTarget, + placeholder: InferType, +) -> Option<()> { + if !config.type_hints { + return None; + } + + let syntax = placeholder.syntax(); + let range = syntax.text_range(); + + let ty = sema.resolve_type(&Type::InferType(placeholder))?; + + let mut label = label_of_ty(famous_defs, config, &ty, display_target)?; + label.prepend_str("= "); + + acc.push(InlayHint { + range, + kind: InlayKind::Type, + label, + text_edit: None, + position: InlayHintPosition::After, + pad_left: true, + pad_right: false, + resolve_parent: None, + }); + Some(()) +} + +#[cfg(test)] +mod tests { + use crate::{ + InlayHintsConfig, + inlay_hints::tests::{DISABLED_CONFIG, check_with_config}, + }; + + #[track_caller] + fn check_type_infer(#[rust_analyzer::rust_fixture] ra_fixture: &str) { + check_with_config(InlayHintsConfig { type_hints: true, ..DISABLED_CONFIG }, ra_fixture); + } + + #[test] + fn inferred_types() { + check_type_infer( + r#" +struct S<T>(T); + +fn foo() { + let t: (_, _, [_; _]) = (1_u32, S(2), [false] as _); + //^ = u32 + //^ = S<i32> + //^ = bool + //^ = [bool; 1] +} +"#, + ); + } +} |