ide/inlay_hints/
implicit_static.rs1use either::Either;
6use ide_db::famous_defs::FamousDefs;
7use ide_db::text_edit::TextEdit;
8use syntax::{
9 SyntaxKind,
10 ast::{self, AstNode},
11};
12
13use crate::{InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind, LifetimeElisionHints};
14
15pub(super) fn hints(
16 acc: &mut Vec<InlayHint>,
17 FamousDefs(_sema, _): &FamousDefs<'_, '_>,
18 config: &InlayHintsConfig<'_>,
19 statik_or_const: Either<ast::Static, ast::Const>,
20) -> Option<()> {
21 if config.lifetime_elision_hints != LifetimeElisionHints::Always {
22 return None;
23 }
24
25 if let Either::Right(it) = &statik_or_const
26 && ast::AssocItemList::can_cast(
27 it.syntax().parent().map_or(SyntaxKind::EOF, |it| it.kind()),
28 )
29 {
30 return None;
31 }
32
33 if let Some(ast::Type::RefType(ty)) = statik_or_const.either(|it| it.ty(), |it| it.ty())
34 && ty.lifetime().is_none()
35 {
36 let t = ty.amp_token()?;
37 acc.push(InlayHint {
38 range: t.text_range(),
39 kind: InlayKind::Lifetime,
40 label: "'static".into(),
41 text_edit: Some(
42 config
43 .lazy_text_edit(|| TextEdit::insert(t.text_range().start(), "'static ".into())),
44 ),
45 position: InlayHintPosition::After,
46 pad_left: false,
47 pad_right: true,
48 resolve_parent: None,
49 });
50 }
51
52 Some(())
53}
54
55#[cfg(test)]
56mod tests {
57 use crate::{
58 InlayHintsConfig, LifetimeElisionHints,
59 inlay_hints::tests::{TEST_CONFIG, check_with_config},
60 };
61
62 #[test]
63 fn hints_lifetimes_static() {
64 check_with_config(
65 InlayHintsConfig {
66 lifetime_elision_hints: LifetimeElisionHints::Always,
67 ..TEST_CONFIG
68 },
69 r#"
70trait Trait {}
71static S: &str = "";
72// ^'static
73const C: &str = "";
74// ^'static
75const C: &dyn Trait = panic!();
76// ^'static
77
78impl () {
79 const C: &str = "";
80 const C: &dyn Trait = panic!();
81}
82"#,
83 );
84 }
85}