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