]> git.lizzy.rs Git - rust.git/blob - crates/ide_completion/src/completions/lifetime.rs
Less filtering in completion tests
[rust.git] / crates / ide_completion / src / completions / lifetime.rs
1 //! Completes lifetimes and labels.
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 lp_string;
12     let param_lifetime = match (
13         &ctx.lifetime_syntax,
14         ctx.lifetime_param_syntax.as_ref().and_then(|lp| lp.lifetime()),
15     ) {
16         (Some(lt), Some(lp)) if lp == lt.clone() => return,
17         (Some(_), Some(lp)) => {
18             lp_string = lp.to_string();
19             Some(&*lp_string)
20         }
21         _ => None,
22     };
23
24     ctx.scope.process_all_names(&mut |name, res| {
25         if let ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) = res {
26             if param_lifetime != Some(&*name.to_string()) {
27                 acc.add_resolution(ctx, name, &res);
28             }
29         }
30     });
31     if param_lifetime.is_none() {
32         acc.add_static_lifetime(ctx);
33     }
34 }
35
36 /// Completes labels.
37 pub(crate) fn complete_label(acc: &mut Completions, ctx: &CompletionContext) {
38     if !ctx.is_label_ref {
39         return;
40     }
41     ctx.scope.process_all_names(&mut |name, res| {
42         if let ScopeDef::Label(_) = res {
43             acc.add_resolution(ctx, name, &res);
44         }
45     });
46 }
47
48 #[cfg(test)]
49 mod tests {
50     use expect_test::{expect, Expect};
51
52     use crate::tests::{check_edit, completion_list};
53
54     fn check(ra_fixture: &str, expect: Expect) {
55         let actual = completion_list(ra_fixture);
56         expect.assert_eq(&actual);
57     }
58
59     #[test]
60     fn check_lifetime_edit() {
61         check_edit(
62             "'lifetime",
63             r#"
64 fn func<'lifetime>(foo: &'li$0) {}
65 "#,
66             r#"
67 fn func<'lifetime>(foo: &'lifetime) {}
68 "#,
69         );
70         cov_mark::check!(completes_if_lifetime_without_idents);
71         check_edit(
72             "'lifetime",
73             r#"
74 fn func<'lifetime>(foo: &'$0) {}
75 "#,
76             r#"
77 fn func<'lifetime>(foo: &'lifetime) {}
78 "#,
79         );
80     }
81
82     #[test]
83     fn complete_lifetime_in_ref() {
84         check(
85             r#"
86 fn foo<'lifetime>(foo: &'a$0 usize) {}
87 "#,
88             expect![[r#"
89                 lt 'lifetime
90                 lt 'static
91             "#]],
92         );
93     }
94
95     #[test]
96     fn complete_lifetime_in_ref_missing_ty() {
97         check(
98             r#"
99 fn foo<'lifetime>(foo: &'a$0) {}
100 "#,
101             expect![[r#"
102                 lt 'lifetime
103                 lt 'static
104             "#]],
105         );
106     }
107     #[test]
108     fn complete_lifetime_in_self_ref() {
109         check(
110             r#"
111 struct Foo;
112 impl<'impl> Foo {
113     fn foo<'func>(&'a$0 self) {}
114 }
115 "#,
116             expect![[r#"
117                 lt 'func
118                 lt 'impl
119                 lt 'static
120             "#]],
121         );
122     }
123
124     #[test]
125     fn complete_lifetime_in_arg_list() {
126         check(
127             r#"
128 struct Foo<'lt>;
129 fn foo<'lifetime>(_: Foo<'a$0>) {}
130 "#,
131             expect![[r#"
132                 lt 'lifetime
133                 lt 'static
134             "#]],
135         );
136     }
137
138     #[test]
139     fn complete_lifetime_in_where_pred() {
140         check(
141             r#"
142 fn foo2<'lifetime, T>() where 'a$0 {}
143 "#,
144             expect![[r#"
145                 lt 'lifetime
146                 lt 'static
147             "#]],
148         );
149     }
150
151     #[test]
152     fn complete_lifetime_in_ty_bound() {
153         check(
154             r#"
155 fn foo2<'lifetime, T>() where T: 'a$0 {}
156 "#,
157             expect![[r#"
158                 lt 'lifetime
159                 lt 'static
160             "#]],
161         );
162         check(
163             r#"
164 fn foo2<'lifetime, T>() where T: Trait<'a$0> {}
165 "#,
166             expect![[r#"
167                 lt 'lifetime
168                 lt 'static
169             "#]],
170         );
171     }
172
173     #[test]
174     fn dont_complete_lifetime_in_assoc_ty_bound() {
175         check(
176             r#"
177 fn foo2<'lifetime, T>() where T: Trait<Item = 'a$0> {}
178 "#,
179             expect![[r#""#]],
180         );
181     }
182
183     #[test]
184     fn complete_lifetime_in_param_list() {
185         check(
186             r#"
187 fn foo<'a$0>() {}
188 "#,
189             expect![[r#""#]],
190         );
191         check(
192             r#"
193 fn foo<'footime, 'lifetime: 'a$0>() {}
194 "#,
195             expect![[r#"
196                 lt 'footime
197             "#]],
198         );
199     }
200
201     #[test]
202     fn check_label_edit() {
203         check_edit(
204             "'label",
205             r#"
206 fn foo() {
207     'label: loop {
208         break '$0
209     }
210 }
211 "#,
212             r#"
213 fn foo() {
214     'label: loop {
215         break 'label
216     }
217 }
218 "#,
219         );
220     }
221
222     #[test]
223     fn complete_label_in_loop() {
224         check(
225             r#"
226 fn foo() {
227     'foop: loop {
228         break '$0
229     }
230 }
231 "#,
232             expect![[r#"
233                 lb 'foop
234             "#]],
235         );
236         check(
237             r#"
238 fn foo() {
239     'foop: loop {
240         continue '$0
241     }
242 }
243 "#,
244             expect![[r#"
245                 lb 'foop
246             "#]],
247         );
248     }
249
250     #[test]
251     fn complete_label_in_block_nested() {
252         check(
253             r#"
254 fn foo() {
255     'foop: {
256         'baap: {
257             break '$0
258         }
259     }
260 }
261 "#,
262             expect![[r#"
263                 lb 'baap
264                 lb 'foop
265             "#]],
266         );
267     }
268
269     #[test]
270     fn complete_label_in_loop_with_value() {
271         check(
272             r#"
273 fn foo() {
274     'foop: loop {
275         break '$0 i32;
276     }
277 }
278 "#,
279             expect![[r#"
280                 lb 'foop
281             "#]],
282         );
283     }
284
285     #[test]
286     fn complete_label_in_while_cond() {
287         check(
288             r#"
289 fn foo() {
290     'outer: while { 'inner: loop { break '$0 } } {}
291 }
292 "#,
293             expect![[r#"
294                 lb 'inner
295                 lb 'outer
296             "#]],
297         );
298     }
299
300     #[test]
301     fn complete_label_in_for_iterable() {
302         check(
303             r#"
304 fn foo() {
305     'outer: for _ in [{ 'inner: loop { break '$0 } }] {}
306 }
307 "#,
308             expect![[r#"
309                 lb 'inner
310             "#]],
311         );
312     }
313 }