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