]> git.lizzy.rs Git - rust.git/blob - crates/ide_completion/src/completions/dot.rs
Merge #11393
[rust.git] / crates / ide_completion / src / completions / dot.rs
1 //! Completes references after dot (fields and method calls).
2
3 use either::Either;
4 use rustc_hash::FxHashSet;
5
6 use crate::{context::CompletionContext, patterns::ImmediateLocation, Completions};
7
8 /// Complete dot accesses, i.e. fields or methods.
9 pub(crate) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
10     let dot_receiver = match ctx.dot_receiver() {
11         Some(expr) => expr,
12         _ => return complete_undotted_self(acc, ctx),
13     };
14
15     let receiver_ty = match ctx.sema.type_of_expr(dot_receiver) {
16         Some(ty) => ty.original,
17         _ => return,
18     };
19
20     if matches!(ctx.completion_location, Some(ImmediateLocation::MethodCall { .. })) {
21         cov_mark::hit!(test_no_struct_field_completion_for_method_call);
22     } else {
23         complete_fields(ctx, &receiver_ty, |field, ty| match field {
24             Either::Left(field) => acc.add_field(ctx, None, field, &ty),
25             Either::Right(tuple_idx) => acc.add_tuple_field(ctx, None, tuple_idx, &ty),
26         });
27     }
28     complete_methods(ctx, &receiver_ty, |func| acc.add_method(ctx, func, None, None));
29 }
30
31 fn complete_undotted_self(acc: &mut Completions, ctx: &CompletionContext) {
32     if !ctx.config.enable_self_on_the_fly {
33         return;
34     }
35     if !ctx.is_trivial_path() || ctx.is_path_disallowed() || !ctx.expects_expression() {
36         return;
37     }
38     if let Some(func) = ctx.function_def.as_ref().and_then(|fn_| ctx.sema.to_def(fn_)) {
39         if let Some(self_) = func.self_param(ctx.db) {
40             let ty = self_.ty(ctx.db);
41             complete_fields(ctx, &ty, |field, ty| match field {
42                 either::Either::Left(field) => {
43                     acc.add_field(ctx, Some(hir::known::SELF_PARAM), field, &ty)
44                 }
45                 either::Either::Right(tuple_idx) => {
46                     acc.add_tuple_field(ctx, Some(hir::known::SELF_PARAM), tuple_idx, &ty)
47                 }
48             });
49             complete_methods(ctx, &ty, |func| {
50                 acc.add_method(ctx, func, Some(hir::known::SELF_PARAM), None)
51             });
52         }
53     }
54 }
55
56 fn complete_fields(
57     ctx: &CompletionContext,
58     receiver: &hir::Type,
59     mut f: impl FnMut(Either<hir::Field, usize>, hir::Type),
60 ) {
61     for receiver in receiver.autoderef(ctx.db) {
62         for (field, ty) in receiver.fields(ctx.db) {
63             f(Either::Left(field), ty);
64         }
65         for (i, ty) in receiver.tuple_fields(ctx.db).into_iter().enumerate() {
66             // Tuple fields are always public (tuple struct fields are handled above).
67             f(Either::Right(i), ty);
68         }
69     }
70 }
71
72 fn complete_methods(
73     ctx: &CompletionContext,
74     receiver: &hir::Type,
75     mut f: impl FnMut(hir::Function),
76 ) {
77     if let Some(krate) = ctx.krate {
78         let mut seen_methods = FxHashSet::default();
79         let mut traits_in_scope = ctx.scope.visible_traits();
80
81         // Remove drop from the environment as calling `Drop::drop` is not allowed
82         if let Some(drop_trait) = ctx.famous_defs().core_ops_Drop() {
83             cov_mark::hit!(dot_remove_drop_trait);
84             traits_in_scope.remove(&drop_trait.into());
85         }
86
87         receiver.iterate_method_candidates(
88             ctx.db,
89             krate,
90             &traits_in_scope,
91             ctx.module,
92             None,
93             |_ty, func| {
94                 if func.self_param(ctx.db).is_some() && seen_methods.insert(func.name(ctx.db)) {
95                     f(func);
96                 }
97                 None::<()>
98             },
99         );
100     }
101 }
102
103 #[cfg(test)]
104 mod tests {
105     use expect_test::{expect, Expect};
106
107     use crate::tests::{check_edit, completion_list_no_kw};
108
109     fn check(ra_fixture: &str, expect: Expect) {
110         let actual = completion_list_no_kw(ra_fixture);
111         expect.assert_eq(&actual);
112     }
113
114     #[test]
115     fn test_struct_field_and_method_completion() {
116         check(
117             r#"
118 struct S { foo: u32 }
119 impl S {
120     fn bar(&self) {}
121 }
122 fn foo(s: S) { s.$0 }
123 "#,
124             expect![[r#"
125                 fd foo   u32
126                 me bar() fn(&self)
127             "#]],
128         );
129     }
130
131     #[test]
132     fn test_struct_field_completion_self() {
133         check(
134             r#"
135 struct S { the_field: (u32,) }
136 impl S {
137     fn foo(self) { self.$0 }
138 }
139 "#,
140             expect![[r#"
141                 fd the_field (u32,)
142                 me foo()     fn(self)
143             "#]],
144         )
145     }
146
147     #[test]
148     fn test_struct_field_completion_autoderef() {
149         check(
150             r#"
151 struct A { the_field: (u32, i32) }
152 impl A {
153     fn foo(&self) { self.$0 }
154 }
155 "#,
156             expect![[r#"
157                 fd the_field (u32, i32)
158                 me foo()     fn(&self)
159             "#]],
160         )
161     }
162
163     #[test]
164     fn test_no_struct_field_completion_for_method_call() {
165         cov_mark::check!(test_no_struct_field_completion_for_method_call);
166         check(
167             r#"
168 struct A { the_field: u32 }
169 fn foo(a: A) { a.$0() }
170 "#,
171             expect![[r#""#]],
172         );
173     }
174
175     #[test]
176     fn test_visibility_filtering() {
177         check(
178             r#"
179 //- /lib.rs crate:lib new_source_root:local
180 pub mod m {
181     pub struct A {
182         private_field: u32,
183         pub pub_field: u32,
184         pub(crate) crate_field: u32,
185         pub(super) super_field: u32,
186     }
187 }
188 //- /main.rs crate:main deps:lib new_source_root:local
189 fn foo(a: lib::m::A) { a.$0 }
190 "#,
191             expect![[r#"
192                 fd private_field u32
193                 fd pub_field     u32
194                 fd crate_field   u32
195                 fd super_field   u32
196             "#]],
197         );
198
199         check(
200             r#"
201 //- /lib.rs crate:lib new_source_root:library
202 pub mod m {
203     pub struct A {
204         private_field: u32,
205         pub pub_field: u32,
206         pub(crate) crate_field: u32,
207         pub(super) super_field: u32,
208     }
209 }
210 //- /main.rs crate:main deps:lib new_source_root:local
211 fn foo(a: lib::m::A) { a.$0 }
212 "#,
213             expect![[r#"
214                 fd pub_field u32
215             "#]],
216         );
217
218         check(
219             r#"
220 //- /lib.rs crate:lib new_source_root:library
221 pub mod m {
222     pub struct A(
223         i32,
224         pub f64,
225     );
226 }
227 //- /main.rs crate:main deps:lib new_source_root:local
228 fn foo(a: lib::m::A) { a.$0 }
229 "#,
230             expect![[r#"
231                 fd 1 f64
232             "#]],
233         );
234
235         check(
236             r#"
237 //- /lib.rs crate:lib new_source_root:local
238 pub struct A {}
239 mod m {
240     impl super::A {
241         fn private_method(&self) {}
242         pub(crate) fn crate_method(&self) {}
243         pub fn pub_method(&self) {}
244     }
245 }
246 //- /main.rs crate:main deps:lib new_source_root:local
247 fn foo(a: lib::A) { a.$0 }
248 "#,
249             expect![[r#"
250                 me private_method() fn(&self)
251                 me crate_method()   fn(&self)
252                 me pub_method()     fn(&self)
253             "#]],
254         );
255         check(
256             r#"
257 //- /lib.rs crate:lib new_source_root:library
258 pub struct A {}
259 mod m {
260     impl super::A {
261         fn private_method(&self) {}
262         pub(crate) fn crate_method(&self) {}
263         pub fn pub_method(&self) {}
264     }
265 }
266 //- /main.rs crate:main deps:lib new_source_root:local
267 fn foo(a: lib::A) { a.$0 }
268 "#,
269             expect![[r#"
270                 me pub_method() fn(&self)
271             "#]],
272         );
273     }
274
275     #[test]
276     fn test_local_impls() {
277         check(
278             r#"
279 //- /lib.rs crate:lib
280 pub struct A {}
281 mod m {
282     impl super::A {
283         pub fn pub_module_method(&self) {}
284     }
285     fn f() {
286         impl super::A {
287             pub fn pub_foreign_local_method(&self) {}
288         }
289     }
290 }
291 //- /main.rs crate:main deps:lib
292 fn foo(a: lib::A) {
293     impl lib::A {
294         fn local_method(&self) {}
295     }
296     a.$0
297 }
298 "#,
299             expect![[r#"
300                 me local_method()      fn(&self)
301                 me pub_module_method() fn(&self)
302             "#]],
303         );
304     }
305
306     #[test]
307     fn test_doc_hidden_filtering() {
308         check(
309             r#"
310 //- /lib.rs crate:lib deps:dep
311 fn foo(a: dep::A) { a.$0 }
312 //- /dep.rs crate:dep
313 pub struct A {
314     #[doc(hidden)]
315     pub hidden_field: u32,
316     pub pub_field: u32,
317 }
318
319 impl A {
320     pub fn pub_method(&self) {}
321
322     #[doc(hidden)]
323     pub fn hidden_method(&self) {}
324 }
325             "#,
326             expect![[r#"
327                 fd pub_field    u32
328                 me pub_method() fn(&self)
329             "#]],
330         )
331     }
332
333     #[test]
334     fn test_union_field_completion() {
335         check(
336             r#"
337 union U { field: u8, other: u16 }
338 fn foo(u: U) { u.$0 }
339 "#,
340             expect![[r#"
341                 fd field u8
342                 fd other u16
343             "#]],
344         );
345     }
346
347     #[test]
348     fn test_method_completion_only_fitting_impls() {
349         check(
350             r#"
351 struct A<T> {}
352 impl A<u32> {
353     fn the_method(&self) {}
354 }
355 impl A<i32> {
356     fn the_other_method(&self) {}
357 }
358 fn foo(a: A<u32>) { a.$0 }
359 "#,
360             expect![[r#"
361                 me the_method() fn(&self)
362             "#]],
363         )
364     }
365
366     #[test]
367     fn test_trait_method_completion() {
368         check(
369             r#"
370 struct A {}
371 trait Trait { fn the_method(&self); }
372 impl Trait for A {}
373 fn foo(a: A) { a.$0 }
374 "#,
375             expect![[r#"
376                 me the_method() (as Trait) fn(&self)
377             "#]],
378         );
379         check_edit(
380             "the_method",
381             r#"
382 struct A {}
383 trait Trait { fn the_method(&self); }
384 impl Trait for A {}
385 fn foo(a: A) { a.$0 }
386 "#,
387             r#"
388 struct A {}
389 trait Trait { fn the_method(&self); }
390 impl Trait for A {}
391 fn foo(a: A) { a.the_method()$0 }
392 "#,
393         );
394     }
395
396     #[test]
397     fn test_trait_method_completion_deduplicated() {
398         check(
399             r"
400 struct A {}
401 trait Trait { fn the_method(&self); }
402 impl<T> Trait for T {}
403 fn foo(a: &A) { a.$0 }
404 ",
405             expect![[r#"
406                 me the_method() (as Trait) fn(&self)
407             "#]],
408         );
409     }
410
411     #[test]
412     fn completes_trait_method_from_other_module() {
413         check(
414             r"
415 struct A {}
416 mod m {
417     pub trait Trait { fn the_method(&self); }
418 }
419 use m::Trait;
420 impl Trait for A {}
421 fn foo(a: A) { a.$0 }
422 ",
423             expect![[r#"
424                 me the_method() (as Trait) fn(&self)
425             "#]],
426         );
427     }
428
429     #[test]
430     fn test_no_non_self_method() {
431         check(
432             r#"
433 struct A {}
434 impl A {
435     fn the_method() {}
436 }
437 fn foo(a: A) {
438    a.$0
439 }
440 "#,
441             expect![[r#""#]],
442         );
443     }
444
445     #[test]
446     fn test_tuple_field_completion() {
447         check(
448             r#"
449 fn foo() {
450    let b = (0, 3.14);
451    b.$0
452 }
453 "#,
454             expect![[r#"
455                 fd 0 i32
456                 fd 1 f64
457             "#]],
458         );
459     }
460
461     #[test]
462     fn test_tuple_struct_field_completion() {
463         check(
464             r#"
465 struct S(i32, f64);
466 fn foo() {
467    let b = S(0, 3.14);
468    b.$0
469 }
470 "#,
471             expect![[r#"
472                 fd 0 i32
473                 fd 1 f64
474             "#]],
475         );
476     }
477
478     #[test]
479     fn test_tuple_field_inference() {
480         check(
481             r#"
482 pub struct S;
483 impl S { pub fn blah(&self) {} }
484
485 struct T(S);
486
487 impl T {
488     fn foo(&self) {
489         // FIXME: This doesn't work without the trailing `a` as `0.` is a float
490         self.0.a$0
491     }
492 }
493 "#,
494             expect![[r#"
495                 me blah() fn(&self)
496             "#]],
497         );
498     }
499
500     #[test]
501     fn test_completion_works_in_consts() {
502         check(
503             r#"
504 struct A { the_field: u32 }
505 const X: u32 = {
506     A { the_field: 92 }.$0
507 };
508 "#,
509             expect![[r#"
510                 fd the_field u32
511             "#]],
512         );
513     }
514
515     #[test]
516     fn works_in_simple_macro_1() {
517         check(
518             r#"
519 macro_rules! m { ($e:expr) => { $e } }
520 struct A { the_field: u32 }
521 fn foo(a: A) {
522     m!(a.x$0)
523 }
524 "#,
525             expect![[r#"
526                 fd the_field u32
527             "#]],
528         );
529     }
530
531     #[test]
532     fn works_in_simple_macro_2() {
533         // this doesn't work yet because the macro doesn't expand without the token -- maybe it can be fixed with better recovery
534         check(
535             r#"
536 macro_rules! m { ($e:expr) => { $e } }
537 struct A { the_field: u32 }
538 fn foo(a: A) {
539     m!(a.$0)
540 }
541 "#,
542             expect![[r#"
543                 fd the_field u32
544             "#]],
545         );
546     }
547
548     #[test]
549     fn works_in_simple_macro_recursive_1() {
550         check(
551             r#"
552 macro_rules! m { ($e:expr) => { $e } }
553 struct A { the_field: u32 }
554 fn foo(a: A) {
555     m!(m!(m!(a.x$0)))
556 }
557 "#,
558             expect![[r#"
559                 fd the_field u32
560             "#]],
561         );
562     }
563
564     #[test]
565     fn macro_expansion_resilient() {
566         check(
567             r#"
568 macro_rules! d {
569     () => {};
570     ($val:expr) => {
571         match $val { tmp => { tmp } }
572     };
573     // Trailing comma with single argument is ignored
574     ($val:expr,) => { $crate::d!($val) };
575     ($($val:expr),+ $(,)?) => {
576         ($($crate::d!($val)),+,)
577     };
578 }
579 struct A { the_field: u32 }
580 fn foo(a: A) {
581     d!(a.$0)
582 }
583 "#,
584             expect![[r#"
585                 fd the_field u32
586             "#]],
587         );
588     }
589
590     #[test]
591     fn test_method_completion_issue_3547() {
592         check(
593             r#"
594 struct HashSet<T> {}
595 impl<T> HashSet<T> {
596     pub fn the_method(&self) {}
597 }
598 fn foo() {
599     let s: HashSet<_>;
600     s.$0
601 }
602 "#,
603             expect![[r#"
604                 me the_method() fn(&self)
605             "#]],
606         );
607     }
608
609     #[test]
610     fn completes_method_call_when_receiver_is_a_macro_call() {
611         check(
612             r#"
613 struct S;
614 impl S { fn foo(&self) {} }
615 macro_rules! make_s { () => { S }; }
616 fn main() { make_s!().f$0; }
617 "#,
618             expect![[r#"
619                 me foo() fn(&self)
620             "#]],
621         )
622     }
623
624     #[test]
625     fn completes_after_macro_call_in_submodule() {
626         check(
627             r#"
628 macro_rules! empty {
629     () => {};
630 }
631
632 mod foo {
633     #[derive(Debug, Default)]
634     struct Template2 {}
635
636     impl Template2 {
637         fn private(&self) {}
638     }
639     fn baz() {
640         let goo: Template2 = Template2 {};
641         empty!();
642         goo.$0
643     }
644 }
645         "#,
646             expect![[r#"
647                 me private() fn(&self)
648             "#]],
649         );
650     }
651
652     #[test]
653     fn issue_8931() {
654         check(
655             r#"
656 //- minicore: fn
657 struct S;
658
659 struct Foo;
660 impl Foo {
661     fn foo(&self) -> &[u8] { loop {} }
662 }
663
664 impl S {
665     fn indented(&mut self, f: impl FnOnce(&mut Self)) {
666     }
667
668     fn f(&mut self, v: Foo) {
669         self.indented(|this| v.$0)
670     }
671 }
672         "#,
673             expect![[r#"
674                 me foo() fn(&self) -> &[u8]
675             "#]],
676         );
677     }
678
679     #[test]
680     fn completes_bare_fields_and_methods_in_methods() {
681         check(
682             r#"
683 struct Foo { field: i32 }
684
685 impl Foo { fn foo(&self) { $0 } }"#,
686             expect![[r#"
687                 lc self       &Foo
688                 sp Self
689                 st Foo
690                 bt u32
691                 fd self.field i32
692                 me self.foo() fn(&self)
693             "#]],
694         );
695         check(
696             r#"
697 struct Foo(i32);
698
699 impl Foo { fn foo(&mut self) { $0 } }"#,
700             expect![[r#"
701                 lc self       &mut Foo
702                 sp Self
703                 st Foo
704                 bt u32
705                 fd self.0     i32
706                 me self.foo() fn(&mut self)
707             "#]],
708         );
709     }
710
711     #[test]
712     fn macro_completion_after_dot() {
713         check(
714             r#"
715 macro_rules! m {
716     ($e:expr) => { $e };
717 }
718
719 struct Completable;
720
721 impl Completable {
722     fn method(&self) {}
723 }
724
725 fn f() {
726     let c = Completable;
727     m!(c.$0);
728 }
729     "#,
730             expect![[r#"
731                 me method() fn(&self)
732             "#]],
733         );
734     }
735
736     #[test]
737     fn completes_method_call_when_receiver_type_has_errors_issue_10297() {
738         check(
739             r#"
740 //- minicore: iterator, sized
741 struct Vec<T>;
742 impl<T> IntoIterator for Vec<T> {
743     type Item = ();
744     type IntoIter = ();
745     fn into_iter(self);
746 }
747 fn main() {
748     let x: Vec<_>;
749     x.$0;
750 }
751 "#,
752             expect![[r#"
753                 me into_iter() (as IntoIterator) fn(self) -> <Self as IntoIterator>::IntoIter
754             "#]],
755         )
756     }
757
758     #[test]
759     fn postfix_drop_completion() {
760         cov_mark::check!(dot_remove_drop_trait);
761         cov_mark::check!(postfix_drop_completion);
762         check_edit(
763             "drop",
764             r#"
765 //- minicore: drop
766 struct Vec<T>(T);
767 impl<T> Drop for Vec<T> {
768     fn drop(&mut self) {}
769 }
770 fn main() {
771     let x = Vec(0u32)
772     x.$0;
773 }
774 "#,
775             r"
776 struct Vec<T>(T);
777 impl<T> Drop for Vec<T> {
778     fn drop(&mut self) {}
779 }
780 fn main() {
781     let x = Vec(0u32)
782     drop($0x);
783 }
784 ",
785         )
786     }
787 }