]> git.proxmox.com Git - rustc.git/blob - src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs
New upstream version 1.69.0+dfsg1
[rustc.git] / src / tools / rust-analyzer / crates / ide-completion / src / tests / special.rs
1 //! Tests that don't fit into a specific category.
2
3 use expect_test::{expect, Expect};
4
5 use crate::tests::{
6 check_edit, completion_list, completion_list_no_kw, completion_list_with_trigger_character,
7 };
8
9 fn check_no_kw(ra_fixture: &str, expect: Expect) {
10 let actual = completion_list_no_kw(ra_fixture);
11 expect.assert_eq(&actual)
12 }
13
14 fn check(ra_fixture: &str, expect: Expect) {
15 let actual = completion_list(ra_fixture);
16 expect.assert_eq(&actual)
17 }
18
19 pub(crate) fn check_with_trigger_character(
20 ra_fixture: &str,
21 trigger_character: Option<char>,
22 expect: Expect,
23 ) {
24 let actual = completion_list_with_trigger_character(ra_fixture, trigger_character);
25 expect.assert_eq(&actual)
26 }
27
28 #[test]
29 fn completes_if_prefix_is_keyword() {
30 check_edit(
31 "wherewolf",
32 r#"
33 fn main() {
34 let wherewolf = 92;
35 drop(where$0)
36 }
37 "#,
38 r#"
39 fn main() {
40 let wherewolf = 92;
41 drop(wherewolf)
42 }
43 "#,
44 )
45 }
46
47 /// Regression test for issue #6091.
48 #[test]
49 fn correctly_completes_module_items_prefixed_with_underscore() {
50 check_edit(
51 "_alpha",
52 r#"
53 fn main() {
54 _$0
55 }
56 fn _alpha() {}
57 "#,
58 r#"
59 fn main() {
60 _alpha()$0
61 }
62 fn _alpha() {}
63 "#,
64 )
65 }
66
67 #[test]
68 fn completes_prelude() {
69 check_no_kw(
70 r#"
71 //- /main.rs edition:2018 crate:main deps:std
72 fn foo() { let x: $0 }
73
74 //- /std/lib.rs crate:std
75 pub mod prelude {
76 pub mod rust_2018 {
77 pub struct Option;
78 }
79 }
80 "#,
81 expect![[r#"
82 md std
83 st Option
84 bt u32
85 "#]],
86 );
87 }
88
89 #[test]
90 fn completes_prelude_macros() {
91 check_no_kw(
92 r#"
93 //- /main.rs edition:2018 crate:main deps:std
94 fn f() {$0}
95
96 //- /std/lib.rs crate:std
97 pub mod prelude {
98 pub mod rust_2018 {
99 pub use crate::concat;
100 }
101 }
102
103 mod macros {
104 #[rustc_builtin_macro]
105 #[macro_export]
106 macro_rules! concat { }
107 }
108 "#,
109 expect![[r#"
110 fn f() fn()
111 ma concat!(…) macro_rules! concat
112 md std
113 bt u32
114 "#]],
115 );
116 }
117
118 #[test]
119 fn completes_std_prelude_if_core_is_defined() {
120 check_no_kw(
121 r#"
122 //- /main.rs crate:main deps:core,std
123 fn foo() { let x: $0 }
124
125 //- /core/lib.rs crate:core
126 pub mod prelude {
127 pub mod rust_2021 {
128 pub struct Option;
129 }
130 }
131
132 //- /std/lib.rs crate:std deps:core
133 pub mod prelude {
134 pub mod rust_2021 {
135 pub struct String;
136 }
137 }
138 "#,
139 expect![[r#"
140 md core
141 md std
142 st String
143 bt u32
144 "#]],
145 );
146 }
147
148 #[test]
149 fn respects_doc_hidden() {
150 check_no_kw(
151 r#"
152 //- /lib.rs crate:lib deps:std
153 fn f() {
154 format_$0
155 }
156
157 //- /std.rs crate:std
158 #[doc(hidden)]
159 #[macro_export]
160 macro_rules! format_args_nl {
161 () => {}
162 }
163
164 pub mod prelude {
165 pub mod rust_2018 {}
166 }
167 "#,
168 expect![[r#"
169 fn f() fn()
170 md std
171 bt u32
172 "#]],
173 );
174 }
175
176 #[test]
177 fn respects_doc_hidden_in_assoc_item_list() {
178 check_no_kw(
179 r#"
180 //- /lib.rs crate:lib deps:std
181 struct S;
182 impl S {
183 format_$0
184 }
185
186 //- /std.rs crate:std
187 #[doc(hidden)]
188 #[macro_export]
189 macro_rules! format_args_nl {
190 () => {}
191 }
192
193 pub mod prelude {
194 pub mod rust_2018 {}
195 }
196 "#,
197 expect![[r#"
198 md std
199 "#]],
200 );
201 }
202
203 #[test]
204 fn associated_item_visibility() {
205 check_no_kw(
206 r#"
207 //- /lib.rs crate:lib new_source_root:library
208 pub struct S;
209
210 impl S {
211 pub fn public_method() { }
212 fn private_method() { }
213 pub type PublicType = u32;
214 type PrivateType = u32;
215 pub const PUBLIC_CONST: u32 = 1;
216 const PRIVATE_CONST: u32 = 1;
217 }
218
219 //- /main.rs crate:main deps:lib new_source_root:local
220 fn foo() { let _ = lib::S::$0 }
221 "#,
222 expect![[r#"
223 ct PUBLIC_CONST pub const PUBLIC_CONST: u32
224 fn public_method() fn()
225 ta PublicType pub type PublicType = u32
226 "#]],
227 );
228 }
229
230 #[test]
231 fn completes_union_associated_method() {
232 check_no_kw(
233 r#"
234 union U {};
235 impl U { fn m() { } }
236
237 fn foo() { let _ = U::$0 }
238 "#,
239 expect![[r#"
240 fn m() fn()
241 "#]],
242 );
243 }
244
245 #[test]
246 fn completes_trait_associated_method_1() {
247 check_no_kw(
248 r#"
249 trait Trait { fn m(); }
250
251 fn foo() { let _ = Trait::$0 }
252 "#,
253 expect![[r#"
254 fn m() (as Trait) fn()
255 "#]],
256 );
257 }
258
259 #[test]
260 fn completes_trait_associated_method_2() {
261 check_no_kw(
262 r#"
263 trait Trait { fn m(); }
264
265 struct S;
266 impl Trait for S {}
267
268 fn foo() { let _ = S::$0 }
269 "#,
270 expect![[r#"
271 fn m() (as Trait) fn()
272 "#]],
273 );
274 }
275
276 #[test]
277 fn completes_trait_associated_method_3() {
278 check_no_kw(
279 r#"
280 trait Trait { fn m(); }
281
282 struct S;
283 impl Trait for S {}
284
285 fn foo() { let _ = <S as Trait>::$0 }
286 "#,
287 expect![[r#"
288 fn m() (as Trait) fn()
289 "#]],
290 );
291 }
292
293 #[test]
294 fn completes_ty_param_assoc_ty() {
295 check_no_kw(
296 r#"
297 trait Super {
298 type Ty;
299 const CONST: u8;
300 fn func() {}
301 fn method(&self) {}
302 }
303
304 trait Sub: Super {
305 type SubTy;
306 const C2: ();
307 fn subfunc() {}
308 fn submethod(&self) {}
309 }
310
311 fn foo<T: Sub>() { T::$0 }
312 "#,
313 expect![[r#"
314 ct C2 (as Sub) const C2: ()
315 ct CONST (as Super) const CONST: u8
316 fn func() (as Super) fn()
317 fn subfunc() (as Sub) fn()
318 ta SubTy (as Sub) type SubTy
319 ta Ty (as Super) type Ty
320 me method(…) (as Super) fn(&self)
321 me submethod(…) (as Sub) fn(&self)
322 "#]],
323 );
324 }
325
326 #[test]
327 fn completes_self_param_assoc_ty() {
328 check_no_kw(
329 r#"
330 trait Super {
331 type Ty;
332 const CONST: u8 = 0;
333 fn func() {}
334 fn method(&self) {}
335 }
336
337 trait Sub: Super {
338 type SubTy;
339 const C2: () = ();
340 fn subfunc() {}
341 fn submethod(&self) {}
342 }
343
344 struct Wrap<T>(T);
345 impl<T> Super for Wrap<T> {}
346 impl<T> Sub for Wrap<T> {
347 fn subfunc() {
348 // Should be able to assume `Self: Sub + Super`
349 Self::$0
350 }
351 }
352 "#,
353 expect![[r#"
354 ct C2 (as Sub) const C2: ()
355 ct CONST (as Super) const CONST: u8
356 fn func() (as Super) fn()
357 fn subfunc() (as Sub) fn()
358 ta SubTy (as Sub) type SubTy
359 ta Ty (as Super) type Ty
360 me method(…) (as Super) fn(&self)
361 me submethod(…) (as Sub) fn(&self)
362 "#]],
363 );
364 }
365
366 #[test]
367 fn completes_type_alias() {
368 check_no_kw(
369 r#"
370 struct S;
371 impl S { fn foo() {} }
372 type T = S;
373 impl T { fn bar() {} }
374
375 fn main() { T::$0; }
376 "#,
377 expect![[r#"
378 fn bar() fn()
379 fn foo() fn()
380 "#]],
381 );
382 }
383
384 #[test]
385 fn completes_qualified_macros() {
386 check_no_kw(
387 r#"
388 #[macro_export]
389 macro_rules! foo { () => {} }
390
391 fn main() { let _ = crate::$0 }
392 "#,
393 expect![[r#"
394 fn main() fn()
395 ma foo!(…) macro_rules! foo
396 "#]],
397 );
398 }
399
400 #[test]
401 fn does_not_complete_non_fn_macros() {
402 check_no_kw(
403 r#"
404 mod m {
405 #[rustc_builtin_macro]
406 pub macro Clone {}
407 }
408
409 fn f() {m::$0}
410 "#,
411 expect![[r#""#]],
412 );
413 check_no_kw(
414 r#"
415 mod m {
416 #[rustc_builtin_macro]
417 pub macro bench {}
418 }
419
420 fn f() {m::$0}
421 "#,
422 expect![[r#""#]],
423 );
424 }
425
426 #[test]
427 fn completes_reexported_items_under_correct_name() {
428 check_no_kw(
429 r#"
430 fn foo() { self::m::$0 }
431
432 mod m {
433 pub use super::p::wrong_fn as right_fn;
434 pub use super::p::WRONG_CONST as RIGHT_CONST;
435 pub use super::p::WrongType as RightType;
436 }
437 mod p {
438 pub fn wrong_fn() {}
439 pub const WRONG_CONST: u32 = 1;
440 pub struct WrongType {};
441 }
442 "#,
443 expect![[r#"
444 ct RIGHT_CONST
445 fn right_fn() fn()
446 st RightType
447 "#]],
448 );
449
450 check_edit(
451 "RightType",
452 r#"
453 fn foo() { self::m::$0 }
454
455 mod m {
456 pub use super::p::wrong_fn as right_fn;
457 pub use super::p::WRONG_CONST as RIGHT_CONST;
458 pub use super::p::WrongType as RightType;
459 }
460 mod p {
461 pub fn wrong_fn() {}
462 pub const WRONG_CONST: u32 = 1;
463 pub struct WrongType {};
464 }
465 "#,
466 r#"
467 fn foo() { self::m::RightType }
468
469 mod m {
470 pub use super::p::wrong_fn as right_fn;
471 pub use super::p::WRONG_CONST as RIGHT_CONST;
472 pub use super::p::WrongType as RightType;
473 }
474 mod p {
475 pub fn wrong_fn() {}
476 pub const WRONG_CONST: u32 = 1;
477 pub struct WrongType {};
478 }
479 "#,
480 );
481 }
482
483 #[test]
484 fn completes_in_simple_macro_call() {
485 check_no_kw(
486 r#"
487 macro_rules! m { ($e:expr) => { $e } }
488 fn main() { m!(self::f$0); }
489 fn foo() {}
490 "#,
491 expect![[r#"
492 fn foo() fn()
493 fn main() fn()
494 "#]],
495 );
496 }
497
498 #[test]
499 fn function_mod_share_name() {
500 check_no_kw(
501 r#"
502 fn foo() { self::m::$0 }
503
504 mod m {
505 pub mod z {}
506 pub fn z() {}
507 }
508 "#,
509 expect![[r#"
510 fn z() fn()
511 md z
512 "#]],
513 );
514 }
515
516 #[test]
517 fn completes_hashmap_new() {
518 check_no_kw(
519 r#"
520 struct RandomState;
521 struct HashMap<K, V, S = RandomState> {}
522
523 impl<K, V> HashMap<K, V, RandomState> {
524 pub fn new() -> HashMap<K, V, RandomState> { }
525 }
526 fn foo() {
527 HashMap::$0
528 }
529 "#,
530 expect![[r#"
531 fn new() fn() -> HashMap<K, V, RandomState>
532 "#]],
533 );
534 }
535
536 #[test]
537 fn completes_variant_through_self() {
538 cov_mark::check!(completes_variant_through_self);
539 check_no_kw(
540 r#"
541 enum Foo {
542 Bar,
543 Baz,
544 }
545
546 impl Foo {
547 fn foo(self) {
548 Self::$0
549 }
550 }
551 "#,
552 expect![[r#"
553 ev Bar Bar
554 ev Baz Baz
555 me foo(…) fn(self)
556 "#]],
557 );
558 }
559
560 #[test]
561 fn completes_non_exhaustive_variant_within_the_defining_crate() {
562 check_no_kw(
563 r#"
564 enum Foo {
565 #[non_exhaustive]
566 Bar,
567 Baz,
568 }
569
570 fn foo(self) {
571 Foo::$0
572 }
573 "#,
574 expect![[r#"
575 ev Bar Bar
576 ev Baz Baz
577 "#]],
578 );
579
580 check_no_kw(
581 r#"
582 //- /main.rs crate:main deps:e
583 fn foo(self) {
584 e::Foo::$0
585 }
586
587 //- /e.rs crate:e
588 enum Foo {
589 #[non_exhaustive]
590 Bar,
591 Baz,
592 }
593 "#,
594 expect![[r#"
595 ev Baz Baz
596 "#]],
597 );
598 }
599
600 #[test]
601 fn completes_primitive_assoc_const() {
602 cov_mark::check!(completes_primitive_assoc_const);
603 check_no_kw(
604 r#"
605 //- /lib.rs crate:lib deps:core
606 fn f() {
607 u8::$0
608 }
609
610 //- /core.rs crate:core
611 #[lang = "u8"]
612 impl u8 {
613 pub const MAX: Self = 255;
614
615 pub fn func(self) {}
616 }
617 "#,
618 expect![[r#"
619 ct MAX pub const MAX: Self
620 me func(…) fn(self)
621 "#]],
622 );
623 }
624
625 #[test]
626 fn completes_variant_through_alias() {
627 cov_mark::check!(completes_variant_through_alias);
628 check_no_kw(
629 r#"
630 enum Foo {
631 Bar
632 }
633 type Foo2 = Foo;
634 fn main() {
635 Foo2::$0
636 }
637 "#,
638 expect![[r#"
639 ev Bar Bar
640 "#]],
641 );
642 }
643
644 #[test]
645 fn respects_doc_hidden2() {
646 check_no_kw(
647 r#"
648 //- /lib.rs crate:lib deps:dep
649 fn f() {
650 dep::$0
651 }
652
653 //- /dep.rs crate:dep
654 #[doc(hidden)]
655 #[macro_export]
656 macro_rules! m {
657 () => {}
658 }
659
660 #[doc(hidden)]
661 pub fn f() {}
662
663 #[doc(hidden)]
664 pub struct S;
665
666 #[doc(hidden)]
667 pub mod m {}
668 "#,
669 expect![[r#""#]],
670 )
671 }
672
673 #[test]
674 fn type_anchor_empty() {
675 check_no_kw(
676 r#"
677 trait Foo {
678 fn foo() -> Self;
679 }
680 struct Bar;
681 impl Foo for Bar {
682 fn foo() -> {
683 Bar
684 }
685 }
686 fn bar() -> Bar {
687 <_>::$0
688 }
689 "#,
690 expect![[r#"
691 fn foo() (as Foo) fn() -> Self
692 "#]],
693 );
694 }
695
696 #[test]
697 fn type_anchor_type() {
698 check_no_kw(
699 r#"
700 trait Foo {
701 fn foo() -> Self;
702 }
703 struct Bar;
704 impl Bar {
705 fn bar() {}
706 }
707 impl Foo for Bar {
708 fn foo() -> {
709 Bar
710 }
711 }
712 fn bar() -> Bar {
713 <Bar>::$0
714 }
715 "#,
716 expect![[r#"
717 fn bar() fn()
718 fn foo() (as Foo) fn() -> Self
719 "#]],
720 );
721 }
722
723 #[test]
724 fn type_anchor_type_trait() {
725 check_no_kw(
726 r#"
727 trait Foo {
728 fn foo() -> Self;
729 }
730 struct Bar;
731 impl Bar {
732 fn bar() {}
733 }
734 impl Foo for Bar {
735 fn foo() -> {
736 Bar
737 }
738 }
739 fn bar() -> Bar {
740 <Bar as Foo>::$0
741 }
742 "#,
743 expect![[r#"
744 fn foo() (as Foo) fn() -> Self
745 "#]],
746 );
747 }
748
749 #[test]
750 fn completes_fn_in_pub_trait_generated_by_macro() {
751 check_no_kw(
752 r#"
753 mod other_mod {
754 macro_rules! make_method {
755 ($name:ident) => {
756 fn $name(&self) {}
757 };
758 }
759
760 pub trait MyTrait {
761 make_method! { by_macro }
762 fn not_by_macro(&self) {}
763 }
764
765 pub struct Foo {}
766
767 impl MyTrait for Foo {}
768 }
769
770 fn main() {
771 use other_mod::{Foo, MyTrait};
772 let f = Foo {};
773 f.$0
774 }
775 "#,
776 expect![[r#"
777 me by_macro() (as MyTrait) fn(&self)
778 me not_by_macro() (as MyTrait) fn(&self)
779 "#]],
780 )
781 }
782
783 #[test]
784 fn completes_fn_in_pub_trait_generated_by_recursive_macro() {
785 check_no_kw(
786 r#"
787 mod other_mod {
788 macro_rules! make_method {
789 ($name:ident) => {
790 fn $name(&self) {}
791 };
792 }
793
794 macro_rules! make_trait {
795 () => {
796 pub trait MyTrait {
797 make_method! { by_macro }
798 fn not_by_macro(&self) {}
799 }
800 }
801 }
802
803 make_trait!();
804
805 pub struct Foo {}
806
807 impl MyTrait for Foo {}
808 }
809
810 fn main() {
811 use other_mod::{Foo, MyTrait};
812 let f = Foo {};
813 f.$0
814 }
815 "#,
816 expect![[r#"
817 me by_macro() (as MyTrait) fn(&self)
818 me not_by_macro() (as MyTrait) fn(&self)
819 "#]],
820 )
821 }
822
823 #[test]
824 fn completes_const_in_pub_trait_generated_by_macro() {
825 check_no_kw(
826 r#"
827 mod other_mod {
828 macro_rules! make_const {
829 ($name:ident) => {
830 const $name: u8 = 1;
831 };
832 }
833
834 pub trait MyTrait {
835 make_const! { by_macro }
836 }
837
838 pub struct Foo {}
839
840 impl MyTrait for Foo {}
841 }
842
843 fn main() {
844 use other_mod::{Foo, MyTrait};
845 let f = Foo {};
846 Foo::$0
847 }
848 "#,
849 expect![[r#"
850 ct by_macro (as MyTrait) pub const by_macro: u8
851 "#]],
852 )
853 }
854
855 #[test]
856 fn completes_locals_from_macros() {
857 check_no_kw(
858 r#"
859
860 macro_rules! x {
861 ($x:ident, $expr:expr) => {
862 let $x = 0;
863 $expr
864 };
865 }
866 fn main() {
867 x! {
868 foobar, {
869 f$0
870 }
871 };
872 }
873 "#,
874 expect![[r#"
875 fn main() fn()
876 lc foobar i32
877 ma x!(…) macro_rules! x
878 bt u32
879 "#]],
880 )
881 }
882
883 #[test]
884 fn regression_12644() {
885 check_no_kw(
886 r#"
887 macro_rules! __rust_force_expr {
888 ($e:expr) => {
889 $e
890 };
891 }
892 macro_rules! vec {
893 ($elem:expr) => {
894 __rust_force_expr!($elem)
895 };
896 }
897
898 struct Struct;
899 impl Struct {
900 fn foo(self) {}
901 }
902
903 fn f() {
904 vec![Struct].$0;
905 }
906 "#,
907 expect![[r#"
908 me foo() fn(self)
909 "#]],
910 );
911 }
912
913 #[test]
914 fn completes_after_colon_with_trigger() {
915 check_with_trigger_character(
916 r#"
917 //- minicore: option
918 fn foo { ::$0 }
919 "#,
920 Some(':'),
921 expect![[r#"
922 md core
923 "#]],
924 );
925 check_with_trigger_character(
926 r#"
927 //- minicore: option
928 fn foo { /* test */::$0 }
929 "#,
930 Some(':'),
931 expect![[r#"
932 md core
933 "#]],
934 );
935
936 check_with_trigger_character(
937 r#"
938 fn foo { crate::$0 }
939 "#,
940 Some(':'),
941 expect![[r#"
942 fn foo() fn()
943 "#]],
944 );
945
946 check_with_trigger_character(
947 r#"
948 fn foo { crate:$0 }
949 "#,
950 Some(':'),
951 expect![""],
952 );
953 }
954
955 #[test]
956 fn completes_after_colon_without_trigger() {
957 check_with_trigger_character(
958 r#"
959 fn foo { crate::$0 }
960 "#,
961 None,
962 expect![[r#"
963 fn foo() fn()
964 "#]],
965 );
966
967 check_with_trigger_character(
968 r#"
969 fn foo { crate:$0 }
970 "#,
971 None,
972 expect![""],
973 );
974 }
975
976 #[test]
977 fn no_completions_in_invalid_path() {
978 check(
979 r#"
980 fn foo { crate:::$0 }
981 "#,
982 expect![""],
983 );
984 check_no_kw(
985 r#"
986 fn foo { crate::::$0 }
987 "#,
988 expect![""],
989 )
990 }