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