]> git.lizzy.rs Git - rust.git/blob - crates/ide_completion/src/completions/lifetime.rs
Add basic lifetime completion
[rust.git] / crates / ide_completion / src / completions / lifetime.rs
1 //! Completes lifetimes.
2 use hir::ScopeDef;
3
4 use crate::{completions::Completions, context::CompletionContext};
5
6 /// Completes lifetimes.
7 pub(crate) fn complete_lifetime(acc: &mut Completions, ctx: &CompletionContext) {
8     if !ctx.lifetime_allowed {
9         return;
10     }
11     let param_lifetime = match (
12         &ctx.lifetime_syntax,
13         ctx.lifetime_param_syntax.as_ref().and_then(|lp| lp.lifetime()),
14     ) {
15         (Some(lt), Some(lp)) if lp == lt.clone() => return,
16         (Some(_), Some(lp)) => Some(lp.to_string()),
17         _ => None,
18     };
19
20     ctx.scope.process_all_names(&mut |name, res| {
21         if let ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) = res {
22             if param_lifetime != Some(name.to_string()) {
23                 acc.add_resolution(ctx, name.to_string(), &res);
24             }
25         }
26     });
27     if param_lifetime.is_none() {
28         acc.add_static_lifetime(ctx);
29     }
30 }
31
32 #[cfg(test)]
33 mod tests {
34     use expect_test::{expect, Expect};
35
36     use crate::{
37         test_utils::{check_edit, completion_list_with_config, TEST_CONFIG},
38         CompletionConfig, CompletionKind,
39     };
40
41     fn check(ra_fixture: &str, expect: Expect) {
42         check_with_config(TEST_CONFIG, ra_fixture, expect);
43     }
44
45     fn check_with_config(config: CompletionConfig, ra_fixture: &str, expect: Expect) {
46         let actual = completion_list_with_config(config, ra_fixture, CompletionKind::Reference);
47         expect.assert_eq(&actual)
48     }
49
50     #[test]
51     fn check_lifetime_edit() {
52         check_edit(
53             "'lifetime",
54             r#"
55 fn func<'lifetime>(foo: &'li$0) {}
56 "#,
57             r#"
58 fn func<'lifetime>(foo: &'lifetime) {}
59 "#,
60         );
61     }
62
63     #[test]
64     fn complete_lifetime_in_ref() {
65         check(
66             r#"
67 fn foo<'lifetime>(foo: &'a$0 usize) {}
68 "#,
69             expect![[r#"
70                 lt 'lifetime
71                 lt 'static
72             "#]],
73         );
74     }
75
76     #[test]
77     fn complete_lifetime_in_ref_missing_ty() {
78         check(
79             r#"
80 fn foo<'lifetime>(foo: &'a$0) {}
81 "#,
82             expect![[r#"
83                 lt 'lifetime
84                 lt 'static
85             "#]],
86         );
87     }
88     #[test]
89     fn complete_lifetime_in_self_ref() {
90         check(
91             r#"
92 struct Foo;
93 impl<'impl> Foo {
94     fn foo<'func>(&'a$0 self) {}
95 }
96 "#,
97             expect![[r#"
98                 lt 'func
99                 lt 'impl
100                 lt 'static
101             "#]],
102         );
103     }
104
105     #[test]
106     fn complete_lifetime_in_arg_list() {
107         check(
108             r#"
109 struct Foo<'lt>;
110 fn foo<'lifetime>(_: Foo<'a$0>) {}
111 "#,
112             expect![[r#"
113                 lt 'lifetime
114                 lt 'static
115             "#]],
116         );
117     }
118
119     #[test]
120     fn complete_lifetime_in_where_pred() {
121         check(
122             r#"
123 fn foo2<'lifetime, T>() where 'a$0 {}
124 "#,
125             expect![[r#"
126                 lt 'lifetime
127                 lt 'static
128             "#]],
129         );
130     }
131
132     #[test]
133     fn complete_lifetime_in_ty_bound() {
134         check(
135             r#"
136 fn foo2<'lifetime, T>() where T: 'a$0 {}
137 "#,
138             expect![[r#"
139                 lt 'lifetime
140                 lt 'static
141             "#]],
142         );
143         check(
144             r#"
145 fn foo2<'lifetime, T>() where T: Trait<'a$0> {}
146 "#,
147             expect![[r#"
148                 lt 'lifetime
149                 lt 'static
150             "#]],
151         );
152     }
153
154     #[test]
155     fn dont_complete_lifetime_in_assoc_ty_bound() {
156         check(
157             r#"
158 fn foo2<'lifetime, T>() where T: Trait<Item = 'a$0> {}
159 "#,
160             expect![[r#""#]],
161         );
162     }
163
164     #[test]
165     fn complete_lifetime_in_param_list() {
166         check(
167             r#"
168 fn foo<'a$0>() {}
169 "#,
170             expect![[r#""#]],
171         );
172         check(
173             r#"
174 fn foo<'footime, 'lifetime: 'a$0>() {}
175 "#,
176             expect![[r#"
177                 lt 'footime
178             "#]],
179         );
180     }
181 }