]> git.lizzy.rs Git - rust.git/blob - crates/ide_completion/src/completions/unqualified_path.rs
7496d26c4db89b709c6e118863d39b3d9214a388
[rust.git] / crates / ide_completion / src / completions / unqualified_path.rs
1 //! Completion of names from the current scope, e.g. locals and imported items.
2
3 use hir::ScopeDef;
4 use syntax::AstNode;
5
6 use crate::{CompletionContext, Completions};
7
8 pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
9     if !ctx.is_trivial_path {
10         return;
11     }
12     if ctx.record_lit_syntax.is_some()
13         || ctx.record_pat_syntax.is_some()
14         || ctx.attribute_under_caret.is_some()
15         || ctx.mod_declaration_under_caret.is_some()
16         || ctx.has_impl_or_trait_parent()
17     {
18         return;
19     }
20
21     if let Some(hir::Adt::Enum(e)) =
22         ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
23     {
24         super::complete_enum_variants(acc, ctx, e, |acc, ctx, variant, path| {
25             acc.add_qualified_enum_variant(ctx, variant, path)
26         });
27     }
28
29     ctx.scope.process_all_names(&mut |name, res| {
30         if let ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) = res {
31             cov_mark::hit!(skip_lifetime_completion);
32             return;
33         }
34         if ctx.use_item_syntax.is_some() {
35             if let (ScopeDef::Unknown, Some(name_ref)) = (&res, &ctx.name_ref_syntax) {
36                 if name_ref.syntax().text() == name.to_string().as_str() {
37                     cov_mark::hit!(self_fulfilling_completion);
38                     return;
39                 }
40             }
41         }
42         acc.add_resolution(ctx, name.to_string(), &res);
43     });
44 }
45
46 #[cfg(test)]
47 mod tests {
48     use expect_test::{expect, Expect};
49
50     use crate::{
51         test_utils::{check_edit, completion_list_with_config, TEST_CONFIG},
52         CompletionConfig, CompletionKind,
53     };
54
55     fn check(ra_fixture: &str, expect: Expect) {
56         check_with_config(TEST_CONFIG, ra_fixture, expect);
57     }
58
59     fn check_with_config(config: CompletionConfig, ra_fixture: &str, expect: Expect) {
60         let actual = completion_list_with_config(config, ra_fixture, CompletionKind::Reference);
61         expect.assert_eq(&actual)
62     }
63
64     #[test]
65     fn self_fulfilling_completion() {
66         cov_mark::check!(self_fulfilling_completion);
67         check(
68             r#"
69 use foo$0
70 use std::collections;
71 "#,
72             expect![[r#"
73                 ?? collections
74             "#]],
75         );
76     }
77
78     #[test]
79     fn bind_pat_and_path_ignore_at() {
80         check(
81             r#"
82 enum Enum { A, B }
83 fn quux(x: Option<Enum>) {
84     match x {
85         None => (),
86         Some(en$0 @ Enum::A) => (),
87     }
88 }
89 "#,
90             expect![[r#""#]],
91         );
92     }
93
94     #[test]
95     fn bind_pat_and_path_ignore_ref() {
96         check(
97             r#"
98 enum Enum { A, B }
99 fn quux(x: Option<Enum>) {
100     match x {
101         None => (),
102         Some(ref en$0) => (),
103     }
104 }
105 "#,
106             expect![[r#""#]],
107         );
108     }
109
110     #[test]
111     fn bind_pat_and_path() {
112         check(
113             r#"
114 enum Enum { A, B }
115 fn quux(x: Option<Enum>) {
116     match x {
117         None => (),
118         Some(En$0) => (),
119     }
120 }
121 "#,
122             expect![[r#"
123                 en Enum
124             "#]],
125         );
126     }
127
128     #[test]
129     fn completes_bindings_from_let() {
130         check(
131             r#"
132 fn quux(x: i32) {
133     let y = 92;
134     1 + $0;
135     let z = ();
136 }
137 "#,
138             expect![[r#"
139                 lc y       i32
140                 lc x       i32
141                 fn quux(…) fn(i32)
142             "#]],
143         );
144     }
145
146     #[test]
147     fn completes_bindings_from_if_let() {
148         check(
149             r#"
150 fn quux() {
151     if let Some(x) = foo() {
152         let y = 92;
153     };
154     if let Some(a) = bar() {
155         let b = 62;
156         1 + $0
157     }
158 }
159 "#,
160             expect![[r#"
161                 lc b      i32
162                 lc a
163                 fn quux() fn()
164             "#]],
165         );
166     }
167
168     #[test]
169     fn completes_bindings_from_for() {
170         check(
171             r#"
172 fn quux() {
173     for x in &[1, 2, 3] { $0 }
174 }
175 "#,
176             expect![[r#"
177                 lc x
178                 fn quux() fn()
179             "#]],
180         );
181     }
182
183     #[test]
184     fn completes_if_prefix_is_keyword() {
185         cov_mark::check!(completes_if_prefix_is_keyword);
186         check_edit(
187             "wherewolf",
188             r#"
189 fn main() {
190     let wherewolf = 92;
191     drop(where$0)
192 }
193 "#,
194             r#"
195 fn main() {
196     let wherewolf = 92;
197     drop(wherewolf)
198 }
199 "#,
200         )
201     }
202
203     #[test]
204     fn completes_generic_params() {
205         check(
206             r#"fn quux<T>() { $0 }"#,
207             expect![[r#"
208                 tp T
209                 fn quux() fn()
210             "#]],
211         );
212         check(
213             r#"fn quux<const C: usize>() { $0 }"#,
214             expect![[r#"
215                 cp C
216                 fn quux() fn()
217             "#]],
218         );
219     }
220
221     #[test]
222     fn does_not_complete_lifetimes() {
223         cov_mark::check!(skip_lifetime_completion);
224         check(
225             r#"fn quux<'a>() { $0 }"#,
226             expect![[r#"
227                 fn quux() fn()
228             "#]],
229         );
230     }
231
232     #[test]
233     fn completes_generic_params_in_struct() {
234         check(
235             r#"struct S<T> { x: $0}"#,
236             expect![[r#"
237                 sp Self
238                 tp T
239                 st S<…>
240             "#]],
241         );
242     }
243
244     #[test]
245     fn completes_self_in_enum() {
246         check(
247             r#"enum X { Y($0) }"#,
248             expect![[r#"
249                 sp Self
250                 en X
251             "#]],
252         );
253     }
254
255     #[test]
256     fn completes_module_items() {
257         check(
258             r#"
259 struct S;
260 enum E {}
261 fn quux() { $0 }
262 "#,
263             expect![[r#"
264                 st S
265                 fn quux() fn()
266                 en E
267             "#]],
268         );
269     }
270
271     /// Regression test for issue #6091.
272     #[test]
273     fn correctly_completes_module_items_prefixed_with_underscore() {
274         check_edit(
275             "_alpha",
276             r#"
277 fn main() {
278     _$0
279 }
280 fn _alpha() {}
281 "#,
282             r#"
283 fn main() {
284     _alpha()$0
285 }
286 fn _alpha() {}
287 "#,
288         )
289     }
290
291     #[test]
292     fn completes_extern_prelude() {
293         check(
294             r#"
295 //- /lib.rs crate:main deps:other_crate
296 use $0;
297
298 //- /other_crate/lib.rs crate:other_crate
299 // nothing here
300 "#,
301             expect![[r#"
302                 md other_crate
303             "#]],
304         );
305     }
306
307     #[test]
308     fn completes_module_items_in_nested_modules() {
309         check(
310             r#"
311 struct Foo;
312 mod m {
313     struct Bar;
314     fn quux() { $0 }
315 }
316 "#,
317             expect![[r#"
318                 fn quux() fn()
319                 st Bar
320             "#]],
321         );
322     }
323
324     #[test]
325     fn completes_return_type() {
326         check(
327             r#"
328 struct Foo;
329 fn x() -> $0
330 "#,
331             expect![[r#"
332                 st Foo
333                 fn x() fn()
334             "#]],
335         );
336     }
337
338     #[test]
339     fn dont_show_both_completions_for_shadowing() {
340         check(
341             r#"
342 fn foo() {
343     let bar = 92;
344     {
345         let bar = 62;
346         drop($0)
347     }
348 }
349 "#,
350             // FIXME: should be only one bar here
351             expect![[r#"
352                 lc bar   i32
353                 lc bar   i32
354                 fn foo() fn()
355             "#]],
356         );
357     }
358
359     #[test]
360     fn completes_self_in_methods() {
361         check(
362             r#"impl S { fn foo(&self) { $0 } }"#,
363             expect![[r#"
364                 lc self &{unknown}
365                 sp Self
366             "#]],
367         );
368     }
369
370     #[test]
371     fn completes_prelude() {
372         check(
373             r#"
374 //- /main.rs crate:main deps:std
375 fn foo() { let x: $0 }
376
377 //- /std/lib.rs crate:std
378 #[prelude_import]
379 use prelude::*;
380
381 mod prelude { struct Option; }
382 "#,
383             expect![[r#"
384                 fn foo()  fn()
385                 md std
386                 st Option
387             "#]],
388         );
389     }
390
391     #[test]
392     fn completes_prelude_macros() {
393         check(
394             r#"
395 //- /main.rs crate:main deps:std
396 fn f() {$0}
397
398 //- /std/lib.rs crate:std
399 #[prelude_import]
400 pub use prelude::*;
401
402 #[macro_use]
403 mod prelude {
404     pub use crate::concat;
405 }
406
407 mod macros {
408     #[rustc_builtin_macro]
409     #[macro_export]
410     macro_rules! concat { }
411 }
412 "#,
413             expect![[r##"
414                 fn f()        fn()
415                 ma concat!(…) #[macro_export] macro_rules! concat
416                 md std
417             "##]],
418         );
419     }
420
421     #[test]
422     fn completes_std_prelude_if_core_is_defined() {
423         check(
424             r#"
425 //- /main.rs crate:main deps:core,std
426 fn foo() { let x: $0 }
427
428 //- /core/lib.rs crate:core
429 #[prelude_import]
430 use prelude::*;
431
432 mod prelude { struct Option; }
433
434 //- /std/lib.rs crate:std deps:core
435 #[prelude_import]
436 use prelude::*;
437
438 mod prelude { struct String; }
439 "#,
440             expect![[r#"
441                 fn foo()  fn()
442                 md std
443                 md core
444                 st String
445             "#]],
446         );
447     }
448
449     #[test]
450     fn completes_macros_as_value() {
451         check(
452             r#"
453 macro_rules! foo { () => {} }
454
455 #[macro_use]
456 mod m1 {
457     macro_rules! bar { () => {} }
458 }
459
460 mod m2 {
461     macro_rules! nope { () => {} }
462
463     #[macro_export]
464     macro_rules! baz { () => {} }
465 }
466
467 fn main() { let v = $0 }
468 "#,
469             expect![[r##"
470                 md m1
471                 ma baz!(…) #[macro_export] macro_rules! baz
472                 fn main()  fn()
473                 md m2
474                 ma bar!(…) macro_rules! bar
475                 ma foo!(…) macro_rules! foo
476             "##]],
477         );
478     }
479
480     #[test]
481     fn completes_both_macro_and_value() {
482         check(
483             r#"
484 macro_rules! foo { () => {} }
485 fn foo() { $0 }
486 "#,
487             expect![[r#"
488                 fn foo()   fn()
489                 ma foo!(…) macro_rules! foo
490             "#]],
491         );
492     }
493
494     #[test]
495     fn completes_macros_as_type() {
496         check(
497             r#"
498 macro_rules! foo { () => {} }
499 fn main() { let x: $0 }
500 "#,
501             expect![[r#"
502                 fn main()  fn()
503                 ma foo!(…) macro_rules! foo
504             "#]],
505         );
506     }
507
508     #[test]
509     fn completes_macros_as_stmt() {
510         check(
511             r#"
512 macro_rules! foo { () => {} }
513 fn main() { $0 }
514 "#,
515             expect![[r#"
516                 fn main()  fn()
517                 ma foo!(…) macro_rules! foo
518             "#]],
519         );
520     }
521
522     #[test]
523     fn completes_local_item() {
524         check(
525             r#"
526 fn main() {
527     return f$0;
528     fn frobnicate() {}
529 }
530 "#,
531             expect![[r#"
532                 fn frobnicate() fn()
533                 fn main()       fn()
534             "#]],
535         );
536     }
537
538     #[test]
539     fn completes_in_simple_macro_1() {
540         check(
541             r#"
542 macro_rules! m { ($e:expr) => { $e } }
543 fn quux(x: i32) {
544     let y = 92;
545     m!($0);
546 }
547 "#,
548             expect![[r#"
549                 lc y       i32
550                 lc x       i32
551                 fn quux(…) fn(i32)
552                 ma m!(…)   macro_rules! m
553             "#]],
554         );
555     }
556
557     #[test]
558     fn completes_in_simple_macro_2() {
559         check(
560             r"
561 macro_rules! m { ($e:expr) => { $e } }
562 fn quux(x: i32) {
563     let y = 92;
564     m!(x$0);
565 }
566 ",
567             expect![[r#"
568                 lc y       i32
569                 lc x       i32
570                 fn quux(…) fn(i32)
571                 ma m!(…)   macro_rules! m
572             "#]],
573         );
574     }
575
576     #[test]
577     fn completes_in_simple_macro_without_closing_parens() {
578         check(
579             r#"
580 macro_rules! m { ($e:expr) => { $e } }
581 fn quux(x: i32) {
582     let y = 92;
583     m!(x$0
584 }
585 "#,
586             expect![[r#"
587                 lc y       i32
588                 lc x       i32
589                 fn quux(…) fn(i32)
590                 ma m!(…)   macro_rules! m
591             "#]],
592         );
593     }
594
595     #[test]
596     fn completes_unresolved_uses() {
597         check(
598             r#"
599 use spam::Quux;
600
601 fn main() { $0 }
602 "#,
603             expect![[r#"
604                 fn main() fn()
605                 ?? Quux
606             "#]],
607         );
608     }
609
610     #[test]
611     fn completes_enum_variant_basic_expr() {
612         check(
613             r#"
614 enum Foo { Bar, Baz, Quux }
615 fn main() { let foo: Foo = Q$0 }
616 "#,
617             expect![[r#"
618                 ev Foo::Bar  ()
619                 ev Foo::Baz  ()
620                 ev Foo::Quux ()
621                 en Foo
622                 fn main()    fn()
623             "#]],
624         )
625     }
626
627     #[test]
628     fn completes_enum_variant_from_module() {
629         check(
630             r#"
631 mod m { pub enum E { V } }
632 fn f() -> m::E { V$0 }
633 "#,
634             expect![[r#"
635                 ev m::E::V ()
636                 md m
637                 fn f()     fn() -> E
638             "#]],
639         )
640     }
641
642     #[test]
643     fn dont_complete_attr() {
644         check(
645             r#"
646 struct Foo;
647 #[$0]
648 fn f() {}
649 "#,
650             expect![[""]],
651         )
652     }
653
654     #[test]
655     fn completes_type_or_trait_in_impl_block() {
656         check(
657             r#"
658 trait MyTrait {}
659 struct MyStruct {}
660
661 impl My$0
662 "#,
663             expect![[r#"
664                 sp Self
665                 tt MyTrait
666                 st MyStruct
667             "#]],
668         )
669     }
670 }