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