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