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