]> git.lizzy.rs Git - rust.git/blob - src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs
Rollup merge of #104199 - SarthakSingh31:issue-97417-1, r=cjgillot
[rust.git] / src / tools / rust-analyzer / crates / ide-completion / src / completions / keyword.rs
1 //! Completes `where` and `for` keywords.
2
3 use syntax::ast::{self, Item};
4
5 use crate::{CompletionContext, Completions};
6
7 pub(crate) fn complete_for_and_where(
8     acc: &mut Completions,
9     ctx: &CompletionContext<'_>,
10     keyword_item: &ast::Item,
11 ) {
12     let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet);
13
14     match keyword_item {
15         Item::Impl(it) => {
16             if it.for_token().is_none() && it.trait_().is_none() && it.self_ty().is_some() {
17                 add_keyword("for", "for");
18             }
19             add_keyword("where", "where");
20         }
21         Item::Enum(_)
22         | Item::Fn(_)
23         | Item::Struct(_)
24         | Item::Trait(_)
25         | Item::TypeAlias(_)
26         | Item::Union(_) => {
27             add_keyword("where", "where");
28         }
29         _ => (),
30     }
31 }
32
33 #[cfg(test)]
34 mod tests {
35     use expect_test::{expect, Expect};
36
37     use crate::tests::{check_edit, completion_list};
38
39     fn check(ra_fixture: &str, expect: Expect) {
40         let actual = completion_list(ra_fixture);
41         expect.assert_eq(&actual)
42     }
43
44     #[test]
45     fn test_else_edit_after_if() {
46         check_edit(
47             "else",
48             r#"fn quux() { if true { () } $0 }"#,
49             r#"fn quux() { if true { () } else {
50     $0
51 } }"#,
52         );
53     }
54
55     #[test]
56     fn test_keywords_after_unsafe_in_block_expr() {
57         check(
58             r"fn my_fn() { unsafe $0 }",
59             expect![[r#"
60                 kw fn
61                 kw impl
62                 kw trait
63             "#]],
64         );
65     }
66
67     #[test]
68     fn test_completion_await_impls_future() {
69         check(
70             r#"
71 //- minicore: future
72 use core::future::*;
73 struct A {}
74 impl Future for A {}
75 fn foo(a: A) { a.$0 }
76 "#,
77             expect![[r#"
78                 kw await                  expr.await
79                 me into_future() (as IntoFuture) fn(self) -> <Self as IntoFuture>::IntoFuture
80                 sn box                    Box::new(expr)
81                 sn call                   function(expr)
82                 sn dbg                    dbg!(expr)
83                 sn dbgr                   dbg!(&expr)
84                 sn let                    let
85                 sn letm                   let mut
86                 sn match                  match expr {}
87                 sn ref                    &expr
88                 sn refm                   &mut expr
89             "#]],
90         );
91
92         check(
93             r#"
94 //- minicore: future
95 use std::future::*;
96 fn foo() {
97     let a = async {};
98     a.$0
99 }
100 "#,
101             expect![[r#"
102                 kw await                  expr.await
103                 me into_future() (use core::future::IntoFuture) fn(self) -> <Self as IntoFuture>::IntoFuture
104                 sn box                    Box::new(expr)
105                 sn call                   function(expr)
106                 sn dbg                    dbg!(expr)
107                 sn dbgr                   dbg!(&expr)
108                 sn let                    let
109                 sn letm                   let mut
110                 sn match                  match expr {}
111                 sn ref                    &expr
112                 sn refm                   &mut expr
113             "#]],
114         );
115     }
116
117     #[test]
118     fn test_completion_await_impls_into_future() {
119         check(
120             r#"
121 //- minicore: future
122 use core::future::*;
123 struct A {}
124 impl IntoFuture for A {}
125 fn foo(a: A) { a.$0 }
126 "#,
127             expect![[r#"
128                 kw await                  expr.await
129                 me into_future() (as IntoFuture) fn(self) -> <Self as IntoFuture>::IntoFuture
130                 sn box                    Box::new(expr)
131                 sn call                   function(expr)
132                 sn dbg                    dbg!(expr)
133                 sn dbgr                   dbg!(&expr)
134                 sn let                    let
135                 sn letm                   let mut
136                 sn match                  match expr {}
137                 sn ref                    &expr
138                 sn refm                   &mut expr
139             "#]],
140         );
141     }
142
143     #[test]
144     fn let_semi() {
145         cov_mark::check!(let_semi);
146         check_edit(
147             "match",
148             r#"
149 fn main() { let x = $0 }
150 "#,
151             r#"
152 fn main() { let x = match $1 {
153     $0
154 }; }
155 "#,
156         );
157
158         check_edit(
159             "if",
160             r#"
161 fn main() {
162     let x = $0
163     let y = 92;
164 }
165 "#,
166             r#"
167 fn main() {
168     let x = if $1 {
169     $0
170 };
171     let y = 92;
172 }
173 "#,
174         );
175
176         check_edit(
177             "loop",
178             r#"
179 fn main() {
180     let x = $0
181     bar();
182 }
183 "#,
184             r#"
185 fn main() {
186     let x = loop {
187     $0
188 };
189     bar();
190 }
191 "#,
192         );
193     }
194
195     #[test]
196     fn if_completion_in_match_guard() {
197         check_edit(
198             "if",
199             r"
200 fn main() {
201     match () {
202         () $0
203     }
204 }
205 ",
206             r"
207 fn main() {
208     match () {
209         () if $0
210     }
211 }
212 ",
213         )
214     }
215
216     #[test]
217     fn if_completion_in_match_arm_expr() {
218         check_edit(
219             "if",
220             r"
221 fn main() {
222     match () {
223         () => $0
224     }
225 }
226 ",
227             r"
228 fn main() {
229     match () {
230         () => if $1 {
231     $0
232 }
233     }
234 }
235 ",
236         )
237     }
238
239     #[test]
240     fn if_completion_in_match_arm_expr_block() {
241         check_edit(
242             "if",
243             r"
244 fn main() {
245     match () {
246         () => {
247             $0
248         }
249     }
250 }
251 ",
252             r"
253 fn main() {
254     match () {
255         () => {
256             if $1 {
257     $0
258 }
259         }
260     }
261 }
262 ",
263         )
264     }
265 }