]> git.lizzy.rs Git - rust.git/blob - crates/ide/src/hover/tests.rs
Merge #10796
[rust.git] / crates / ide / src / hover / tests.rs
1 use expect_test::{expect, Expect};
2 use ide_db::base_db::{FileLoader, FileRange};
3 use syntax::TextRange;
4
5 use crate::{fixture, hover::HoverDocFormat, HoverConfig};
6
7 fn check_hover_no_result(ra_fixture: &str) {
8     let (analysis, position) = fixture::position(ra_fixture);
9     let hover = analysis
10         .hover(
11             &HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::Markdown) },
12             FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
13         )
14         .unwrap();
15     assert!(hover.is_none(), "hover not expected but found: {:?}", hover.unwrap());
16 }
17
18 fn check(ra_fixture: &str, expect: Expect) {
19     let (analysis, position) = fixture::position(ra_fixture);
20     let hover = analysis
21         .hover(
22             &HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::Markdown) },
23             FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
24         )
25         .unwrap()
26         .unwrap();
27
28     let content = analysis.db.file_text(position.file_id);
29     let hovered_element = &content[hover.range];
30
31     let actual = format!("*{}*\n{}\n", hovered_element, hover.info.markup);
32     expect.assert_eq(&actual)
33 }
34
35 fn check_hover_no_links(ra_fixture: &str, expect: Expect) {
36     let (analysis, position) = fixture::position(ra_fixture);
37     let hover = analysis
38         .hover(
39             &HoverConfig { links_in_hover: false, documentation: Some(HoverDocFormat::Markdown) },
40             FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
41         )
42         .unwrap()
43         .unwrap();
44
45     let content = analysis.db.file_text(position.file_id);
46     let hovered_element = &content[hover.range];
47
48     let actual = format!("*{}*\n{}\n", hovered_element, hover.info.markup);
49     expect.assert_eq(&actual)
50 }
51
52 fn check_hover_no_markdown(ra_fixture: &str, expect: Expect) {
53     let (analysis, position) = fixture::position(ra_fixture);
54     let hover = analysis
55         .hover(
56             &HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::PlainText) },
57             FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
58         )
59         .unwrap()
60         .unwrap();
61
62     let content = analysis.db.file_text(position.file_id);
63     let hovered_element = &content[hover.range];
64
65     let actual = format!("*{}*\n{}\n", hovered_element, hover.info.markup);
66     expect.assert_eq(&actual)
67 }
68
69 fn check_actions(ra_fixture: &str, expect: Expect) {
70     let (analysis, file_id, position) = fixture::range_or_position(ra_fixture);
71     let hover = analysis
72         .hover(
73             &HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::Markdown) },
74             FileRange { file_id, range: position.range_or_empty() },
75         )
76         .unwrap()
77         .unwrap();
78     expect.assert_debug_eq(&hover.info.actions)
79 }
80
81 fn check_hover_range(ra_fixture: &str, expect: Expect) {
82     let (analysis, range) = fixture::range(ra_fixture);
83     let hover = analysis
84         .hover(
85             &HoverConfig { links_in_hover: false, documentation: Some(HoverDocFormat::Markdown) },
86             range,
87         )
88         .unwrap()
89         .unwrap();
90     expect.assert_eq(hover.info.markup.as_str())
91 }
92
93 fn check_hover_range_no_results(ra_fixture: &str) {
94     let (analysis, range) = fixture::range(ra_fixture);
95     let hover = analysis
96         .hover(
97             &HoverConfig { links_in_hover: false, documentation: Some(HoverDocFormat::Markdown) },
98             range,
99         )
100         .unwrap();
101     assert!(hover.is_none());
102 }
103
104 #[test]
105 fn hover_descend_macros_avoids_duplicates() {
106     check(
107         r#"
108 macro_rules! dupe_use {
109     ($local:ident) => {
110         {
111             $local;
112             $local;
113         }
114     }
115 }
116 fn foo() {
117     let local = 0;
118     dupe_use!(local$0);
119 }
120 "#,
121         expect![[r#"
122             *local*
123
124             ```rust
125             let local: i32
126             ```
127         "#]],
128     );
129 }
130
131 #[test]
132 fn hover_shows_all_macro_descends() {
133     check(
134         r#"
135 macro_rules! m {
136     ($name:ident) => {
137         /// Outer
138         fn $name() {}
139
140         mod module {
141             /// Inner
142             fn $name() {}
143         }
144     };
145 }
146
147 m!(ab$0c);
148             "#,
149         expect![[r#"
150             *abc*
151
152             ```rust
153             test::module
154             ```
155
156             ```rust
157             fn abc()
158             ```
159
160             ---
161
162             Inner
163             ---
164
165             ```rust
166             test
167             ```
168
169             ```rust
170             fn abc()
171             ```
172
173             ---
174
175             Outer
176             "#]],
177     );
178 }
179
180 #[test]
181 fn hover_shows_type_of_an_expression() {
182     check(
183         r#"
184 pub fn foo() -> u32 { 1 }
185
186 fn main() {
187     let foo_test = foo()$0;
188 }
189 "#,
190         expect![[r#"
191             *foo()*
192             ```rust
193             u32
194             ```
195         "#]],
196     );
197 }
198
199 #[test]
200 fn hover_remove_markdown_if_configured() {
201     check_hover_no_markdown(
202         r#"
203 pub fn foo() -> u32 { 1 }
204
205 fn main() {
206     let foo_test = foo()$0;
207 }
208 "#,
209         expect![[r#"
210             *foo()*
211             u32
212         "#]],
213     );
214 }
215
216 #[test]
217 fn hover_shows_long_type_of_an_expression() {
218     check(
219         r#"
220 struct Scan<A, B, C> { a: A, b: B, c: C }
221 struct Iter<I> { inner: I }
222 enum Option<T> { Some(T), None }
223
224 struct OtherStruct<T> { i: T }
225
226 fn scan<A, B, C>(a: A, b: B, c: C) -> Iter<Scan<OtherStruct<A>, B, C>> {
227     Iter { inner: Scan { a, b, c } }
228 }
229
230 fn main() {
231     let num: i32 = 55;
232     let closure = |memo: &mut u32, value: &u32, _another: &mut u32| -> Option<u32> {
233         Option::Some(*memo + value)
234     };
235     let number = 5u32;
236     let mut iter$0 = scan(OtherStruct { i: num }, closure, number);
237 }
238 "#,
239         expect![[r#"
240                 *iter*
241
242                 ```rust
243                 let mut iter: Iter<Scan<OtherStruct<OtherStruct<i32>>, |&mut u32, &u32, &mut u32| -> Option<u32>, u32>>
244                 ```
245             "#]],
246     );
247 }
248
249 #[test]
250 fn hover_shows_fn_signature() {
251     // Single file with result
252     check(
253         r#"
254 pub fn foo() -> u32 { 1 }
255
256 fn main() { let foo_test = fo$0o(); }
257 "#,
258         expect![[r#"
259                 *foo*
260
261                 ```rust
262                 test
263                 ```
264
265                 ```rust
266                 pub fn foo() -> u32
267                 ```
268             "#]],
269     );
270
271     // Multiple candidates but results are ambiguous.
272     check(
273         r#"
274 //- /a.rs
275 pub fn foo() -> u32 { 1 }
276
277 //- /b.rs
278 pub fn foo() -> &str { "" }
279
280 //- /c.rs
281 pub fn foo(a: u32, b: u32) {}
282
283 //- /main.rs
284 mod a;
285 mod b;
286 mod c;
287
288 fn main() { let foo_test = fo$0o(); }
289         "#,
290         expect![[r#"
291                 *foo*
292                 ```rust
293                 {unknown}
294                 ```
295             "#]],
296     );
297
298     // Use literal `crate` in path
299     check(
300         r#"
301 pub struct X;
302
303 fn foo() -> crate::X { X }
304
305 fn main() { f$0oo(); }
306         "#,
307         expect![[r#"
308             *foo*
309
310             ```rust
311             test
312             ```
313
314             ```rust
315             fn foo() -> crate::X
316             ```
317         "#]],
318     );
319
320     // Check `super` in path
321     check(
322         r#"
323 pub struct X;
324
325 mod m { pub fn foo() -> super::X { super::X } }
326
327 fn main() { m::f$0oo(); }
328         "#,
329         expect![[r#"
330                 *foo*
331
332                 ```rust
333                 test::m
334                 ```
335
336                 ```rust
337                 pub fn foo() -> super::X
338                 ```
339             "#]],
340     );
341 }
342
343 #[test]
344 fn hover_shows_fn_signature_with_type_params() {
345     check(
346         r#"
347 pub fn foo<'a, T: AsRef<str>>(b: &'a T) -> &'a str { }
348
349 fn main() { let foo_test = fo$0o(); }
350         "#,
351         expect![[r#"
352                 *foo*
353
354                 ```rust
355                 test
356                 ```
357
358                 ```rust
359                 pub fn foo<'a, T>(b: &'a T) -> &'a str
360                 where
361                     T: AsRef<str>,
362                 ```
363             "#]],
364     );
365 }
366
367 #[test]
368 fn hover_shows_fn_signature_on_fn_name() {
369     check(
370         r#"
371 pub fn foo$0(a: u32, b: u32) -> u32 {}
372
373 fn main() { }
374 "#,
375         expect![[r#"
376                 *foo*
377
378                 ```rust
379                 test
380                 ```
381
382                 ```rust
383                 pub fn foo(a: u32, b: u32) -> u32
384                 ```
385             "#]],
386     );
387 }
388
389 #[test]
390 fn hover_shows_fn_doc() {
391     check(
392         r#"
393 /// # Example
394 /// ```
395 /// # use std::path::Path;
396 /// #
397 /// foo(Path::new("hello, world!"))
398 /// ```
399 pub fn foo$0(_: &Path) {}
400
401 fn main() { }
402 "#,
403         expect![[r##"
404                 *foo*
405
406                 ```rust
407                 test
408                 ```
409
410                 ```rust
411                 pub fn foo(_: &Path)
412                 ```
413
414                 ---
415
416                 # Example
417
418                 ```
419                 # use std::path::Path;
420                 #
421                 foo(Path::new("hello, world!"))
422                 ```
423             "##]],
424     );
425 }
426
427 #[test]
428 fn hover_shows_fn_doc_attr_raw_string() {
429     check(
430         r##"
431 #[doc = r#"Raw string doc attr"#]
432 pub fn foo$0(_: &Path) {}
433
434 fn main() { }
435 "##,
436         expect![[r##"
437                 *foo*
438
439                 ```rust
440                 test
441                 ```
442
443                 ```rust
444                 pub fn foo(_: &Path)
445                 ```
446
447                 ---
448
449                 Raw string doc attr
450             "##]],
451     );
452 }
453
454 #[test]
455 fn hover_shows_struct_field_info() {
456     // Hovering over the field when instantiating
457     check(
458         r#"
459 struct Foo { field_a: u32 }
460
461 fn main() {
462     let foo = Foo { field_a$0: 0, };
463 }
464 "#,
465         expect![[r#"
466                 *field_a*
467
468                 ```rust
469                 test::Foo
470                 ```
471
472                 ```rust
473                 field_a: u32
474                 ```
475             "#]],
476     );
477
478     // Hovering over the field in the definition
479     check(
480         r#"
481 struct Foo { field_a$0: u32 }
482
483 fn main() {
484     let foo = Foo { field_a: 0 };
485 }
486 "#,
487         expect![[r#"
488                 *field_a*
489
490                 ```rust
491                 test::Foo
492                 ```
493
494                 ```rust
495                 field_a: u32
496                 ```
497             "#]],
498     );
499 }
500
501 #[test]
502 fn hover_const_static() {
503     check(
504         r#"const foo$0: u32 = 123;"#,
505         expect![[r#"
506             *foo*
507
508             ```rust
509             test
510             ```
511
512             ```rust
513             const foo: u32 = 123
514             ```
515         "#]],
516     );
517     check(
518         r#"
519 const foo$0: u32 = {
520     let x = foo();
521     x + 100
522 };"#,
523         expect![[r#"
524             *foo*
525
526             ```rust
527             test
528             ```
529
530             ```rust
531             const foo: u32 = {
532                 let x = foo();
533                 x + 100
534             }
535             ```
536         "#]],
537     );
538
539     check(
540         r#"static foo$0: u32 = 456;"#,
541         expect![[r#"
542             *foo*
543
544             ```rust
545             test
546             ```
547
548             ```rust
549             static foo: u32 = 456
550             ```
551         "#]],
552     );
553 }
554
555 #[test]
556 fn hover_default_generic_types() {
557     check(
558         r#"
559 struct Test<K, T = u8> { k: K, t: T }
560
561 fn main() {
562     let zz$0 = Test { t: 23u8, k: 33 };
563 }"#,
564         expect![[r#"
565                 *zz*
566
567                 ```rust
568                 let zz: Test<i32, u8>
569                 ```
570             "#]],
571     );
572 }
573
574 #[test]
575 fn hover_some() {
576     check(
577         r#"
578 enum Option<T> { Some(T) }
579 use Option::Some;
580
581 fn main() { So$0me(12); }
582 "#,
583         expect![[r#"
584                 *Some*
585
586                 ```rust
587                 test::Option
588                 ```
589
590                 ```rust
591                 Some(T)
592                 ```
593             "#]],
594     );
595
596     check(
597         r#"
598 enum Option<T> { Some(T) }
599 use Option::Some;
600
601 fn main() { let b$0ar = Some(12); }
602 "#,
603         expect![[r#"
604                 *bar*
605
606                 ```rust
607                 let bar: Option<i32>
608                 ```
609             "#]],
610     );
611 }
612
613 #[test]
614 fn hover_enum_variant() {
615     check(
616         r#"
617 enum Option<T> {
618     /// The None variant
619     Non$0e
620 }
621 "#,
622         expect![[r#"
623                 *None*
624
625                 ```rust
626                 test::Option
627                 ```
628
629                 ```rust
630                 None
631                 ```
632
633                 ---
634
635                 The None variant
636             "#]],
637     );
638
639     check(
640         r#"
641 enum Option<T> {
642     /// The Some variant
643     Some(T)
644 }
645 fn main() {
646     let s = Option::Som$0e(12);
647 }
648 "#,
649         expect![[r#"
650                 *Some*
651
652                 ```rust
653                 test::Option
654                 ```
655
656                 ```rust
657                 Some(T)
658                 ```
659
660                 ---
661
662                 The Some variant
663             "#]],
664     );
665 }
666
667 #[test]
668 fn hover_for_local_variable() {
669     check(
670         r#"fn func(foo: i32) { fo$0o; }"#,
671         expect![[r#"
672                 *foo*
673
674                 ```rust
675                 foo: i32
676                 ```
677             "#]],
678     )
679 }
680
681 #[test]
682 fn hover_for_local_variable_pat() {
683     check(
684         r#"fn func(fo$0o: i32) {}"#,
685         expect![[r#"
686                 *foo*
687
688                 ```rust
689                 foo: i32
690                 ```
691             "#]],
692     )
693 }
694
695 #[test]
696 fn hover_local_var_edge() {
697     check(
698         r#"fn func(foo: i32) { if true { $0foo; }; }"#,
699         expect![[r#"
700                 *foo*
701
702                 ```rust
703                 foo: i32
704                 ```
705             "#]],
706     )
707 }
708
709 #[test]
710 fn hover_for_param_edge() {
711     check(
712         r#"fn func($0foo: i32) {}"#,
713         expect![[r#"
714                 *foo*
715
716                 ```rust
717                 foo: i32
718                 ```
719             "#]],
720     )
721 }
722
723 #[test]
724 fn hover_for_param_with_multiple_traits() {
725     check(
726         r#"
727             //- minicore: sized
728             trait Deref {
729                 type Target: ?Sized;
730             }
731             trait DerefMut {
732                 type Target: ?Sized;
733             }
734             fn f(_x$0: impl Deref<Target=u8> + DerefMut<Target=u8>) {}"#,
735         expect![[r#"
736                 *_x*
737
738                 ```rust
739                 _x: impl Deref<Target = u8> + DerefMut<Target = u8>
740                 ```
741             "#]],
742     )
743 }
744
745 #[test]
746 fn test_hover_infer_associated_method_result() {
747     check(
748         r#"
749 struct Thing { x: u32 }
750
751 impl Thing {
752     fn new() -> Thing { Thing { x: 0 } }
753 }
754
755 fn main() { let foo_$0test = Thing::new(); }
756 "#,
757         expect![[r#"
758                 *foo_test*
759
760                 ```rust
761                 let foo_test: Thing
762                 ```
763             "#]],
764     )
765 }
766
767 #[test]
768 fn test_hover_infer_associated_method_exact() {
769     check(
770         r#"
771 mod wrapper {
772     struct Thing { x: u32 }
773
774     impl Thing {
775         fn new() -> Thing { Thing { x: 0 } }
776     }
777 }
778
779 fn main() { let foo_test = wrapper::Thing::new$0(); }
780 "#,
781         expect![[r#"
782                 *new*
783
784                 ```rust
785                 test::wrapper::Thing
786                 ```
787
788                 ```rust
789                 fn new() -> Thing
790                 ```
791             "#]],
792     )
793 }
794
795 #[test]
796 fn test_hover_infer_associated_const_in_pattern() {
797     check(
798         r#"
799 struct X;
800 impl X {
801     const C: u32 = 1;
802 }
803
804 fn main() {
805     match 1 {
806         X::C$0 => {},
807         2 => {},
808         _ => {}
809     };
810 }
811 "#,
812         expect![[r#"
813             *C*
814
815             ```rust
816             test
817             ```
818
819             ```rust
820             const C: u32 = 1
821             ```
822         "#]],
823     )
824 }
825
826 #[test]
827 fn test_hover_self() {
828     check(
829         r#"
830 struct Thing { x: u32 }
831 impl Thing {
832     fn new() -> Self { Self$0 { x: 0 } }
833 }
834 "#,
835         expect![[r#"
836                 *Self*
837
838                 ```rust
839                 test
840                 ```
841
842                 ```rust
843                 struct Thing
844                 ```
845             "#]],
846     );
847     check(
848         r#"
849 struct Thing { x: u32 }
850 impl Thing {
851     fn new() -> Self$0 { Self { x: 0 } }
852 }
853 "#,
854         expect![[r#"
855                 *Self*
856
857                 ```rust
858                 test
859                 ```
860
861                 ```rust
862                 struct Thing
863                 ```
864             "#]],
865     );
866     check(
867         r#"
868 enum Thing { A }
869 impl Thing {
870     pub fn new() -> Self$0 { Thing::A }
871 }
872 "#,
873         expect![[r#"
874                 *Self*
875
876                 ```rust
877                 test
878                 ```
879
880                 ```rust
881                 enum Thing
882                 ```
883             "#]],
884     );
885     check(
886         r#"
887         enum Thing { A }
888         impl Thing {
889             pub fn thing(a: Self$0) {}
890         }
891         "#,
892         expect![[r#"
893                 *Self*
894
895                 ```rust
896                 test
897                 ```
898
899                 ```rust
900                 enum Thing
901                 ```
902             "#]],
903     );
904 }
905
906 #[test]
907 fn test_hover_shadowing_pat() {
908     check(
909         r#"
910 fn x() {}
911
912 fn y() {
913     let x = 0i32;
914     x$0;
915 }
916 "#,
917         expect![[r#"
918                 *x*
919
920                 ```rust
921                 let x: i32
922                 ```
923             "#]],
924     )
925 }
926
927 #[test]
928 fn test_hover_macro_invocation() {
929     check(
930         r#"
931 macro_rules! foo { () => {} }
932
933 fn f() { fo$0o!(); }
934 "#,
935         expect![[r#"
936                 *foo*
937
938                 ```rust
939                 test
940                 ```
941
942                 ```rust
943                 macro_rules! foo
944                 ```
945             "#]],
946     )
947 }
948
949 #[test]
950 fn test_hover_macro2_invocation() {
951     check(
952         r#"
953 /// foo bar
954 ///
955 /// foo bar baz
956 macro foo() {}
957
958 fn f() { fo$0o!(); }
959 "#,
960         expect![[r#"
961                 *foo*
962
963                 ```rust
964                 test
965                 ```
966
967                 ```rust
968                 macro foo
969                 ```
970
971                 ---
972
973                 foo bar
974
975                 foo bar baz
976             "#]],
977     )
978 }
979
980 #[test]
981 fn test_hover_tuple_field() {
982     check(
983         r#"struct TS(String, i32$0);"#,
984         expect![[r#"
985                 *i32*
986
987                 ```rust
988                 i32
989                 ```
990             "#]],
991     )
992 }
993
994 #[test]
995 fn test_hover_through_macro() {
996     check(
997         r#"
998 macro_rules! id { ($($tt:tt)*) => { $($tt)* } }
999 fn foo() {}
1000 id! {
1001     fn bar() { fo$0o(); }
1002 }
1003 "#,
1004         expect![[r#"
1005                 *foo*
1006
1007                 ```rust
1008                 test
1009                 ```
1010
1011                 ```rust
1012                 fn foo()
1013                 ```
1014             "#]],
1015     );
1016 }
1017
1018 #[test]
1019 fn test_hover_through_attr() {
1020     check(
1021         r#"
1022 //- proc_macros: identity
1023 #[proc_macros::identity]
1024 fn foo$0() {}
1025 "#,
1026         expect![[r#"
1027                 *foo*
1028
1029                 ```rust
1030                 test
1031                 ```
1032
1033                 ```rust
1034                 fn foo()
1035                 ```
1036             "#]],
1037     );
1038 }
1039
1040 #[test]
1041 fn test_hover_through_expr_in_macro() {
1042     check(
1043         r#"
1044 macro_rules! id { ($($tt:tt)*) => { $($tt)* } }
1045 fn foo(bar:u32) { let a = id!(ba$0r); }
1046 "#,
1047         expect![[r#"
1048                 *bar*
1049
1050                 ```rust
1051                 bar: u32
1052                 ```
1053             "#]],
1054     );
1055 }
1056
1057 #[test]
1058 fn test_hover_through_expr_in_macro_recursive() {
1059     check(
1060         r#"
1061 macro_rules! id_deep { ($($tt:tt)*) => { $($tt)* } }
1062 macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } }
1063 fn foo(bar:u32) { let a = id!(ba$0r); }
1064 "#,
1065         expect![[r#"
1066                 *bar*
1067
1068                 ```rust
1069                 bar: u32
1070                 ```
1071             "#]],
1072     );
1073 }
1074
1075 #[test]
1076 fn test_hover_through_func_in_macro_recursive() {
1077     check(
1078         r#"
1079 macro_rules! id_deep { ($($tt:tt)*) => { $($tt)* } }
1080 macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } }
1081 fn bar() -> u32 { 0 }
1082 fn foo() { let a = id!([0u32, bar($0)] ); }
1083 "#,
1084         expect![[r#"
1085                 *bar()*
1086                 ```rust
1087                 u32
1088                 ```
1089             "#]],
1090     );
1091 }
1092
1093 #[test]
1094 fn test_hover_through_literal_string_in_macro() {
1095     check(
1096         r#"
1097 macro_rules! arr { ($($tt:tt)*) => { [$($tt)*)] } }
1098 fn foo() {
1099     let mastered_for_itunes = "";
1100     let _ = arr!("Tr$0acks", &mastered_for_itunes);
1101 }
1102 "#,
1103         expect![[r#"
1104                 *"Tracks"*
1105                 ```rust
1106                 &str
1107                 ```
1108             "#]],
1109     );
1110 }
1111
1112 #[test]
1113 fn test_hover_through_assert_macro() {
1114     check(
1115         r#"
1116 #[rustc_builtin_macro]
1117 macro_rules! assert {}
1118
1119 fn bar() -> bool { true }
1120 fn foo() {
1121     assert!(ba$0r());
1122 }
1123 "#,
1124         expect![[r#"
1125                 *bar*
1126
1127                 ```rust
1128                 test
1129                 ```
1130
1131                 ```rust
1132                 fn bar() -> bool
1133                 ```
1134             "#]],
1135     );
1136 }
1137
1138 #[test]
1139 fn test_hover_through_literal_string_in_builtin_macro() {
1140     check_hover_no_result(
1141         r#"
1142             #[rustc_builtin_macro]
1143             macro_rules! format {}
1144
1145             fn foo() {
1146                 format!("hel$0lo {}", 0);
1147             }
1148 "#,
1149     );
1150 }
1151
1152 #[test]
1153 fn test_hover_non_ascii_space_doc() {
1154     check(
1155         "
1156 /// <- `\u{3000}` here
1157 fn foo() { }
1158
1159 fn bar() { fo$0o(); }
1160 ",
1161         expect![[r#"
1162                 *foo*
1163
1164                 ```rust
1165                 test
1166                 ```
1167
1168                 ```rust
1169                 fn foo()
1170                 ```
1171
1172                 ---
1173
1174                 \<- ` ` here
1175             "#]],
1176     );
1177 }
1178
1179 #[test]
1180 fn test_hover_function_show_qualifiers() {
1181     check(
1182         r#"async fn foo$0() {}"#,
1183         expect![[r#"
1184                 *foo*
1185
1186                 ```rust
1187                 test
1188                 ```
1189
1190                 ```rust
1191                 async fn foo()
1192                 ```
1193             "#]],
1194     );
1195     check(
1196         r#"pub const unsafe fn foo$0() {}"#,
1197         expect![[r#"
1198                 *foo*
1199
1200                 ```rust
1201                 test
1202                 ```
1203
1204                 ```rust
1205                 pub const unsafe fn foo()
1206                 ```
1207             "#]],
1208     );
1209     // Top level `pub(crate)` will be displayed as no visibility.
1210     check(
1211         r#"mod m { pub(crate) async unsafe extern "C" fn foo$0() {} }"#,
1212         expect![[r#"
1213                 *foo*
1214
1215                 ```rust
1216                 test::m
1217                 ```
1218
1219                 ```rust
1220                 pub(crate) async unsafe extern "C" fn foo()
1221                 ```
1222             "#]],
1223     );
1224 }
1225
1226 #[test]
1227 fn test_hover_trait_show_qualifiers() {
1228     check_actions(
1229         r"unsafe trait foo$0() {}",
1230         expect![[r#"
1231                 [
1232                     Implementation(
1233                         FilePosition {
1234                             file_id: FileId(
1235                                 0,
1236                             ),
1237                             offset: 13,
1238                         },
1239                     ),
1240                 ]
1241             "#]],
1242     );
1243 }
1244
1245 #[test]
1246 fn test_hover_extern_crate() {
1247     check(
1248         r#"
1249 //- /main.rs crate:main deps:std
1250 extern crate st$0d;
1251 //- /std/lib.rs crate:std
1252 //! Standard library for this test
1253 //!
1254 //! Printed?
1255 //! abc123
1256 "#,
1257         expect![[r#"
1258                 *std*
1259
1260                 ```rust
1261                 extern crate std
1262                 ```
1263
1264                 ---
1265
1266                 Standard library for this test
1267
1268                 Printed?
1269                 abc123
1270             "#]],
1271     );
1272     check(
1273         r#"
1274 //- /main.rs crate:main deps:std
1275 extern crate std as ab$0c;
1276 //- /std/lib.rs crate:std
1277 //! Standard library for this test
1278 //!
1279 //! Printed?
1280 //! abc123
1281 "#,
1282         expect![[r#"
1283                 *abc*
1284
1285                 ```rust
1286                 extern crate std
1287                 ```
1288
1289                 ---
1290
1291                 Standard library for this test
1292
1293                 Printed?
1294                 abc123
1295             "#]],
1296     );
1297 }
1298
1299 #[test]
1300 fn test_hover_mod_with_same_name_as_function() {
1301     check(
1302         r#"
1303 use self::m$0y::Bar;
1304 mod my { pub struct Bar; }
1305
1306 fn my() {}
1307 "#,
1308         expect![[r#"
1309                 *my*
1310
1311                 ```rust
1312                 test
1313                 ```
1314
1315                 ```rust
1316                 mod my
1317                 ```
1318             "#]],
1319     );
1320 }
1321
1322 #[test]
1323 fn test_hover_struct_doc_comment() {
1324     check(
1325         r#"
1326 /// This is an example
1327 /// multiline doc
1328 ///
1329 /// # Example
1330 ///
1331 /// ```
1332 /// let five = 5;
1333 ///
1334 /// assert_eq!(6, my_crate::add_one(5));
1335 /// ```
1336 struct Bar;
1337
1338 fn foo() { let bar = Ba$0r; }
1339 "#,
1340         expect![[r##"
1341                 *Bar*
1342
1343                 ```rust
1344                 test
1345                 ```
1346
1347                 ```rust
1348                 struct Bar
1349                 ```
1350
1351                 ---
1352
1353                 This is an example
1354                 multiline doc
1355
1356                 # Example
1357
1358                 ```
1359                 let five = 5;
1360
1361                 assert_eq!(6, my_crate::add_one(5));
1362                 ```
1363             "##]],
1364     );
1365 }
1366
1367 #[test]
1368 fn test_hover_struct_doc_attr() {
1369     check(
1370         r#"
1371 #[doc = "bar docs"]
1372 struct Bar;
1373
1374 fn foo() { let bar = Ba$0r; }
1375 "#,
1376         expect![[r#"
1377                 *Bar*
1378
1379                 ```rust
1380                 test
1381                 ```
1382
1383                 ```rust
1384                 struct Bar
1385                 ```
1386
1387                 ---
1388
1389                 bar docs
1390             "#]],
1391     );
1392 }
1393
1394 #[test]
1395 fn test_hover_struct_doc_attr_multiple_and_mixed() {
1396     check(
1397         r#"
1398 /// bar docs 0
1399 #[doc = "bar docs 1"]
1400 #[doc = "bar docs 2"]
1401 struct Bar;
1402
1403 fn foo() { let bar = Ba$0r; }
1404 "#,
1405         expect![[r#"
1406                 *Bar*
1407
1408                 ```rust
1409                 test
1410                 ```
1411
1412                 ```rust
1413                 struct Bar
1414                 ```
1415
1416                 ---
1417
1418                 bar docs 0
1419                 bar docs 1
1420                 bar docs 2
1421             "#]],
1422     );
1423 }
1424
1425 #[test]
1426 fn test_hover_external_url() {
1427     check(
1428         r#"
1429 pub struct Foo;
1430 /// [external](https://www.google.com)
1431 pub struct B$0ar
1432 "#,
1433         expect![[r#"
1434                 *Bar*
1435
1436                 ```rust
1437                 test
1438                 ```
1439
1440                 ```rust
1441                 pub struct Bar
1442                 ```
1443
1444                 ---
1445
1446                 [external](https://www.google.com)
1447             "#]],
1448     );
1449 }
1450
1451 // Check that we don't rewrite links which we can't identify
1452 #[test]
1453 fn test_hover_unknown_target() {
1454     check(
1455         r#"
1456 pub struct Foo;
1457 /// [baz](Baz)
1458 pub struct B$0ar
1459 "#,
1460         expect![[r#"
1461                 *Bar*
1462
1463                 ```rust
1464                 test
1465                 ```
1466
1467                 ```rust
1468                 pub struct Bar
1469                 ```
1470
1471                 ---
1472
1473                 [baz](Baz)
1474             "#]],
1475     );
1476 }
1477
1478 #[test]
1479 fn test_hover_no_links() {
1480     check_hover_no_links(
1481         r#"
1482 /// Test cases:
1483 /// case 1.  bare URL: https://www.example.com/
1484 /// case 2.  inline URL with title: [example](https://www.example.com/)
1485 /// case 3.  code reference: [`Result`]
1486 /// case 4.  code reference but miss footnote: [`String`]
1487 /// case 5.  autolink: <http://www.example.com/>
1488 /// case 6.  email address: <test@example.com>
1489 /// case 7.  reference: [example][example]
1490 /// case 8.  collapsed link: [example][]
1491 /// case 9.  shortcut link: [example]
1492 /// case 10. inline without URL: [example]()
1493 /// case 11. reference: [foo][foo]
1494 /// case 12. reference: [foo][bar]
1495 /// case 13. collapsed link: [foo][]
1496 /// case 14. shortcut link: [foo]
1497 /// case 15. inline without URL: [foo]()
1498 /// case 16. just escaped text: \[foo]
1499 /// case 17. inline link: [Foo](foo::Foo)
1500 ///
1501 /// [`Result`]: ../../std/result/enum.Result.html
1502 /// [^example]: https://www.example.com/
1503 pub fn fo$0o() {}
1504 "#,
1505         expect![[r#"
1506                 *foo*
1507
1508                 ```rust
1509                 test
1510                 ```
1511
1512                 ```rust
1513                 pub fn foo()
1514                 ```
1515
1516                 ---
1517
1518                 Test cases:
1519                 case 1.  bare URL: https://www.example.com/
1520                 case 2.  inline URL with title: [example](https://www.example.com/)
1521                 case 3.  code reference: `Result`
1522                 case 4.  code reference but miss footnote: `String`
1523                 case 5.  autolink: http://www.example.com/
1524                 case 6.  email address: test@example.com
1525                 case 7.  reference: example
1526                 case 8.  collapsed link: example
1527                 case 9.  shortcut link: example
1528                 case 10. inline without URL: example
1529                 case 11. reference: foo
1530                 case 12. reference: foo
1531                 case 13. collapsed link: foo
1532                 case 14. shortcut link: foo
1533                 case 15. inline without URL: foo
1534                 case 16. just escaped text: \[foo\]
1535                 case 17. inline link: Foo
1536
1537                 [^example]: https://www.example.com/
1538             "#]],
1539     );
1540 }
1541
1542 #[test]
1543 fn test_hover_macro_generated_struct_fn_doc_comment() {
1544     cov_mark::check!(hover_macro_generated_struct_fn_doc_comment);
1545
1546     check(
1547         r#"
1548 macro_rules! bar {
1549     () => {
1550         struct Bar;
1551         impl Bar {
1552             /// Do the foo
1553             fn foo(&self) {}
1554         }
1555     }
1556 }
1557
1558 bar!();
1559
1560 fn foo() { let bar = Bar; bar.fo$0o(); }
1561 "#,
1562         expect![[r#"
1563                 *foo*
1564
1565                 ```rust
1566                 test::Bar
1567                 ```
1568
1569                 ```rust
1570                 fn foo(&self)
1571                 ```
1572
1573                 ---
1574
1575                 Do the foo
1576             "#]],
1577     );
1578 }
1579
1580 #[test]
1581 fn test_hover_macro_generated_struct_fn_doc_attr() {
1582     cov_mark::check!(hover_macro_generated_struct_fn_doc_attr);
1583
1584     check(
1585         r#"
1586 macro_rules! bar {
1587     () => {
1588         struct Bar;
1589         impl Bar {
1590             #[doc = "Do the foo"]
1591             fn foo(&self) {}
1592         }
1593     }
1594 }
1595
1596 bar!();
1597
1598 fn foo() { let bar = Bar; bar.fo$0o(); }
1599 "#,
1600         expect![[r#"
1601                 *foo*
1602
1603                 ```rust
1604                 test::Bar
1605                 ```
1606
1607                 ```rust
1608                 fn foo(&self)
1609                 ```
1610
1611                 ---
1612
1613                 Do the foo
1614             "#]],
1615     );
1616 }
1617
1618 #[test]
1619 fn test_hover_trait_has_impl_action() {
1620     check_actions(
1621         r#"trait foo$0() {}"#,
1622         expect![[r#"
1623                 [
1624                     Implementation(
1625                         FilePosition {
1626                             file_id: FileId(
1627                                 0,
1628                             ),
1629                             offset: 6,
1630                         },
1631                     ),
1632                 ]
1633             "#]],
1634     );
1635 }
1636
1637 #[test]
1638 fn test_hover_struct_has_impl_action() {
1639     check_actions(
1640         r"struct foo$0() {}",
1641         expect![[r#"
1642                 [
1643                     Implementation(
1644                         FilePosition {
1645                             file_id: FileId(
1646                                 0,
1647                             ),
1648                             offset: 7,
1649                         },
1650                     ),
1651                 ]
1652             "#]],
1653     );
1654 }
1655
1656 #[test]
1657 fn test_hover_union_has_impl_action() {
1658     check_actions(
1659         r#"union foo$0() {}"#,
1660         expect![[r#"
1661                 [
1662                     Implementation(
1663                         FilePosition {
1664                             file_id: FileId(
1665                                 0,
1666                             ),
1667                             offset: 6,
1668                         },
1669                     ),
1670                 ]
1671             "#]],
1672     );
1673 }
1674
1675 #[test]
1676 fn test_hover_enum_has_impl_action() {
1677     check_actions(
1678         r"enum foo$0() { A, B }",
1679         expect![[r#"
1680                 [
1681                     Implementation(
1682                         FilePosition {
1683                             file_id: FileId(
1684                                 0,
1685                             ),
1686                             offset: 5,
1687                         },
1688                     ),
1689                 ]
1690             "#]],
1691     );
1692 }
1693
1694 #[test]
1695 fn test_hover_self_has_impl_action() {
1696     check_actions(
1697         r#"struct foo where Self$0:;"#,
1698         expect![[r#"
1699                 [
1700                     Implementation(
1701                         FilePosition {
1702                             file_id: FileId(
1703                                 0,
1704                             ),
1705                             offset: 7,
1706                         },
1707                     ),
1708                 ]
1709             "#]],
1710     );
1711 }
1712
1713 #[test]
1714 fn test_hover_test_has_action() {
1715     check_actions(
1716         r#"
1717 #[test]
1718 fn foo_$0test() {}
1719 "#,
1720         expect![[r#"
1721                 [
1722                     Reference(
1723                         FilePosition {
1724                             file_id: FileId(
1725                                 0,
1726                             ),
1727                             offset: 11,
1728                         },
1729                     ),
1730                     Runnable(
1731                         Runnable {
1732                             use_name_in_title: false,
1733                             nav: NavigationTarget {
1734                                 file_id: FileId(
1735                                     0,
1736                                 ),
1737                                 full_range: 0..24,
1738                                 focus_range: 11..19,
1739                                 name: "foo_test",
1740                                 kind: Function,
1741                             },
1742                             kind: Test {
1743                                 test_id: Path(
1744                                     "foo_test",
1745                                 ),
1746                                 attr: TestAttr {
1747                                     ignore: false,
1748                                 },
1749                             },
1750                             cfg: None,
1751                         },
1752                     ),
1753                 ]
1754             "#]],
1755     );
1756 }
1757
1758 #[test]
1759 fn test_hover_test_mod_has_action() {
1760     check_actions(
1761         r#"
1762 mod tests$0 {
1763     #[test]
1764     fn foo_test() {}
1765 }
1766 "#,
1767         expect![[r#"
1768                 [
1769                     Runnable(
1770                         Runnable {
1771                             use_name_in_title: false,
1772                             nav: NavigationTarget {
1773                                 file_id: FileId(
1774                                     0,
1775                                 ),
1776                                 full_range: 0..46,
1777                                 focus_range: 4..9,
1778                                 name: "tests",
1779                                 kind: Module,
1780                                 description: "mod tests",
1781                             },
1782                             kind: TestMod {
1783                                 path: "tests",
1784                             },
1785                             cfg: None,
1786                         },
1787                     ),
1788                 ]
1789             "#]],
1790     );
1791 }
1792
1793 #[test]
1794 fn test_hover_struct_has_goto_type_action() {
1795     check_actions(
1796         r#"
1797 struct S{ f1: u32 }
1798
1799 fn main() { let s$0t = S{ f1:0 }; }
1800 "#,
1801         expect![[r#"
1802                 [
1803                     GoToType(
1804                         [
1805                             HoverGotoTypeData {
1806                                 mod_path: "test::S",
1807                                 nav: NavigationTarget {
1808                                     file_id: FileId(
1809                                         0,
1810                                     ),
1811                                     full_range: 0..19,
1812                                     focus_range: 7..8,
1813                                     name: "S",
1814                                     kind: Struct,
1815                                     description: "struct S",
1816                                 },
1817                             },
1818                         ],
1819                     ),
1820                 ]
1821             "#]],
1822     );
1823 }
1824
1825 #[test]
1826 fn test_hover_generic_struct_has_goto_type_actions() {
1827     check_actions(
1828         r#"
1829 struct Arg(u32);
1830 struct S<T>{ f1: T }
1831
1832 fn main() { let s$0t = S{ f1:Arg(0) }; }
1833 "#,
1834         expect![[r#"
1835                 [
1836                     GoToType(
1837                         [
1838                             HoverGotoTypeData {
1839                                 mod_path: "test::S",
1840                                 nav: NavigationTarget {
1841                                     file_id: FileId(
1842                                         0,
1843                                     ),
1844                                     full_range: 17..37,
1845                                     focus_range: 24..25,
1846                                     name: "S",
1847                                     kind: Struct,
1848                                     description: "struct S<T>",
1849                                 },
1850                             },
1851                             HoverGotoTypeData {
1852                                 mod_path: "test::Arg",
1853                                 nav: NavigationTarget {
1854                                     file_id: FileId(
1855                                         0,
1856                                     ),
1857                                     full_range: 0..16,
1858                                     focus_range: 7..10,
1859                                     name: "Arg",
1860                                     kind: Struct,
1861                                     description: "struct Arg",
1862                                 },
1863                             },
1864                         ],
1865                     ),
1866                 ]
1867             "#]],
1868     );
1869 }
1870
1871 #[test]
1872 fn test_hover_generic_struct_has_flattened_goto_type_actions() {
1873     check_actions(
1874         r#"
1875 struct Arg(u32);
1876 struct S<T>{ f1: T }
1877
1878 fn main() { let s$0t = S{ f1: S{ f1: Arg(0) } }; }
1879 "#,
1880         expect![[r#"
1881                 [
1882                     GoToType(
1883                         [
1884                             HoverGotoTypeData {
1885                                 mod_path: "test::S",
1886                                 nav: NavigationTarget {
1887                                     file_id: FileId(
1888                                         0,
1889                                     ),
1890                                     full_range: 17..37,
1891                                     focus_range: 24..25,
1892                                     name: "S",
1893                                     kind: Struct,
1894                                     description: "struct S<T>",
1895                                 },
1896                             },
1897                             HoverGotoTypeData {
1898                                 mod_path: "test::Arg",
1899                                 nav: NavigationTarget {
1900                                     file_id: FileId(
1901                                         0,
1902                                     ),
1903                                     full_range: 0..16,
1904                                     focus_range: 7..10,
1905                                     name: "Arg",
1906                                     kind: Struct,
1907                                     description: "struct Arg",
1908                                 },
1909                             },
1910                         ],
1911                     ),
1912                 ]
1913             "#]],
1914     );
1915 }
1916
1917 #[test]
1918 fn test_hover_tuple_has_goto_type_actions() {
1919     check_actions(
1920         r#"
1921 struct A(u32);
1922 struct B(u32);
1923 mod M {
1924     pub struct C(u32);
1925 }
1926
1927 fn main() { let s$0t = (A(1), B(2), M::C(3) ); }
1928 "#,
1929         expect![[r#"
1930                 [
1931                     GoToType(
1932                         [
1933                             HoverGotoTypeData {
1934                                 mod_path: "test::A",
1935                                 nav: NavigationTarget {
1936                                     file_id: FileId(
1937                                         0,
1938                                     ),
1939                                     full_range: 0..14,
1940                                     focus_range: 7..8,
1941                                     name: "A",
1942                                     kind: Struct,
1943                                     description: "struct A",
1944                                 },
1945                             },
1946                             HoverGotoTypeData {
1947                                 mod_path: "test::B",
1948                                 nav: NavigationTarget {
1949                                     file_id: FileId(
1950                                         0,
1951                                     ),
1952                                     full_range: 15..29,
1953                                     focus_range: 22..23,
1954                                     name: "B",
1955                                     kind: Struct,
1956                                     description: "struct B",
1957                                 },
1958                             },
1959                             HoverGotoTypeData {
1960                                 mod_path: "test::M::C",
1961                                 nav: NavigationTarget {
1962                                     file_id: FileId(
1963                                         0,
1964                                     ),
1965                                     full_range: 42..60,
1966                                     focus_range: 53..54,
1967                                     name: "C",
1968                                     kind: Struct,
1969                                     description: "pub struct C",
1970                                 },
1971                             },
1972                         ],
1973                     ),
1974                 ]
1975             "#]],
1976     );
1977 }
1978
1979 #[test]
1980 fn test_hover_return_impl_trait_has_goto_type_action() {
1981     check_actions(
1982         r#"
1983 trait Foo {}
1984 fn foo() -> impl Foo {}
1985
1986 fn main() { let s$0t = foo(); }
1987 "#,
1988         expect![[r#"
1989                 [
1990                     GoToType(
1991                         [
1992                             HoverGotoTypeData {
1993                                 mod_path: "test::Foo",
1994                                 nav: NavigationTarget {
1995                                     file_id: FileId(
1996                                         0,
1997                                     ),
1998                                     full_range: 0..12,
1999                                     focus_range: 6..9,
2000                                     name: "Foo",
2001                                     kind: Trait,
2002                                     description: "trait Foo",
2003                                 },
2004                             },
2005                         ],
2006                     ),
2007                 ]
2008             "#]],
2009     );
2010 }
2011
2012 #[test]
2013 fn test_hover_generic_return_impl_trait_has_goto_type_action() {
2014     check_actions(
2015         r#"
2016 trait Foo<T> {}
2017 struct S;
2018 fn foo() -> impl Foo<S> {}
2019
2020 fn main() { let s$0t = foo(); }
2021 "#,
2022         expect![[r#"
2023                 [
2024                     GoToType(
2025                         [
2026                             HoverGotoTypeData {
2027                                 mod_path: "test::Foo",
2028                                 nav: NavigationTarget {
2029                                     file_id: FileId(
2030                                         0,
2031                                     ),
2032                                     full_range: 0..15,
2033                                     focus_range: 6..9,
2034                                     name: "Foo",
2035                                     kind: Trait,
2036                                     description: "trait Foo<T>",
2037                                 },
2038                             },
2039                             HoverGotoTypeData {
2040                                 mod_path: "test::S",
2041                                 nav: NavigationTarget {
2042                                     file_id: FileId(
2043                                         0,
2044                                     ),
2045                                     full_range: 16..25,
2046                                     focus_range: 23..24,
2047                                     name: "S",
2048                                     kind: Struct,
2049                                     description: "struct S",
2050                                 },
2051                             },
2052                         ],
2053                     ),
2054                 ]
2055             "#]],
2056     );
2057 }
2058
2059 #[test]
2060 fn test_hover_return_impl_traits_has_goto_type_action() {
2061     check_actions(
2062         r#"
2063 trait Foo {}
2064 trait Bar {}
2065 fn foo() -> impl Foo + Bar {}
2066
2067 fn main() { let s$0t = foo(); }
2068 "#,
2069         expect![[r#"
2070                 [
2071                     GoToType(
2072                         [
2073                             HoverGotoTypeData {
2074                                 mod_path: "test::Foo",
2075                                 nav: NavigationTarget {
2076                                     file_id: FileId(
2077                                         0,
2078                                     ),
2079                                     full_range: 0..12,
2080                                     focus_range: 6..9,
2081                                     name: "Foo",
2082                                     kind: Trait,
2083                                     description: "trait Foo",
2084                                 },
2085                             },
2086                             HoverGotoTypeData {
2087                                 mod_path: "test::Bar",
2088                                 nav: NavigationTarget {
2089                                     file_id: FileId(
2090                                         0,
2091                                     ),
2092                                     full_range: 13..25,
2093                                     focus_range: 19..22,
2094                                     name: "Bar",
2095                                     kind: Trait,
2096                                     description: "trait Bar",
2097                                 },
2098                             },
2099                         ],
2100                     ),
2101                 ]
2102             "#]],
2103     );
2104 }
2105
2106 #[test]
2107 fn test_hover_generic_return_impl_traits_has_goto_type_action() {
2108     check_actions(
2109         r#"
2110 trait Foo<T> {}
2111 trait Bar<T> {}
2112 struct S1 {}
2113 struct S2 {}
2114
2115 fn foo() -> impl Foo<S1> + Bar<S2> {}
2116
2117 fn main() { let s$0t = foo(); }
2118 "#,
2119         expect![[r#"
2120                 [
2121                     GoToType(
2122                         [
2123                             HoverGotoTypeData {
2124                                 mod_path: "test::Foo",
2125                                 nav: NavigationTarget {
2126                                     file_id: FileId(
2127                                         0,
2128                                     ),
2129                                     full_range: 0..15,
2130                                     focus_range: 6..9,
2131                                     name: "Foo",
2132                                     kind: Trait,
2133                                     description: "trait Foo<T>",
2134                                 },
2135                             },
2136                             HoverGotoTypeData {
2137                                 mod_path: "test::Bar",
2138                                 nav: NavigationTarget {
2139                                     file_id: FileId(
2140                                         0,
2141                                     ),
2142                                     full_range: 16..31,
2143                                     focus_range: 22..25,
2144                                     name: "Bar",
2145                                     kind: Trait,
2146                                     description: "trait Bar<T>",
2147                                 },
2148                             },
2149                             HoverGotoTypeData {
2150                                 mod_path: "test::S1",
2151                                 nav: NavigationTarget {
2152                                     file_id: FileId(
2153                                         0,
2154                                     ),
2155                                     full_range: 32..44,
2156                                     focus_range: 39..41,
2157                                     name: "S1",
2158                                     kind: Struct,
2159                                     description: "struct S1",
2160                                 },
2161                             },
2162                             HoverGotoTypeData {
2163                                 mod_path: "test::S2",
2164                                 nav: NavigationTarget {
2165                                     file_id: FileId(
2166                                         0,
2167                                     ),
2168                                     full_range: 45..57,
2169                                     focus_range: 52..54,
2170                                     name: "S2",
2171                                     kind: Struct,
2172                                     description: "struct S2",
2173                                 },
2174                             },
2175                         ],
2176                     ),
2177                 ]
2178             "#]],
2179     );
2180 }
2181
2182 #[test]
2183 fn test_hover_arg_impl_trait_has_goto_type_action() {
2184     check_actions(
2185         r#"
2186 trait Foo {}
2187 fn foo(ar$0g: &impl Foo) {}
2188 "#,
2189         expect![[r#"
2190                 [
2191                     GoToType(
2192                         [
2193                             HoverGotoTypeData {
2194                                 mod_path: "test::Foo",
2195                                 nav: NavigationTarget {
2196                                     file_id: FileId(
2197                                         0,
2198                                     ),
2199                                     full_range: 0..12,
2200                                     focus_range: 6..9,
2201                                     name: "Foo",
2202                                     kind: Trait,
2203                                     description: "trait Foo",
2204                                 },
2205                             },
2206                         ],
2207                     ),
2208                 ]
2209             "#]],
2210     );
2211 }
2212
2213 #[test]
2214 fn test_hover_arg_impl_traits_has_goto_type_action() {
2215     check_actions(
2216         r#"
2217 trait Foo {}
2218 trait Bar<T> {}
2219 struct S{}
2220
2221 fn foo(ar$0g: &impl Foo + Bar<S>) {}
2222 "#,
2223         expect![[r#"
2224                 [
2225                     GoToType(
2226                         [
2227                             HoverGotoTypeData {
2228                                 mod_path: "test::Foo",
2229                                 nav: NavigationTarget {
2230                                     file_id: FileId(
2231                                         0,
2232                                     ),
2233                                     full_range: 0..12,
2234                                     focus_range: 6..9,
2235                                     name: "Foo",
2236                                     kind: Trait,
2237                                     description: "trait Foo",
2238                                 },
2239                             },
2240                             HoverGotoTypeData {
2241                                 mod_path: "test::Bar",
2242                                 nav: NavigationTarget {
2243                                     file_id: FileId(
2244                                         0,
2245                                     ),
2246                                     full_range: 13..28,
2247                                     focus_range: 19..22,
2248                                     name: "Bar",
2249                                     kind: Trait,
2250                                     description: "trait Bar<T>",
2251                                 },
2252                             },
2253                             HoverGotoTypeData {
2254                                 mod_path: "test::S",
2255                                 nav: NavigationTarget {
2256                                     file_id: FileId(
2257                                         0,
2258                                     ),
2259                                     full_range: 29..39,
2260                                     focus_range: 36..37,
2261                                     name: "S",
2262                                     kind: Struct,
2263                                     description: "struct S",
2264                                 },
2265                             },
2266                         ],
2267                     ),
2268                 ]
2269             "#]],
2270     );
2271 }
2272
2273 #[test]
2274 fn test_hover_async_block_impl_trait_has_goto_type_action() {
2275     check_actions(
2276         r#"
2277 //- minicore: future
2278 struct S;
2279 fn foo() {
2280     let fo$0o = async { S };
2281 }
2282 "#,
2283         expect![[r#"
2284                 [
2285                     GoToType(
2286                         [
2287                             HoverGotoTypeData {
2288                                 mod_path: "core::future::Future",
2289                                 nav: NavigationTarget {
2290                                     file_id: FileId(
2291                                         1,
2292                                     ),
2293                                     full_range: 276..458,
2294                                     focus_range: 315..321,
2295                                     name: "Future",
2296                                     kind: Trait,
2297                                     description: "pub trait Future",
2298                                 },
2299                             },
2300                             HoverGotoTypeData {
2301                                 mod_path: "test::S",
2302                                 nav: NavigationTarget {
2303                                     file_id: FileId(
2304                                         0,
2305                                     ),
2306                                     full_range: 0..9,
2307                                     focus_range: 7..8,
2308                                     name: "S",
2309                                     kind: Struct,
2310                                     description: "struct S",
2311                                 },
2312                             },
2313                         ],
2314                     ),
2315                 ]
2316             "#]],
2317     );
2318 }
2319
2320 #[test]
2321 fn test_hover_arg_generic_impl_trait_has_goto_type_action() {
2322     check_actions(
2323         r#"
2324 trait Foo<T> {}
2325 struct S {}
2326 fn foo(ar$0g: &impl Foo<S>) {}
2327 "#,
2328         expect![[r#"
2329                 [
2330                     GoToType(
2331                         [
2332                             HoverGotoTypeData {
2333                                 mod_path: "test::Foo",
2334                                 nav: NavigationTarget {
2335                                     file_id: FileId(
2336                                         0,
2337                                     ),
2338                                     full_range: 0..15,
2339                                     focus_range: 6..9,
2340                                     name: "Foo",
2341                                     kind: Trait,
2342                                     description: "trait Foo<T>",
2343                                 },
2344                             },
2345                             HoverGotoTypeData {
2346                                 mod_path: "test::S",
2347                                 nav: NavigationTarget {
2348                                     file_id: FileId(
2349                                         0,
2350                                     ),
2351                                     full_range: 16..27,
2352                                     focus_range: 23..24,
2353                                     name: "S",
2354                                     kind: Struct,
2355                                     description: "struct S",
2356                                 },
2357                             },
2358                         ],
2359                     ),
2360                 ]
2361             "#]],
2362     );
2363 }
2364
2365 #[test]
2366 fn test_hover_dyn_return_has_goto_type_action() {
2367     check_actions(
2368         r#"
2369 trait Foo {}
2370 struct S;
2371 impl Foo for S {}
2372
2373 struct B<T>{}
2374 fn foo() -> B<dyn Foo> {}
2375
2376 fn main() { let s$0t = foo(); }
2377 "#,
2378         expect![[r#"
2379                 [
2380                     GoToType(
2381                         [
2382                             HoverGotoTypeData {
2383                                 mod_path: "test::B",
2384                                 nav: NavigationTarget {
2385                                     file_id: FileId(
2386                                         0,
2387                                     ),
2388                                     full_range: 42..55,
2389                                     focus_range: 49..50,
2390                                     name: "B",
2391                                     kind: Struct,
2392                                     description: "struct B<T>",
2393                                 },
2394                             },
2395                             HoverGotoTypeData {
2396                                 mod_path: "test::Foo",
2397                                 nav: NavigationTarget {
2398                                     file_id: FileId(
2399                                         0,
2400                                     ),
2401                                     full_range: 0..12,
2402                                     focus_range: 6..9,
2403                                     name: "Foo",
2404                                     kind: Trait,
2405                                     description: "trait Foo",
2406                                 },
2407                             },
2408                         ],
2409                     ),
2410                 ]
2411             "#]],
2412     );
2413 }
2414
2415 #[test]
2416 fn test_hover_dyn_arg_has_goto_type_action() {
2417     check_actions(
2418         r#"
2419 trait Foo {}
2420 fn foo(ar$0g: &dyn Foo) {}
2421 "#,
2422         expect![[r#"
2423                 [
2424                     GoToType(
2425                         [
2426                             HoverGotoTypeData {
2427                                 mod_path: "test::Foo",
2428                                 nav: NavigationTarget {
2429                                     file_id: FileId(
2430                                         0,
2431                                     ),
2432                                     full_range: 0..12,
2433                                     focus_range: 6..9,
2434                                     name: "Foo",
2435                                     kind: Trait,
2436                                     description: "trait Foo",
2437                                 },
2438                             },
2439                         ],
2440                     ),
2441                 ]
2442             "#]],
2443     );
2444 }
2445
2446 #[test]
2447 fn test_hover_generic_dyn_arg_has_goto_type_action() {
2448     check_actions(
2449         r#"
2450 trait Foo<T> {}
2451 struct S {}
2452 fn foo(ar$0g: &dyn Foo<S>) {}
2453 "#,
2454         expect![[r#"
2455                 [
2456                     GoToType(
2457                         [
2458                             HoverGotoTypeData {
2459                                 mod_path: "test::Foo",
2460                                 nav: NavigationTarget {
2461                                     file_id: FileId(
2462                                         0,
2463                                     ),
2464                                     full_range: 0..15,
2465                                     focus_range: 6..9,
2466                                     name: "Foo",
2467                                     kind: Trait,
2468                                     description: "trait Foo<T>",
2469                                 },
2470                             },
2471                             HoverGotoTypeData {
2472                                 mod_path: "test::S",
2473                                 nav: NavigationTarget {
2474                                     file_id: FileId(
2475                                         0,
2476                                     ),
2477                                     full_range: 16..27,
2478                                     focus_range: 23..24,
2479                                     name: "S",
2480                                     kind: Struct,
2481                                     description: "struct S",
2482                                 },
2483                             },
2484                         ],
2485                     ),
2486                 ]
2487             "#]],
2488     );
2489 }
2490
2491 #[test]
2492 fn test_hover_goto_type_action_links_order() {
2493     check_actions(
2494         r#"
2495 trait ImplTrait<T> {}
2496 trait DynTrait<T> {}
2497 struct B<T> {}
2498 struct S {}
2499
2500 fn foo(a$0rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
2501 "#,
2502         expect![[r#"
2503                 [
2504                     GoToType(
2505                         [
2506                             HoverGotoTypeData {
2507                                 mod_path: "test::ImplTrait",
2508                                 nav: NavigationTarget {
2509                                     file_id: FileId(
2510                                         0,
2511                                     ),
2512                                     full_range: 0..21,
2513                                     focus_range: 6..15,
2514                                     name: "ImplTrait",
2515                                     kind: Trait,
2516                                     description: "trait ImplTrait<T>",
2517                                 },
2518                             },
2519                             HoverGotoTypeData {
2520                                 mod_path: "test::B",
2521                                 nav: NavigationTarget {
2522                                     file_id: FileId(
2523                                         0,
2524                                     ),
2525                                     full_range: 43..57,
2526                                     focus_range: 50..51,
2527                                     name: "B",
2528                                     kind: Struct,
2529                                     description: "struct B<T>",
2530                                 },
2531                             },
2532                             HoverGotoTypeData {
2533                                 mod_path: "test::DynTrait",
2534                                 nav: NavigationTarget {
2535                                     file_id: FileId(
2536                                         0,
2537                                     ),
2538                                     full_range: 22..42,
2539                                     focus_range: 28..36,
2540                                     name: "DynTrait",
2541                                     kind: Trait,
2542                                     description: "trait DynTrait<T>",
2543                                 },
2544                             },
2545                             HoverGotoTypeData {
2546                                 mod_path: "test::S",
2547                                 nav: NavigationTarget {
2548                                     file_id: FileId(
2549                                         0,
2550                                     ),
2551                                     full_range: 58..69,
2552                                     focus_range: 65..66,
2553                                     name: "S",
2554                                     kind: Struct,
2555                                     description: "struct S",
2556                                 },
2557                             },
2558                         ],
2559                     ),
2560                 ]
2561             "#]],
2562     );
2563 }
2564
2565 #[test]
2566 fn test_hover_associated_type_has_goto_type_action() {
2567     check_actions(
2568         r#"
2569 trait Foo {
2570     type Item;
2571     fn get(self) -> Self::Item {}
2572 }
2573
2574 struct Bar{}
2575 struct S{}
2576
2577 impl Foo for S { type Item = Bar; }
2578
2579 fn test() -> impl Foo { S {} }
2580
2581 fn main() { let s$0t = test().get(); }
2582 "#,
2583         expect![[r#"
2584                 [
2585                     GoToType(
2586                         [
2587                             HoverGotoTypeData {
2588                                 mod_path: "test::Foo",
2589                                 nav: NavigationTarget {
2590                                     file_id: FileId(
2591                                         0,
2592                                     ),
2593                                     full_range: 0..62,
2594                                     focus_range: 6..9,
2595                                     name: "Foo",
2596                                     kind: Trait,
2597                                     description: "trait Foo",
2598                                 },
2599                             },
2600                         ],
2601                     ),
2602                 ]
2603             "#]],
2604     );
2605 }
2606
2607 #[test]
2608 fn test_hover_const_param_has_goto_type_action() {
2609     check_actions(
2610         r#"
2611 struct Bar;
2612 struct Foo<const BAR: Bar>;
2613
2614 impl<const BAR: Bar> Foo<BAR$0> {}
2615 "#,
2616         expect![[r#"
2617                 [
2618                     GoToType(
2619                         [
2620                             HoverGotoTypeData {
2621                                 mod_path: "test::Bar",
2622                                 nav: NavigationTarget {
2623                                     file_id: FileId(
2624                                         0,
2625                                     ),
2626                                     full_range: 0..11,
2627                                     focus_range: 7..10,
2628                                     name: "Bar",
2629                                     kind: Struct,
2630                                     description: "struct Bar",
2631                                 },
2632                             },
2633                         ],
2634                     ),
2635                 ]
2636             "#]],
2637     );
2638 }
2639
2640 #[test]
2641 fn test_hover_type_param_has_goto_type_action() {
2642     check_actions(
2643         r#"
2644 trait Foo {}
2645
2646 fn foo<T: Foo>(t: T$0){}
2647 "#,
2648         expect![[r#"
2649                 [
2650                     GoToType(
2651                         [
2652                             HoverGotoTypeData {
2653                                 mod_path: "test::Foo",
2654                                 nav: NavigationTarget {
2655                                     file_id: FileId(
2656                                         0,
2657                                     ),
2658                                     full_range: 0..12,
2659                                     focus_range: 6..9,
2660                                     name: "Foo",
2661                                     kind: Trait,
2662                                     description: "trait Foo",
2663                                 },
2664                             },
2665                         ],
2666                     ),
2667                 ]
2668             "#]],
2669     );
2670 }
2671
2672 #[test]
2673 fn test_hover_self_has_go_to_type() {
2674     check_actions(
2675         r#"
2676 struct Foo;
2677 impl Foo {
2678     fn foo(&self$0) {}
2679 }
2680 "#,
2681         expect![[r#"
2682                 [
2683                     GoToType(
2684                         [
2685                             HoverGotoTypeData {
2686                                 mod_path: "test::Foo",
2687                                 nav: NavigationTarget {
2688                                     file_id: FileId(
2689                                         0,
2690                                     ),
2691                                     full_range: 0..11,
2692                                     focus_range: 7..10,
2693                                     name: "Foo",
2694                                     kind: Struct,
2695                                     description: "struct Foo",
2696                                 },
2697                             },
2698                         ],
2699                     ),
2700                 ]
2701             "#]],
2702     );
2703 }
2704
2705 #[test]
2706 fn hover_displays_normalized_crate_names() {
2707     check(
2708         r#"
2709 //- /lib.rs crate:name-with-dashes
2710 pub mod wrapper {
2711     pub struct Thing { x: u32 }
2712
2713     impl Thing {
2714         pub fn new() -> Thing { Thing { x: 0 } }
2715     }
2716 }
2717
2718 //- /main.rs crate:main deps:name-with-dashes
2719 fn main() { let foo_test = name_with_dashes::wrapper::Thing::new$0(); }
2720 "#,
2721         expect![[r#"
2722             *new*
2723
2724             ```rust
2725             name_with_dashes::wrapper::Thing
2726             ```
2727
2728             ```rust
2729             pub fn new() -> Thing
2730             ```
2731             "#]],
2732     )
2733 }
2734
2735 #[test]
2736 fn hover_field_pat_shorthand_ref_match_ergonomics() {
2737     check(
2738         r#"
2739 struct S {
2740     f: i32,
2741 }
2742
2743 fn main() {
2744     let s = S { f: 0 };
2745     let S { f$0 } = &s;
2746 }
2747 "#,
2748         expect![[r#"
2749                 *f*
2750
2751                 ```rust
2752                 f: &i32
2753                 ```
2754                 ---
2755
2756                 ```rust
2757                 test::S
2758                 ```
2759
2760                 ```rust
2761                 f: i32
2762                 ```
2763             "#]],
2764     );
2765 }
2766
2767 #[test]
2768 fn hover_self_param_shows_type() {
2769     check(
2770         r#"
2771 struct Foo {}
2772 impl Foo {
2773     fn bar(&sel$0f) {}
2774 }
2775 "#,
2776         expect![[r#"
2777                 *self*
2778
2779                 ```rust
2780                 self: &Foo
2781                 ```
2782             "#]],
2783     );
2784 }
2785
2786 #[test]
2787 fn hover_self_param_shows_type_for_arbitrary_self_type() {
2788     check(
2789         r#"
2790 struct Arc<T>(T);
2791 struct Foo {}
2792 impl Foo {
2793     fn bar(sel$0f: Arc<Foo>) {}
2794 }
2795 "#,
2796         expect![[r#"
2797                 *self*
2798
2799                 ```rust
2800                 self: Arc<Foo>
2801                 ```
2802             "#]],
2803     );
2804 }
2805
2806 #[test]
2807 fn hover_doc_outer_inner() {
2808     check(
2809         r#"
2810 /// Be quick;
2811 mod Foo$0 {
2812     //! time is mana
2813
2814     /// This comment belongs to the function
2815     fn foo() {}
2816 }
2817 "#,
2818         expect![[r#"
2819                 *Foo*
2820
2821                 ```rust
2822                 test
2823                 ```
2824
2825                 ```rust
2826                 mod Foo
2827                 ```
2828
2829                 ---
2830
2831                 Be quick;
2832                 time is mana
2833             "#]],
2834     );
2835 }
2836
2837 #[test]
2838 fn hover_doc_outer_inner_attribue() {
2839     check(
2840         r#"
2841 #[doc = "Be quick;"]
2842 mod Foo$0 {
2843     #![doc = "time is mana"]
2844
2845     #[doc = "This comment belongs to the function"]
2846     fn foo() {}
2847 }
2848 "#,
2849         expect![[r#"
2850                 *Foo*
2851
2852                 ```rust
2853                 test
2854                 ```
2855
2856                 ```rust
2857                 mod Foo
2858                 ```
2859
2860                 ---
2861
2862                 Be quick;
2863                 time is mana
2864             "#]],
2865     );
2866 }
2867
2868 #[test]
2869 fn hover_doc_block_style_indentend() {
2870     check(
2871         r#"
2872 /**
2873     foo
2874     ```rust
2875     let x = 3;
2876     ```
2877 */
2878 fn foo$0() {}
2879 "#,
2880         expect![[r#"
2881                 *foo*
2882
2883                 ```rust
2884                 test
2885                 ```
2886
2887                 ```rust
2888                 fn foo()
2889                 ```
2890
2891                 ---
2892
2893                 foo
2894
2895                 ```rust
2896                 let x = 3;
2897                 ```
2898             "#]],
2899     );
2900 }
2901
2902 #[test]
2903 fn hover_comments_dont_highlight_parent() {
2904     cov_mark::check!(no_highlight_on_comment_hover);
2905     check_hover_no_result(
2906         r#"
2907 fn no_hover() {
2908     // no$0hover
2909 }
2910 "#,
2911     );
2912 }
2913
2914 #[test]
2915 fn hover_label() {
2916     check(
2917         r#"
2918 fn foo() {
2919     'label$0: loop {}
2920 }
2921 "#,
2922         expect![[r#"
2923             *'label*
2924
2925             ```rust
2926             'label
2927             ```
2928             "#]],
2929     );
2930 }
2931
2932 #[test]
2933 fn hover_lifetime() {
2934     check(
2935         r#"fn foo<'lifetime>(_: &'lifetime$0 ()) {}"#,
2936         expect![[r#"
2937             *'lifetime*
2938
2939             ```rust
2940             'lifetime
2941             ```
2942             "#]],
2943     );
2944 }
2945
2946 #[test]
2947 fn hover_type_param() {
2948     check(
2949         r#"
2950 //- minicore: sized
2951 struct Foo<T>(T);
2952 trait TraitA {}
2953 trait TraitB {}
2954 impl<T: TraitA + TraitB> Foo<T$0> where T: Sized {}
2955 "#,
2956         expect![[r#"
2957                 *T*
2958
2959                 ```rust
2960                 T: TraitA + TraitB
2961                 ```
2962             "#]],
2963     );
2964     check(
2965         r#"
2966 //- minicore: sized
2967 struct Foo<T>(T);
2968 impl<T> Foo<T$0> {}
2969 "#,
2970         expect![[r#"
2971                 *T*
2972
2973                 ```rust
2974                 T
2975                 ```
2976                 "#]],
2977     );
2978     // lifetimes bounds arent being tracked yet
2979     check(
2980         r#"
2981 //- minicore: sized
2982 struct Foo<T>(T);
2983 impl<T: 'static> Foo<T$0> {}
2984 "#,
2985         expect![[r#"
2986                 *T*
2987
2988                 ```rust
2989                 T
2990                 ```
2991                 "#]],
2992     );
2993 }
2994
2995 #[test]
2996 fn hover_type_param_sized_bounds() {
2997     // implicit `: Sized` bound
2998     check(
2999         r#"
3000 //- minicore: sized
3001 trait Trait {}
3002 struct Foo<T>(T);
3003 impl<T: Trait> Foo<T$0> {}
3004 "#,
3005         expect![[r#"
3006                 *T*
3007
3008                 ```rust
3009                 T: Trait
3010                 ```
3011             "#]],
3012     );
3013     check(
3014         r#"
3015 //- minicore: sized
3016 trait Trait {}
3017 struct Foo<T>(T);
3018 impl<T: Trait + ?Sized> Foo<T$0> {}
3019 "#,
3020         expect![[r#"
3021                 *T*
3022
3023                 ```rust
3024                 T: Trait + ?Sized
3025                 ```
3026             "#]],
3027     );
3028 }
3029
3030 mod type_param_sized_bounds {
3031     use super::*;
3032
3033     #[test]
3034     fn single_implicit() {
3035         check(
3036             r#"
3037 //- minicore: sized
3038 fn foo<T$0>() {}
3039 "#,
3040             expect![[r#"
3041                     *T*
3042
3043                     ```rust
3044                     T
3045                     ```
3046                 "#]],
3047         );
3048     }
3049
3050     #[test]
3051     fn single_explicit() {
3052         check(
3053             r#"
3054 //- minicore: sized
3055 fn foo<T$0: Sized>() {}
3056 "#,
3057             expect![[r#"
3058                     *T*
3059
3060                     ```rust
3061                     T
3062                     ```
3063                 "#]],
3064         );
3065     }
3066
3067     #[test]
3068     fn single_relaxed() {
3069         check(
3070             r#"
3071 //- minicore: sized
3072 fn foo<T$0: ?Sized>() {}
3073 "#,
3074             expect![[r#"
3075                     *T*
3076
3077                     ```rust
3078                     T: ?Sized
3079                     ```
3080                 "#]],
3081         );
3082     }
3083
3084     #[test]
3085     fn multiple_implicit() {
3086         check(
3087             r#"
3088 //- minicore: sized
3089 trait Trait {}
3090 fn foo<T$0: Trait>() {}
3091 "#,
3092             expect![[r#"
3093                     *T*
3094
3095                     ```rust
3096                     T: Trait
3097                     ```
3098                 "#]],
3099         );
3100     }
3101
3102     #[test]
3103     fn multiple_explicit() {
3104         check(
3105             r#"
3106 //- minicore: sized
3107 trait Trait {}
3108 fn foo<T$0: Trait + Sized>() {}
3109 "#,
3110             expect![[r#"
3111                     *T*
3112
3113                     ```rust
3114                     T: Trait
3115                     ```
3116                 "#]],
3117         );
3118     }
3119
3120     #[test]
3121     fn multiple_relaxed() {
3122         check(
3123             r#"
3124 //- minicore: sized
3125 trait Trait {}
3126 fn foo<T$0: Trait + ?Sized>() {}
3127 "#,
3128             expect![[r#"
3129                     *T*
3130
3131                     ```rust
3132                     T: Trait + ?Sized
3133                     ```
3134                 "#]],
3135         );
3136     }
3137
3138     #[test]
3139     fn mixed() {
3140         check(
3141             r#"
3142 //- minicore: sized
3143 fn foo<T$0: ?Sized + Sized + Sized>() {}
3144 "#,
3145             expect![[r#"
3146                     *T*
3147
3148                     ```rust
3149                     T
3150                     ```
3151                 "#]],
3152         );
3153         check(
3154             r#"
3155 //- minicore: sized
3156 trait Trait {}
3157 fn foo<T$0: Sized + ?Sized + Sized + Trait>() {}
3158 "#,
3159             expect![[r#"
3160                     *T*
3161
3162                     ```rust
3163                     T: Trait
3164                     ```
3165                 "#]],
3166         );
3167     }
3168 }
3169
3170 #[test]
3171 fn hover_const_param() {
3172     check(
3173         r#"
3174 struct Foo<const LEN: usize>;
3175 impl<const LEN: usize> Foo<LEN$0> {}
3176 "#,
3177         expect![[r#"
3178                 *LEN*
3179
3180                 ```rust
3181                 const LEN: usize
3182                 ```
3183             "#]],
3184     );
3185 }
3186
3187 #[test]
3188 fn hover_const_pat() {
3189     check(
3190         r#"
3191 /// This is a doc
3192 const FOO: usize = 3;
3193 fn foo() {
3194     match 5 {
3195         FOO$0 => (),
3196         _ => ()
3197     }
3198 }
3199 "#,
3200         expect![[r#"
3201             *FOO*
3202
3203             ```rust
3204             test
3205             ```
3206
3207             ```rust
3208             const FOO: usize = 3
3209             ```
3210
3211             ---
3212
3213             This is a doc
3214         "#]],
3215     );
3216 }
3217
3218 #[test]
3219 fn hover_mod_def() {
3220     check(
3221         r#"
3222 //- /main.rs
3223 mod foo$0;
3224 //- /foo.rs
3225 //! For the horde!
3226 "#,
3227         expect![[r#"
3228                 *foo*
3229
3230                 ```rust
3231                 test
3232                 ```
3233
3234                 ```rust
3235                 mod foo
3236                 ```
3237
3238                 ---
3239
3240                 For the horde!
3241             "#]],
3242     );
3243 }
3244
3245 #[test]
3246 fn hover_self_in_use() {
3247     check(
3248         r#"
3249 //! This should not appear
3250 mod foo {
3251     /// But this should appear
3252     pub mod bar {}
3253 }
3254 use foo::bar::{self$0};
3255 "#,
3256         expect![[r#"
3257                 *self*
3258
3259                 ```rust
3260                 test::foo
3261                 ```
3262
3263                 ```rust
3264                 mod bar
3265                 ```
3266
3267                 ---
3268
3269                 But this should appear
3270             "#]],
3271     )
3272 }
3273
3274 #[test]
3275 fn hover_keyword() {
3276     check(
3277         r#"
3278 //- /main.rs crate:main deps:std
3279 fn f() { retur$0n; }
3280 //- /libstd.rs crate:std
3281 /// Docs for return_keyword
3282 mod return_keyword {}
3283 "#,
3284         expect![[r#"
3285                 *return*
3286
3287                 ```rust
3288                 return
3289                 ```
3290
3291                 ---
3292
3293                 Docs for return_keyword
3294             "#]],
3295     );
3296 }
3297
3298 #[test]
3299 fn hover_builtin() {
3300     check(
3301         r#"
3302 //- /main.rs crate:main deps:std
3303 cosnt _: &str$0 = ""; }
3304
3305 //- /libstd.rs crate:std
3306 /// Docs for prim_str
3307 mod prim_str {}
3308 "#,
3309         expect![[r#"
3310                 *str*
3311
3312                 ```rust
3313                 str
3314                 ```
3315
3316                 ---
3317
3318                 Docs for prim_str
3319             "#]],
3320     );
3321 }
3322
3323 #[test]
3324 fn hover_macro_expanded_function() {
3325     check(
3326         r#"
3327 struct S<'a, T>(&'a T);
3328 trait Clone {}
3329 macro_rules! foo {
3330     () => {
3331         fn bar<'t, T: Clone + 't>(s: &mut S<'t, T>, t: u32) -> *mut u32 where
3332             't: 't + 't,
3333             for<'a> T: Clone + 'a
3334         { 0 as _ }
3335     };
3336 }
3337
3338 foo!();
3339
3340 fn main() {
3341     bar$0;
3342 }
3343 "#,
3344         expect![[r#"
3345                 *bar*
3346
3347                 ```rust
3348                 test
3349                 ```
3350
3351                 ```rust
3352                 fn bar<'t, T>(s: &mut S<'t, T>, t: u32) -> *mut u32
3353                 where
3354                     T: Clone + 't,
3355                     't: 't + 't,
3356                     for<'a> T: Clone + 'a,
3357                 ```
3358             "#]],
3359     )
3360 }
3361
3362 #[test]
3363 fn hover_intra_doc_links() {
3364     check(
3365         r#"
3366
3367 pub mod theitem {
3368     /// This is the item. Cool!
3369     pub struct TheItem;
3370 }
3371
3372 /// Gives you a [`TheItem$0`].
3373 ///
3374 /// [`TheItem`]: theitem::TheItem
3375 pub fn gimme() -> theitem::TheItem {
3376     theitem::TheItem
3377 }
3378 "#,
3379         expect![[r#"
3380                 *[`TheItem`]*
3381
3382                 ```rust
3383                 test::theitem
3384                 ```
3385
3386                 ```rust
3387                 pub struct TheItem
3388                 ```
3389
3390                 ---
3391
3392                 This is the item. Cool!
3393             "#]],
3394     );
3395 }
3396
3397 #[test]
3398 fn hover_generic_assoc() {
3399     check(
3400         r#"
3401 fn foo<T: A>() where T::Assoc$0: {}
3402
3403 trait A {
3404     type Assoc;
3405 }"#,
3406         expect![[r#"
3407                 *Assoc*
3408
3409                 ```rust
3410                 test
3411                 ```
3412
3413                 ```rust
3414                 type Assoc
3415                 ```
3416             "#]],
3417     );
3418     check(
3419         r#"
3420 fn foo<T: A>() {
3421     let _: <T>::Assoc$0;
3422 }
3423
3424 trait A {
3425     type Assoc;
3426 }"#,
3427         expect![[r#"
3428                 *Assoc*
3429
3430                 ```rust
3431                 test
3432                 ```
3433
3434                 ```rust
3435                 type Assoc
3436                 ```
3437             "#]],
3438     );
3439     check(
3440         r#"
3441 trait A where
3442     Self::Assoc$0: ,
3443 {
3444     type Assoc;
3445 }"#,
3446         expect![[r#"
3447                 *Assoc*
3448
3449                 ```rust
3450                 test
3451                 ```
3452
3453                 ```rust
3454                 type Assoc
3455                 ```
3456             "#]],
3457     );
3458 }
3459
3460 #[test]
3461 fn string_shadowed_with_inner_items() {
3462     check(
3463         r#"
3464 //- /main.rs crate:main deps:alloc
3465
3466 /// Custom `String` type.
3467 struct String;
3468
3469 fn f() {
3470     let _: String$0;
3471
3472     fn inner() {}
3473 }
3474
3475 //- /alloc.rs crate:alloc
3476 #[prelude_import]
3477 pub use string::*;
3478
3479 mod string {
3480     /// This is `alloc::String`.
3481     pub struct String;
3482 }
3483 "#,
3484         expect![[r#"
3485                 *String*
3486
3487                 ```rust
3488                 main
3489                 ```
3490
3491                 ```rust
3492                 struct String
3493                 ```
3494
3495                 ---
3496
3497                 Custom `String` type.
3498             "#]],
3499     )
3500 }
3501
3502 #[test]
3503 fn function_doesnt_shadow_crate_in_use_tree() {
3504     check(
3505         r#"
3506 //- /main.rs crate:main deps:foo
3507 use foo$0::{foo};
3508
3509 //- /foo.rs crate:foo
3510 pub fn foo() {}
3511 "#,
3512         expect![[r#"
3513                 *foo*
3514
3515                 ```rust
3516                 extern crate foo
3517                 ```
3518             "#]],
3519     )
3520 }
3521
3522 #[test]
3523 fn hover_feature() {
3524     check(
3525         r#"#![feature(box_syntax$0)]"#,
3526         expect![[r##"
3527                 *box_syntax*
3528                 ```
3529                 box_syntax
3530                 ```
3531                 ___
3532
3533                 # `box_syntax`
3534
3535                 The tracking issue for this feature is: [#49733]
3536
3537                 [#49733]: https://github.com/rust-lang/rust/issues/49733
3538
3539                 See also [`box_patterns`](box-patterns.md)
3540
3541                 ------------------------
3542
3543                 Currently the only stable way to create a `Box` is via the `Box::new` method.
3544                 Also it is not possible in stable Rust to destructure a `Box` in a match
3545                 pattern. The unstable `box` keyword can be used to create a `Box`. An example
3546                 usage would be:
3547
3548                 ```rust
3549                 #![feature(box_syntax)]
3550
3551                 fn main() {
3552                     let b = box 5;
3553                 }
3554                 ```
3555
3556             "##]],
3557     )
3558 }
3559
3560 #[test]
3561 fn hover_lint() {
3562     check(
3563         r#"#![allow(arithmetic_overflow$0)]"#,
3564         expect![[r#"
3565                 *arithmetic_overflow*
3566                 ```
3567                 arithmetic_overflow
3568                 ```
3569                 ___
3570
3571                 arithmetic operation overflows
3572             "#]],
3573     )
3574 }
3575
3576 #[test]
3577 fn hover_clippy_lint() {
3578     check(
3579         r#"#![allow(clippy::almost_swapped$0)]"#,
3580         expect![[r#"
3581                 *almost_swapped*
3582                 ```
3583                 clippy::almost_swapped
3584                 ```
3585                 ___
3586
3587                 Checks for `foo = bar; bar = foo` sequences.
3588             "#]],
3589     )
3590 }
3591
3592 #[test]
3593 fn hover_attr_path_qualifier() {
3594     cov_mark::check!(name_ref_classify_attr_path_qualifier);
3595     check(
3596         r#"
3597 //- /foo.rs crate:foo
3598
3599 //- /lib.rs crate:main.rs deps:foo
3600 #[fo$0o::bar()]
3601 struct Foo;
3602 "#,
3603         expect![[r#"
3604                 *foo*
3605
3606                 ```rust
3607                 extern crate foo
3608                 ```
3609             "#]],
3610     )
3611 }
3612
3613 #[test]
3614 fn hover_rename() {
3615     check(
3616         r#"
3617 use self as foo$0;
3618 "#,
3619         expect![[r#"
3620                 *foo*
3621
3622                 ```rust
3623                 extern crate test
3624                 ```
3625             "#]],
3626     );
3627     check(
3628         r#"
3629 mod bar {}
3630 use bar::{self as foo$0};
3631 "#,
3632         expect![[r#"
3633                 *foo*
3634
3635                 ```rust
3636                 test
3637                 ```
3638
3639                 ```rust
3640                 mod bar
3641                 ```
3642             "#]],
3643     );
3644     check(
3645         r#"
3646 mod bar {
3647     use super as foo$0;
3648 }
3649 "#,
3650         expect![[r#"
3651                 *foo*
3652
3653                 ```rust
3654                 extern crate test
3655                 ```
3656             "#]],
3657     );
3658     check(
3659         r#"
3660 use crate as foo$0;
3661 "#,
3662         expect![[r#"
3663                 *foo*
3664
3665                 ```rust
3666                 extern crate test
3667                 ```
3668             "#]],
3669     );
3670 }
3671
3672 #[test]
3673 fn hover_attribute_in_macro() {
3674     check(
3675         r#"
3676 //- minicore:derive
3677 macro_rules! identity {
3678     ($struct:item) => {
3679         $struct
3680     };
3681 }
3682 #[rustc_builtin_macro]
3683 pub macro Copy {}
3684 identity!{
3685     #[derive(Copy$0)]
3686     struct Foo;
3687 }
3688 "#,
3689         expect![[r#"
3690                 *Copy*
3691
3692                 ```rust
3693                 test
3694                 ```
3695
3696                 ```rust
3697                 pub macro Copy
3698                 ```
3699             "#]],
3700     );
3701 }
3702
3703 #[test]
3704 fn hover_derive_input() {
3705     check(
3706         r#"
3707 //- minicore:derive
3708 #[rustc_builtin_macro]
3709 pub macro Copy {}
3710 #[derive(Copy$0)]
3711 struct Foo;
3712 "#,
3713         expect![[r#"
3714                 *Copy*
3715
3716                 ```rust
3717                 test
3718                 ```
3719
3720                 ```rust
3721                 pub macro Copy
3722                 ```
3723             "#]],
3724     );
3725     check(
3726         r#"
3727 //- minicore:derive
3728 mod foo {
3729     #[rustc_builtin_macro]
3730     pub macro Copy {}
3731 }
3732 #[derive(foo::Copy$0)]
3733 struct Foo;
3734 "#,
3735         expect![[r#"
3736                 *Copy*
3737
3738                 ```rust
3739                 test
3740                 ```
3741
3742                 ```rust
3743                 pub macro Copy
3744                 ```
3745             "#]],
3746     );
3747 }
3748
3749 #[test]
3750 fn hover_range_math() {
3751     check_hover_range(
3752         r#"
3753 fn f() { let expr = $01 + 2 * 3$0 }
3754 "#,
3755         expect![[r#"
3756             ```rust
3757             i32
3758             ```"#]],
3759     );
3760
3761     check_hover_range(
3762         r#"
3763 fn f() { let expr = 1 $0+ 2 * $03 }
3764 "#,
3765         expect![[r#"
3766             ```rust
3767             i32
3768             ```"#]],
3769     );
3770
3771     check_hover_range(
3772         r#"
3773 fn f() { let expr = 1 + $02 * 3$0 }
3774 "#,
3775         expect![[r#"
3776             ```rust
3777             i32
3778             ```"#]],
3779     );
3780 }
3781
3782 #[test]
3783 fn hover_range_arrays() {
3784     check_hover_range(
3785         r#"
3786 fn f() { let expr = $0[1, 2, 3, 4]$0 }
3787 "#,
3788         expect![[r#"
3789             ```rust
3790             [i32; 4]
3791             ```"#]],
3792     );
3793
3794     check_hover_range(
3795         r#"
3796 fn f() { let expr = [1, 2, $03, 4]$0 }
3797 "#,
3798         expect![[r#"
3799             ```rust
3800             [i32; 4]
3801             ```"#]],
3802     );
3803
3804     check_hover_range(
3805         r#"
3806 fn f() { let expr = [1, 2, $03$0, 4] }
3807 "#,
3808         expect![[r#"
3809             ```rust
3810             i32
3811             ```"#]],
3812     );
3813 }
3814
3815 #[test]
3816 fn hover_range_functions() {
3817     check_hover_range(
3818         r#"
3819 fn f<T>(a: &[T]) { }
3820 fn b() { $0f$0(&[1, 2, 3, 4, 5]); }
3821 "#,
3822         expect![[r#"
3823             ```rust
3824             fn f<i32>(&[i32])
3825             ```"#]],
3826     );
3827
3828     check_hover_range(
3829         r#"
3830 fn f<T>(a: &[T]) { }
3831 fn b() { f($0&[1, 2, 3, 4, 5]$0); }
3832 "#,
3833         expect![[r#"
3834             ```rust
3835             &[i32; 5]
3836             ```"#]],
3837     );
3838 }
3839
3840 #[test]
3841 fn hover_range_shows_nothing_when_invalid() {
3842     check_hover_range_no_results(
3843         r#"
3844 fn f<T>(a: &[T]) { }
3845 fn b()$0 { f(&[1, 2, 3, 4, 5]); }$0
3846 "#,
3847     );
3848
3849     check_hover_range_no_results(
3850         r#"
3851 fn f<T>$0(a: &[T]) { }
3852 fn b() { f(&[1, 2, 3,$0 4, 5]); }
3853 "#,
3854     );
3855
3856     check_hover_range_no_results(
3857         r#"
3858 fn $0f() { let expr = [1, 2, 3, 4]$0 }
3859 "#,
3860     );
3861 }
3862
3863 #[test]
3864 fn hover_range_shows_unit_for_statements() {
3865     check_hover_range(
3866         r#"
3867 fn f<T>(a: &[T]) { }
3868 fn b() { $0f(&[1, 2, 3, 4, 5]); }$0
3869 "#,
3870         expect![[r#"
3871             ```rust
3872             ()
3873             ```"#]],
3874     );
3875
3876     check_hover_range(
3877         r#"
3878 fn f() { let expr$0 = $0[1, 2, 3, 4] }
3879 "#,
3880         expect![[r#"
3881             ```rust
3882             ()
3883             ```"#]],
3884     );
3885 }
3886
3887 #[test]
3888 fn hover_range_for_pat() {
3889     check_hover_range(
3890         r#"
3891 fn foo() {
3892     let $0x$0 = 0;
3893 }
3894 "#,
3895         expect![[r#"
3896                 ```rust
3897                 i32
3898                 ```"#]],
3899     );
3900
3901     check_hover_range(
3902         r#"
3903 fn foo() {
3904     let $0x$0 = "";
3905 }
3906 "#,
3907         expect![[r#"
3908                 ```rust
3909                 &str
3910                 ```"#]],
3911     );
3912 }
3913
3914 #[test]
3915 fn hover_range_shows_coercions_if_applicable_expr() {
3916     check_hover_range(
3917         r#"
3918 fn foo() {
3919     let x: &u32 = $0&&&&&0$0;
3920 }
3921 "#,
3922         expect![[r#"
3923                 ```text
3924                 Type:       &&&&&u32
3925                 Coerced to:     &u32
3926                 ```
3927             "#]],
3928     );
3929     check_hover_range(
3930         r#"
3931 fn foo() {
3932     let x: *const u32 = $0&0$0;
3933 }
3934 "#,
3935         expect![[r#"
3936                 ```text
3937                 Type:             &u32
3938                 Coerced to: *const u32
3939                 ```
3940             "#]],
3941     );
3942 }
3943
3944 #[test]
3945 fn hover_range_shows_type_actions() {
3946     check_actions(
3947         r#"
3948 struct Foo;
3949 fn foo() {
3950     let x: &Foo = $0&&&&&Foo$0;
3951 }
3952 "#,
3953         expect![[r#"
3954                 [
3955                     GoToType(
3956                         [
3957                             HoverGotoTypeData {
3958                                 mod_path: "test::Foo",
3959                                 nav: NavigationTarget {
3960                                     file_id: FileId(
3961                                         0,
3962                                     ),
3963                                     full_range: 0..11,
3964                                     focus_range: 7..10,
3965                                     name: "Foo",
3966                                     kind: Struct,
3967                                     description: "struct Foo",
3968                                 },
3969                             },
3970                         ],
3971                     ),
3972                 ]
3973             "#]],
3974     );
3975 }
3976
3977 #[test]
3978 fn hover_try_expr_res() {
3979     check_hover_range(
3980         r#"
3981 //- minicore:result
3982 struct FooError;
3983
3984 fn foo() -> Result<(), FooError> {
3985     Ok($0Result::<(), FooError>::Ok(())?$0)
3986 }
3987 "#,
3988         expect![[r#"
3989                 ```rust
3990                 ()
3991                 ```"#]],
3992     );
3993     check_hover_range(
3994         r#"
3995 //- minicore:result
3996 struct FooError;
3997 struct BarError;
3998
3999 fn foo() -> Result<(), FooError> {
4000     Ok($0Result::<(), BarError>::Ok(())?$0)
4001 }
4002 "#,
4003         expect![[r#"
4004                 ```text
4005                 Try Error Type: BarError
4006                 Propagated as:  FooError
4007                 ```
4008             "#]],
4009     );
4010 }
4011
4012 #[test]
4013 fn hover_try_expr() {
4014     check_hover_range(
4015         r#"
4016 struct NotResult<T, U>(T, U);
4017 struct Short;
4018 struct Looooong;
4019
4020 fn foo() -> NotResult<(), Looooong> {
4021     $0NotResult((), Short)?$0;
4022 }
4023 "#,
4024         expect![[r#"
4025                 ```text
4026                 Try Target Type:    NotResult<(), Short>
4027                 Propagated as:   NotResult<(), Looooong>
4028                 ```
4029             "#]],
4030     );
4031     check_hover_range(
4032         r#"
4033 struct NotResult<T, U>(T, U);
4034 struct Short;
4035 struct Looooong;
4036
4037 fn foo() -> NotResult<(), Short> {
4038     $0NotResult((), Looooong)?$0;
4039 }
4040 "#,
4041         expect![[r#"
4042                 ```text
4043                 Try Target Type: NotResult<(), Looooong>
4044                 Propagated as:      NotResult<(), Short>
4045                 ```
4046             "#]],
4047     );
4048 }
4049
4050 #[test]
4051 fn hover_try_expr_option() {
4052     cov_mark::check!(hover_try_expr_opt_opt);
4053     check_hover_range(
4054         r#"
4055 //- minicore: option, try
4056
4057 fn foo() -> Option<()> {
4058     $0Some(0)?$0;
4059     None
4060 }
4061 "#,
4062         expect![[r#"
4063                 ```rust
4064                 <Option<i32> as Try>::Output
4065                 ```"#]],
4066     );
4067 }
4068
4069 #[test]
4070 fn hover_deref_expr() {
4071     check_hover_range(
4072         r#"
4073 //- minicore: deref
4074 use core::ops::Deref;
4075
4076 struct DerefExample<T> {
4077     value: T
4078 }
4079
4080 impl<T> Deref for DerefExample<T> {
4081     type Target = T;
4082
4083     fn deref(&self) -> &Self::Target {
4084         &self.value
4085     }
4086 }
4087
4088 fn foo() {
4089     let x = DerefExample { value: 0 };
4090     let y: i32 = $0*x$0;
4091 }
4092 "#,
4093         expect![[r#"
4094                 ```text
4095                 Dereferenced from: DerefExample<i32>
4096                 To type:                         i32
4097                 ```
4098             "#]],
4099     );
4100 }
4101
4102 #[test]
4103 fn hover_deref_expr_with_coercion() {
4104     check_hover_range(
4105         r#"
4106 //- minicore: deref
4107 use core::ops::Deref;
4108
4109 struct DerefExample<T> {
4110     value: T
4111 }
4112
4113 impl<T> Deref for DerefExample<T> {
4114     type Target = T;
4115
4116     fn deref(&self) -> &Self::Target {
4117         &self.value
4118     }
4119 }
4120
4121 fn foo() {
4122     let x = DerefExample { value: &&&&&0 };
4123     let y: &i32 = $0*x$0;
4124 }
4125 "#,
4126         expect![[r#"
4127                 ```text
4128                 Dereferenced from: DerefExample<&&&&&i32>
4129                 To type:                         &&&&&i32
4130                 Coerced to:                          &i32
4131                 ```
4132             "#]],
4133     );
4134 }
4135
4136 #[test]
4137 fn hover_intra_in_macro() {
4138     check(
4139         r#"
4140 macro_rules! foo_macro {
4141     ($(#[$attr:meta])* $name:ident) => {
4142         $(#[$attr])*
4143         pub struct $name;
4144     }
4145 }
4146
4147 foo_macro!(
4148     /// Doc comment for [`Foo$0`]
4149     Foo
4150 );
4151 "#,
4152         expect![[r#"
4153             *[`Foo`]*
4154
4155             ```rust
4156             test
4157             ```
4158
4159             ```rust
4160             pub struct Foo
4161             ```
4162
4163             ---
4164
4165             Doc comment for [`Foo`](https://doc.rust-lang.org/nightly/test/struct.Foo.html)
4166         "#]],
4167     );
4168 }
4169
4170 #[test]
4171 fn hover_intra_in_attr() {
4172     check(
4173         r#"
4174 #[doc = "Doc comment for [`Foo$0`]"]
4175 pub struct Foo;
4176 "#,
4177         expect![[r#"
4178             *[`Foo`]*
4179
4180             ```rust
4181             test
4182             ```
4183
4184             ```rust
4185             pub struct Foo
4186             ```
4187
4188             ---
4189
4190             Doc comment for [`Foo`](https://doc.rust-lang.org/nightly/test/struct.Foo.html)
4191         "#]],
4192     );
4193 }