]> git.proxmox.com Git - rustc.git/blob - src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs
New upstream version 1.69.0+dfsg1
[rustc.git] / src / tools / rust-analyzer / crates / ide-completion / src / tests / expression.rs
1 //! Completion tests for expressions.
2 use expect_test::{expect, Expect};
3
4 use crate::tests::{check_edit, completion_list, BASE_ITEMS_FIXTURE};
5
6 fn check(ra_fixture: &str, expect: Expect) {
7 let actual = completion_list(&format!("{BASE_ITEMS_FIXTURE}{ra_fixture}"));
8 expect.assert_eq(&actual)
9 }
10
11 fn check_empty(ra_fixture: &str, expect: Expect) {
12 let actual = completion_list(ra_fixture);
13 expect.assert_eq(&actual);
14 }
15
16 #[test]
17 fn complete_literal_struct_with_a_private_field() {
18 // `FooDesc.bar` is private, the completion should not be triggered.
19 check(
20 r#"
21 mod _69latrick {
22 pub struct FooDesc { pub six: bool, pub neuf: Vec<String>, bar: bool }
23 pub fn create_foo(foo_desc: &FooDesc) -> () { () }
24 }
25
26 fn baz() {
27 use _69latrick::*;
28
29 let foo = create_foo(&$0);
30 }
31 "#,
32 // This should not contain `FooDesc {…}`.
33 expect![[r#"
34 ct CONST
35 en Enum
36 fn baz() fn()
37 fn create_foo(…) fn(&FooDesc)
38 fn function() fn()
39 ma makro!(…) macro_rules! makro
40 md _69latrick
41 md module
42 sc STATIC
43 st FooDesc
44 st Record
45 st Tuple
46 st Unit
47 un Union
48 ev TupleV(…) TupleV(u32)
49 bt u32
50 kw crate::
51 kw false
52 kw for
53 kw if
54 kw if let
55 kw loop
56 kw match
57 kw mut
58 kw return
59 kw self::
60 kw true
61 kw unsafe
62 kw while
63 kw while let
64 "#]],
65 )
66 }
67
68 #[test]
69 fn completes_various_bindings() {
70 check_empty(
71 r#"
72 fn func(param0 @ (param1, param2): (i32, i32)) {
73 let letlocal = 92;
74 if let ifletlocal = 100 {
75 match 0 {
76 matcharm => 1 + $0,
77 otherwise => (),
78 }
79 }
80 let letlocal2 = 44;
81 }
82 "#,
83 expect![[r#"
84 fn func(…) fn((i32, i32))
85 lc ifletlocal i32
86 lc letlocal i32
87 lc matcharm i32
88 lc param0 (i32, i32)
89 lc param1 i32
90 lc param2 i32
91 bt u32
92 kw crate::
93 kw false
94 kw for
95 kw if
96 kw if let
97 kw loop
98 kw match
99 kw return
100 kw self::
101 kw true
102 kw unsafe
103 kw while
104 kw while let
105 "#]],
106 );
107 }
108
109 #[test]
110 fn completes_all_the_things_in_fn_body() {
111 check(
112 r#"
113 use non_existant::Unresolved;
114 mod qualified { pub enum Enum { Variant } }
115
116 impl Unit {
117 fn foo<'lifetime, TypeParam, const CONST_PARAM: usize>(self) {
118 fn local_func() {}
119 $0
120 }
121 }
122 "#,
123 // `self` is in here twice, once as the module, once as the local
124 expect![[r#"
125 ct CONST
126 cp CONST_PARAM
127 en Enum
128 fn function() fn()
129 fn local_func() fn()
130 lc self Unit
131 ma makro!(…) macro_rules! makro
132 md module
133 md qualified
134 sp Self
135 sc STATIC
136 st Record
137 st Tuple
138 st Unit
139 tp TypeParam
140 un Union
141 ev TupleV(…) TupleV(u32)
142 bt u32
143 kw const
144 kw crate::
145 kw enum
146 kw extern
147 kw false
148 kw fn
149 kw for
150 kw if
151 kw if let
152 kw impl
153 kw let
154 kw loop
155 kw match
156 kw mod
157 kw return
158 kw self::
159 kw static
160 kw struct
161 kw trait
162 kw true
163 kw type
164 kw union
165 kw unsafe
166 kw use
167 kw while
168 kw while let
169 me self.foo() fn(self)
170 sn macro_rules
171 sn pd
172 sn ppd
173 ?? Unresolved
174 "#]],
175 );
176 check(
177 r#"
178 use non_existant::Unresolved;
179 mod qualified { pub enum Enum { Variant } }
180
181 impl Unit {
182 fn foo<'lifetime, TypeParam, const CONST_PARAM: usize>(self) {
183 fn local_func() {}
184 self::$0
185 }
186 }
187 "#,
188 expect![[r#"
189 ct CONST
190 en Enum
191 fn function() fn()
192 ma makro!(…) macro_rules! makro
193 md module
194 md qualified
195 sc STATIC
196 st Record
197 st Tuple
198 st Unit
199 tt Trait
200 un Union
201 ev TupleV(…) TupleV(u32)
202 ?? Unresolved
203 "#]],
204 );
205 }
206
207 #[test]
208 fn complete_in_block() {
209 check_empty(
210 r#"
211 fn foo() {
212 if true {
213 $0
214 }
215 }
216 "#,
217 expect![[r#"
218 fn foo() fn()
219 bt u32
220 kw const
221 kw crate::
222 kw enum
223 kw extern
224 kw false
225 kw fn
226 kw for
227 kw if
228 kw if let
229 kw impl
230 kw let
231 kw loop
232 kw match
233 kw mod
234 kw return
235 kw self::
236 kw static
237 kw struct
238 kw trait
239 kw true
240 kw type
241 kw union
242 kw unsafe
243 kw use
244 kw while
245 kw while let
246 sn macro_rules
247 sn pd
248 sn ppd
249 "#]],
250 )
251 }
252
253 #[test]
254 fn complete_after_if_expr() {
255 check_empty(
256 r#"
257 fn foo() {
258 if true {}
259 $0
260 }
261 "#,
262 expect![[r#"
263 fn foo() fn()
264 bt u32
265 kw const
266 kw crate::
267 kw else
268 kw else if
269 kw enum
270 kw extern
271 kw false
272 kw fn
273 kw for
274 kw if
275 kw if let
276 kw impl
277 kw let
278 kw loop
279 kw match
280 kw mod
281 kw return
282 kw self::
283 kw static
284 kw struct
285 kw trait
286 kw true
287 kw type
288 kw union
289 kw unsafe
290 kw use
291 kw while
292 kw while let
293 sn macro_rules
294 sn pd
295 sn ppd
296 "#]],
297 )
298 }
299
300 #[test]
301 fn complete_in_match_arm() {
302 check_empty(
303 r#"
304 fn foo() {
305 match () {
306 () => $0
307 }
308 }
309 "#,
310 expect![[r#"
311 fn foo() fn()
312 bt u32
313 kw crate::
314 kw false
315 kw for
316 kw if
317 kw if let
318 kw loop
319 kw match
320 kw return
321 kw self::
322 kw true
323 kw unsafe
324 kw while
325 kw while let
326 "#]],
327 )
328 }
329
330 #[test]
331 fn completes_in_loop_ctx() {
332 check_empty(
333 r"fn my() { loop { $0 } }",
334 expect![[r#"
335 fn my() fn()
336 bt u32
337 kw break
338 kw const
339 kw continue
340 kw crate::
341 kw enum
342 kw extern
343 kw false
344 kw fn
345 kw for
346 kw if
347 kw if let
348 kw impl
349 kw let
350 kw loop
351 kw match
352 kw mod
353 kw return
354 kw self::
355 kw static
356 kw struct
357 kw trait
358 kw true
359 kw type
360 kw union
361 kw unsafe
362 kw use
363 kw while
364 kw while let
365 sn macro_rules
366 sn pd
367 sn ppd
368 "#]],
369 );
370 }
371
372 #[test]
373 fn completes_in_let_initializer() {
374 check_empty(
375 r#"fn main() { let _ = $0 }"#,
376 expect![[r#"
377 fn main() fn()
378 bt u32
379 kw crate::
380 kw false
381 kw for
382 kw if
383 kw if let
384 kw loop
385 kw match
386 kw return
387 kw self::
388 kw true
389 kw unsafe
390 kw while
391 kw while let
392 "#]],
393 )
394 }
395
396 #[test]
397 fn struct_initializer_field_expr() {
398 check_empty(
399 r#"
400 struct Foo {
401 pub f: i32,
402 }
403 fn foo() {
404 Foo {
405 f: $0
406 }
407 }
408 "#,
409 expect![[r#"
410 fn foo() fn()
411 st Foo
412 bt u32
413 kw crate::
414 kw false
415 kw for
416 kw if
417 kw if let
418 kw loop
419 kw match
420 kw return
421 kw self::
422 kw true
423 kw unsafe
424 kw while
425 kw while let
426 "#]],
427 );
428 }
429
430 #[test]
431 fn shadowing_shows_single_completion() {
432 cov_mark::check!(shadowing_shows_single_completion);
433
434 check_empty(
435 r#"
436 fn foo() {
437 let bar = 92;
438 {
439 let bar = 62;
440 drop($0)
441 }
442 }
443 "#,
444 expect![[r#"
445 fn foo() fn()
446 lc bar i32
447 bt u32
448 kw crate::
449 kw false
450 kw for
451 kw if
452 kw if let
453 kw loop
454 kw match
455 kw return
456 kw self::
457 kw true
458 kw unsafe
459 kw while
460 kw while let
461 "#]],
462 );
463 }
464
465 #[test]
466 fn in_macro_expr_frag() {
467 check_empty(
468 r#"
469 macro_rules! m { ($e:expr) => { $e } }
470 fn quux(x: i32) {
471 m!($0);
472 }
473 "#,
474 expect![[r#"
475 fn quux(…) fn(i32)
476 lc x i32
477 ma m!(…) macro_rules! m
478 bt u32
479 kw crate::
480 kw false
481 kw for
482 kw if
483 kw if let
484 kw loop
485 kw match
486 kw return
487 kw self::
488 kw true
489 kw unsafe
490 kw while
491 kw while let
492 "#]],
493 );
494 check_empty(
495 r"
496 macro_rules! m { ($e:expr) => { $e } }
497 fn quux(x: i32) {
498 m!(x$0);
499 }
500 ",
501 expect![[r#"
502 fn quux(…) fn(i32)
503 lc x i32
504 ma m!(…) macro_rules! m
505 bt u32
506 kw crate::
507 kw false
508 kw for
509 kw if
510 kw if let
511 kw loop
512 kw match
513 kw return
514 kw self::
515 kw true
516 kw unsafe
517 kw while
518 kw while let
519 "#]],
520 );
521 check_empty(
522 r#"
523 macro_rules! m { ($e:expr) => { $e } }
524 fn quux(x: i32) {
525 let y = 92;
526 m!(x$0
527 }
528 "#,
529 expect![[r#""#]],
530 );
531 }
532
533 #[test]
534 fn enum_qualified() {
535 check(
536 r#"
537 impl Enum {
538 type AssocType = ();
539 const ASSOC_CONST: () = ();
540 fn assoc_fn() {}
541 }
542 fn func() {
543 Enum::$0
544 }
545 "#,
546 expect![[r#"
547 ct ASSOC_CONST const ASSOC_CONST: ()
548 fn assoc_fn() fn()
549 ta AssocType type AssocType = ()
550 ev RecordV {…} RecordV { field: u32 }
551 ev TupleV(…) TupleV(u32)
552 ev UnitV UnitV
553 "#]],
554 );
555 }
556
557 #[test]
558 fn ty_qualified_no_drop() {
559 check_empty(
560 r#"
561 //- minicore: drop
562 struct Foo;
563 impl Drop for Foo {
564 fn drop(&mut self) {}
565 }
566 fn func() {
567 Foo::$0
568 }
569 "#,
570 expect![[r#""#]],
571 );
572 }
573
574 #[test]
575 fn with_parens() {
576 check_empty(
577 r#"
578 enum Enum {
579 Variant()
580 }
581 impl Enum {
582 fn variant() -> Self { Enum::Variant() }
583 }
584 fn func() {
585 Enum::$0()
586 }
587 "#,
588 expect![[r#"
589 fn variant fn() -> Enum
590 ev Variant Variant
591 "#]],
592 );
593 }
594
595 #[test]
596 fn detail_impl_trait_in_return_position() {
597 check_empty(
598 r"
599 //- minicore: sized
600 trait Trait<T> {}
601 fn foo<U>() -> impl Trait<U> {}
602 fn main() {
603 self::$0
604 }
605 ",
606 expect![[r#"
607 fn foo() fn() -> impl Trait<U>
608 fn main() fn()
609 tt Trait
610 "#]],
611 );
612 }
613
614 #[test]
615 fn detail_async_fn() {
616 check_empty(
617 r#"
618 //- minicore: future, sized
619 trait Trait<T> {}
620 async fn foo() -> u8 {}
621 async fn bar<U>() -> impl Trait<U> {}
622 fn main() {
623 self::$0
624 }
625 "#,
626 expect![[r#"
627 fn bar() async fn() -> impl Trait<U>
628 fn foo() async fn() -> u8
629 fn main() fn()
630 tt Trait
631 "#]],
632 );
633 }
634
635 #[test]
636 fn detail_impl_trait_in_argument_position() {
637 check_empty(
638 r"
639 //- minicore: sized
640 trait Trait<T> {}
641 struct Foo;
642 impl Foo {
643 fn bar<U>(_: impl Trait<U>) {}
644 }
645 fn main() {
646 Foo::$0
647 }
648 ",
649 expect![[r"
650 fn bar(…) fn(impl Trait<U>)
651 "]],
652 );
653 }
654
655 #[test]
656 fn complete_record_expr_path() {
657 check(
658 r#"
659 struct Zulu;
660 impl Zulu {
661 fn test() -> Self { }
662 }
663 fn boi(val: Zulu) { }
664 fn main() {
665 boi(Zulu:: $0 {});
666 }
667 "#,
668 expect![[r#"
669 fn test() fn() -> Zulu
670 "#]],
671 );
672 }
673
674 #[test]
675 fn varaiant_with_struct() {
676 check_empty(
677 r#"
678 pub struct YoloVariant {
679 pub f: usize
680 }
681
682 pub enum HH {
683 Yolo(YoloVariant),
684 }
685
686 fn brr() {
687 let t = HH::Yolo(Y$0);
688 }
689 "#,
690 expect![[r#"
691 en HH
692 fn brr() fn()
693 st YoloVariant
694 st YoloVariant {…} YoloVariant { f: usize }
695 bt u32
696 kw crate::
697 kw false
698 kw for
699 kw if
700 kw if let
701 kw loop
702 kw match
703 kw return
704 kw self::
705 kw true
706 kw unsafe
707 kw while
708 kw while let
709 "#]],
710 );
711 }
712
713 #[test]
714 fn return_unit_block() {
715 cov_mark::check!(return_unit_block);
716 check_edit("return", r#"fn f() { if true { $0 } }"#, r#"fn f() { if true { return; } }"#);
717 }
718
719 #[test]
720 fn return_unit_no_block() {
721 cov_mark::check!(return_unit_no_block);
722 check_edit(
723 "return",
724 r#"fn f() { match () { () => $0 } }"#,
725 r#"fn f() { match () { () => return } }"#,
726 );
727 }
728
729 #[test]
730 fn return_value_block() {
731 cov_mark::check!(return_value_block);
732 check_edit(
733 "return",
734 r#"fn f() -> i32 { if true { $0 } }"#,
735 r#"fn f() -> i32 { if true { return $0; } }"#,
736 );
737 }
738
739 #[test]
740 fn return_value_no_block() {
741 cov_mark::check!(return_value_no_block);
742 check_edit(
743 "return",
744 r#"fn f() -> i32 { match () { () => $0 } }"#,
745 r#"fn f() -> i32 { match () { () => return $0 } }"#,
746 );
747 }
748
749 #[test]
750 fn else_completion_after_if() {
751 check_empty(
752 r#"
753 fn foo() { if foo {} $0 }
754 "#,
755 expect![[r#"
756 fn foo() fn()
757 bt u32
758 kw const
759 kw crate::
760 kw else
761 kw else if
762 kw enum
763 kw extern
764 kw false
765 kw fn
766 kw for
767 kw if
768 kw if let
769 kw impl
770 kw let
771 kw loop
772 kw match
773 kw mod
774 kw return
775 kw self::
776 kw static
777 kw struct
778 kw trait
779 kw true
780 kw type
781 kw union
782 kw unsafe
783 kw use
784 kw while
785 kw while let
786 sn macro_rules
787 sn pd
788 sn ppd
789 "#]],
790 );
791 check_empty(
792 r#"
793 fn foo() { if foo {} el$0 }
794 "#,
795 expect![[r#"
796 fn foo() fn()
797 bt u32
798 kw const
799 kw crate::
800 kw else
801 kw else if
802 kw enum
803 kw extern
804 kw false
805 kw fn
806 kw for
807 kw if
808 kw if let
809 kw impl
810 kw let
811 kw loop
812 kw match
813 kw mod
814 kw return
815 kw self::
816 kw static
817 kw struct
818 kw trait
819 kw true
820 kw type
821 kw union
822 kw unsafe
823 kw use
824 kw while
825 kw while let
826 sn macro_rules
827 sn pd
828 sn ppd
829 "#]],
830 );
831 check_empty(
832 r#"
833 fn foo() { bar(if foo {} $0) }
834 "#,
835 expect![[r#"
836 fn foo() fn()
837 bt u32
838 kw crate::
839 kw else
840 kw else if
841 kw false
842 kw for
843 kw if
844 kw if let
845 kw loop
846 kw match
847 kw return
848 kw self::
849 kw true
850 kw unsafe
851 kw while
852 kw while let
853 "#]],
854 );
855 check_empty(
856 r#"
857 fn foo() { bar(if foo {} el$0) }
858 "#,
859 expect![[r#"
860 fn foo() fn()
861 bt u32
862 kw crate::
863 kw else
864 kw else if
865 kw false
866 kw for
867 kw if
868 kw if let
869 kw loop
870 kw match
871 kw return
872 kw self::
873 kw true
874 kw unsafe
875 kw while
876 kw while let
877 "#]],
878 );
879 check_empty(
880 r#"
881 fn foo() { if foo {} $0 let x = 92; }
882 "#,
883 expect![[r#"
884 fn foo() fn()
885 bt u32
886 kw const
887 kw crate::
888 kw else
889 kw else if
890 kw enum
891 kw extern
892 kw false
893 kw fn
894 kw for
895 kw if
896 kw if let
897 kw impl
898 kw let
899 kw loop
900 kw match
901 kw mod
902 kw return
903 kw self::
904 kw static
905 kw struct
906 kw trait
907 kw true
908 kw type
909 kw union
910 kw unsafe
911 kw use
912 kw while
913 kw while let
914 sn macro_rules
915 sn pd
916 sn ppd
917 "#]],
918 );
919 check_empty(
920 r#"
921 fn foo() { if foo {} el$0 let x = 92; }
922 "#,
923 expect![[r#"
924 fn foo() fn()
925 bt u32
926 kw const
927 kw crate::
928 kw else
929 kw else if
930 kw enum
931 kw extern
932 kw false
933 kw fn
934 kw for
935 kw if
936 kw if let
937 kw impl
938 kw let
939 kw loop
940 kw match
941 kw mod
942 kw return
943 kw self::
944 kw static
945 kw struct
946 kw trait
947 kw true
948 kw type
949 kw union
950 kw unsafe
951 kw use
952 kw while
953 kw while let
954 sn macro_rules
955 sn pd
956 sn ppd
957 "#]],
958 );
959 check_empty(
960 r#"
961 fn foo() { if foo {} el$0 { let x = 92; } }
962 "#,
963 expect![[r#"
964 fn foo() fn()
965 bt u32
966 kw const
967 kw crate::
968 kw else
969 kw else if
970 kw enum
971 kw extern
972 kw false
973 kw fn
974 kw for
975 kw if
976 kw if let
977 kw impl
978 kw let
979 kw loop
980 kw match
981 kw mod
982 kw return
983 kw self::
984 kw static
985 kw struct
986 kw trait
987 kw true
988 kw type
989 kw union
990 kw unsafe
991 kw use
992 kw while
993 kw while let
994 sn macro_rules
995 sn pd
996 sn ppd
997 "#]],
998 );
999 }