]> git.lizzy.rs Git - rust.git/blob - crates/ide/src/hover/tests.rs
Merge #10803
[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                 GoToType(
1754                     [],
1755                 ),
1756             ]
1757         "#]],
1758     );
1759 }
1760
1761 #[test]
1762 fn test_hover_test_mod_has_action() {
1763     check_actions(
1764         r#"
1765 mod tests$0 {
1766     #[test]
1767     fn foo_test() {}
1768 }
1769 "#,
1770         expect![[r#"
1771                 [
1772                     Runnable(
1773                         Runnable {
1774                             use_name_in_title: false,
1775                             nav: NavigationTarget {
1776                                 file_id: FileId(
1777                                     0,
1778                                 ),
1779                                 full_range: 0..46,
1780                                 focus_range: 4..9,
1781                                 name: "tests",
1782                                 kind: Module,
1783                                 description: "mod tests",
1784                             },
1785                             kind: TestMod {
1786                                 path: "tests",
1787                             },
1788                             cfg: None,
1789                         },
1790                     ),
1791                 ]
1792             "#]],
1793     );
1794 }
1795
1796 #[test]
1797 fn test_hover_struct_has_goto_type_action() {
1798     check_actions(
1799         r#"
1800 struct S{ f1: u32 }
1801
1802 fn main() { let s$0t = S{ f1:0 }; }
1803 "#,
1804         expect![[r#"
1805                 [
1806                     GoToType(
1807                         [
1808                             HoverGotoTypeData {
1809                                 mod_path: "test::S",
1810                                 nav: NavigationTarget {
1811                                     file_id: FileId(
1812                                         0,
1813                                     ),
1814                                     full_range: 0..19,
1815                                     focus_range: 7..8,
1816                                     name: "S",
1817                                     kind: Struct,
1818                                     description: "struct S",
1819                                 },
1820                             },
1821                         ],
1822                     ),
1823                 ]
1824             "#]],
1825     );
1826 }
1827
1828 #[test]
1829 fn test_hover_generic_struct_has_goto_type_actions() {
1830     check_actions(
1831         r#"
1832 struct Arg(u32);
1833 struct S<T>{ f1: T }
1834
1835 fn main() { let s$0t = S{ f1:Arg(0) }; }
1836 "#,
1837         expect![[r#"
1838                 [
1839                     GoToType(
1840                         [
1841                             HoverGotoTypeData {
1842                                 mod_path: "test::S",
1843                                 nav: NavigationTarget {
1844                                     file_id: FileId(
1845                                         0,
1846                                     ),
1847                                     full_range: 17..37,
1848                                     focus_range: 24..25,
1849                                     name: "S",
1850                                     kind: Struct,
1851                                     description: "struct S<T>",
1852                                 },
1853                             },
1854                             HoverGotoTypeData {
1855                                 mod_path: "test::Arg",
1856                                 nav: NavigationTarget {
1857                                     file_id: FileId(
1858                                         0,
1859                                     ),
1860                                     full_range: 0..16,
1861                                     focus_range: 7..10,
1862                                     name: "Arg",
1863                                     kind: Struct,
1864                                     description: "struct Arg",
1865                                 },
1866                             },
1867                         ],
1868                     ),
1869                 ]
1870             "#]],
1871     );
1872 }
1873
1874 #[test]
1875 fn test_hover_generic_struct_has_flattened_goto_type_actions() {
1876     check_actions(
1877         r#"
1878 struct Arg(u32);
1879 struct S<T>{ f1: T }
1880
1881 fn main() { let s$0t = S{ f1: S{ f1: Arg(0) } }; }
1882 "#,
1883         expect![[r#"
1884                 [
1885                     GoToType(
1886                         [
1887                             HoverGotoTypeData {
1888                                 mod_path: "test::S",
1889                                 nav: NavigationTarget {
1890                                     file_id: FileId(
1891                                         0,
1892                                     ),
1893                                     full_range: 17..37,
1894                                     focus_range: 24..25,
1895                                     name: "S",
1896                                     kind: Struct,
1897                                     description: "struct S<T>",
1898                                 },
1899                             },
1900                             HoverGotoTypeData {
1901                                 mod_path: "test::Arg",
1902                                 nav: NavigationTarget {
1903                                     file_id: FileId(
1904                                         0,
1905                                     ),
1906                                     full_range: 0..16,
1907                                     focus_range: 7..10,
1908                                     name: "Arg",
1909                                     kind: Struct,
1910                                     description: "struct Arg",
1911                                 },
1912                             },
1913                         ],
1914                     ),
1915                 ]
1916             "#]],
1917     );
1918 }
1919
1920 #[test]
1921 fn test_hover_tuple_has_goto_type_actions() {
1922     check_actions(
1923         r#"
1924 struct A(u32);
1925 struct B(u32);
1926 mod M {
1927     pub struct C(u32);
1928 }
1929
1930 fn main() { let s$0t = (A(1), B(2), M::C(3) ); }
1931 "#,
1932         expect![[r#"
1933                 [
1934                     GoToType(
1935                         [
1936                             HoverGotoTypeData {
1937                                 mod_path: "test::A",
1938                                 nav: NavigationTarget {
1939                                     file_id: FileId(
1940                                         0,
1941                                     ),
1942                                     full_range: 0..14,
1943                                     focus_range: 7..8,
1944                                     name: "A",
1945                                     kind: Struct,
1946                                     description: "struct A",
1947                                 },
1948                             },
1949                             HoverGotoTypeData {
1950                                 mod_path: "test::B",
1951                                 nav: NavigationTarget {
1952                                     file_id: FileId(
1953                                         0,
1954                                     ),
1955                                     full_range: 15..29,
1956                                     focus_range: 22..23,
1957                                     name: "B",
1958                                     kind: Struct,
1959                                     description: "struct B",
1960                                 },
1961                             },
1962                             HoverGotoTypeData {
1963                                 mod_path: "test::M::C",
1964                                 nav: NavigationTarget {
1965                                     file_id: FileId(
1966                                         0,
1967                                     ),
1968                                     full_range: 42..60,
1969                                     focus_range: 53..54,
1970                                     name: "C",
1971                                     kind: Struct,
1972                                     description: "pub struct C",
1973                                 },
1974                             },
1975                         ],
1976                     ),
1977                 ]
1978             "#]],
1979     );
1980 }
1981
1982 #[test]
1983 fn test_hover_return_impl_trait_has_goto_type_action() {
1984     check_actions(
1985         r#"
1986 trait Foo {}
1987 fn foo() -> impl Foo {}
1988
1989 fn main() { let s$0t = foo(); }
1990 "#,
1991         expect![[r#"
1992                 [
1993                     GoToType(
1994                         [
1995                             HoverGotoTypeData {
1996                                 mod_path: "test::Foo",
1997                                 nav: NavigationTarget {
1998                                     file_id: FileId(
1999                                         0,
2000                                     ),
2001                                     full_range: 0..12,
2002                                     focus_range: 6..9,
2003                                     name: "Foo",
2004                                     kind: Trait,
2005                                     description: "trait Foo",
2006                                 },
2007                             },
2008                         ],
2009                     ),
2010                 ]
2011             "#]],
2012     );
2013 }
2014
2015 #[test]
2016 fn test_hover_generic_return_impl_trait_has_goto_type_action() {
2017     check_actions(
2018         r#"
2019 trait Foo<T> {}
2020 struct S;
2021 fn foo() -> impl Foo<S> {}
2022
2023 fn main() { let s$0t = foo(); }
2024 "#,
2025         expect![[r#"
2026                 [
2027                     GoToType(
2028                         [
2029                             HoverGotoTypeData {
2030                                 mod_path: "test::Foo",
2031                                 nav: NavigationTarget {
2032                                     file_id: FileId(
2033                                         0,
2034                                     ),
2035                                     full_range: 0..15,
2036                                     focus_range: 6..9,
2037                                     name: "Foo",
2038                                     kind: Trait,
2039                                     description: "trait Foo<T>",
2040                                 },
2041                             },
2042                             HoverGotoTypeData {
2043                                 mod_path: "test::S",
2044                                 nav: NavigationTarget {
2045                                     file_id: FileId(
2046                                         0,
2047                                     ),
2048                                     full_range: 16..25,
2049                                     focus_range: 23..24,
2050                                     name: "S",
2051                                     kind: Struct,
2052                                     description: "struct S",
2053                                 },
2054                             },
2055                         ],
2056                     ),
2057                 ]
2058             "#]],
2059     );
2060 }
2061
2062 #[test]
2063 fn test_hover_return_impl_traits_has_goto_type_action() {
2064     check_actions(
2065         r#"
2066 trait Foo {}
2067 trait Bar {}
2068 fn foo() -> impl Foo + Bar {}
2069
2070 fn main() { let s$0t = foo(); }
2071 "#,
2072         expect![[r#"
2073                 [
2074                     GoToType(
2075                         [
2076                             HoverGotoTypeData {
2077                                 mod_path: "test::Foo",
2078                                 nav: NavigationTarget {
2079                                     file_id: FileId(
2080                                         0,
2081                                     ),
2082                                     full_range: 0..12,
2083                                     focus_range: 6..9,
2084                                     name: "Foo",
2085                                     kind: Trait,
2086                                     description: "trait Foo",
2087                                 },
2088                             },
2089                             HoverGotoTypeData {
2090                                 mod_path: "test::Bar",
2091                                 nav: NavigationTarget {
2092                                     file_id: FileId(
2093                                         0,
2094                                     ),
2095                                     full_range: 13..25,
2096                                     focus_range: 19..22,
2097                                     name: "Bar",
2098                                     kind: Trait,
2099                                     description: "trait Bar",
2100                                 },
2101                             },
2102                         ],
2103                     ),
2104                 ]
2105             "#]],
2106     );
2107 }
2108
2109 #[test]
2110 fn test_hover_generic_return_impl_traits_has_goto_type_action() {
2111     check_actions(
2112         r#"
2113 trait Foo<T> {}
2114 trait Bar<T> {}
2115 struct S1 {}
2116 struct S2 {}
2117
2118 fn foo() -> impl Foo<S1> + Bar<S2> {}
2119
2120 fn main() { let s$0t = foo(); }
2121 "#,
2122         expect![[r#"
2123                 [
2124                     GoToType(
2125                         [
2126                             HoverGotoTypeData {
2127                                 mod_path: "test::Foo",
2128                                 nav: NavigationTarget {
2129                                     file_id: FileId(
2130                                         0,
2131                                     ),
2132                                     full_range: 0..15,
2133                                     focus_range: 6..9,
2134                                     name: "Foo",
2135                                     kind: Trait,
2136                                     description: "trait Foo<T>",
2137                                 },
2138                             },
2139                             HoverGotoTypeData {
2140                                 mod_path: "test::Bar",
2141                                 nav: NavigationTarget {
2142                                     file_id: FileId(
2143                                         0,
2144                                     ),
2145                                     full_range: 16..31,
2146                                     focus_range: 22..25,
2147                                     name: "Bar",
2148                                     kind: Trait,
2149                                     description: "trait Bar<T>",
2150                                 },
2151                             },
2152                             HoverGotoTypeData {
2153                                 mod_path: "test::S1",
2154                                 nav: NavigationTarget {
2155                                     file_id: FileId(
2156                                         0,
2157                                     ),
2158                                     full_range: 32..44,
2159                                     focus_range: 39..41,
2160                                     name: "S1",
2161                                     kind: Struct,
2162                                     description: "struct S1",
2163                                 },
2164                             },
2165                             HoverGotoTypeData {
2166                                 mod_path: "test::S2",
2167                                 nav: NavigationTarget {
2168                                     file_id: FileId(
2169                                         0,
2170                                     ),
2171                                     full_range: 45..57,
2172                                     focus_range: 52..54,
2173                                     name: "S2",
2174                                     kind: Struct,
2175                                     description: "struct S2",
2176                                 },
2177                             },
2178                         ],
2179                     ),
2180                 ]
2181             "#]],
2182     );
2183 }
2184
2185 #[test]
2186 fn test_hover_arg_impl_trait_has_goto_type_action() {
2187     check_actions(
2188         r#"
2189 trait Foo {}
2190 fn foo(ar$0g: &impl Foo) {}
2191 "#,
2192         expect![[r#"
2193                 [
2194                     GoToType(
2195                         [
2196                             HoverGotoTypeData {
2197                                 mod_path: "test::Foo",
2198                                 nav: NavigationTarget {
2199                                     file_id: FileId(
2200                                         0,
2201                                     ),
2202                                     full_range: 0..12,
2203                                     focus_range: 6..9,
2204                                     name: "Foo",
2205                                     kind: Trait,
2206                                     description: "trait Foo",
2207                                 },
2208                             },
2209                         ],
2210                     ),
2211                 ]
2212             "#]],
2213     );
2214 }
2215
2216 #[test]
2217 fn test_hover_arg_impl_traits_has_goto_type_action() {
2218     check_actions(
2219         r#"
2220 trait Foo {}
2221 trait Bar<T> {}
2222 struct S{}
2223
2224 fn foo(ar$0g: &impl Foo + Bar<S>) {}
2225 "#,
2226         expect![[r#"
2227                 [
2228                     GoToType(
2229                         [
2230                             HoverGotoTypeData {
2231                                 mod_path: "test::Foo",
2232                                 nav: NavigationTarget {
2233                                     file_id: FileId(
2234                                         0,
2235                                     ),
2236                                     full_range: 0..12,
2237                                     focus_range: 6..9,
2238                                     name: "Foo",
2239                                     kind: Trait,
2240                                     description: "trait Foo",
2241                                 },
2242                             },
2243                             HoverGotoTypeData {
2244                                 mod_path: "test::Bar",
2245                                 nav: NavigationTarget {
2246                                     file_id: FileId(
2247                                         0,
2248                                     ),
2249                                     full_range: 13..28,
2250                                     focus_range: 19..22,
2251                                     name: "Bar",
2252                                     kind: Trait,
2253                                     description: "trait Bar<T>",
2254                                 },
2255                             },
2256                             HoverGotoTypeData {
2257                                 mod_path: "test::S",
2258                                 nav: NavigationTarget {
2259                                     file_id: FileId(
2260                                         0,
2261                                     ),
2262                                     full_range: 29..39,
2263                                     focus_range: 36..37,
2264                                     name: "S",
2265                                     kind: Struct,
2266                                     description: "struct S",
2267                                 },
2268                             },
2269                         ],
2270                     ),
2271                 ]
2272             "#]],
2273     );
2274 }
2275
2276 #[test]
2277 fn test_hover_async_block_impl_trait_has_goto_type_action() {
2278     check_actions(
2279         r#"
2280 //- minicore: future
2281 struct S;
2282 fn foo() {
2283     let fo$0o = async { S };
2284 }
2285 "#,
2286         expect![[r#"
2287                 [
2288                     GoToType(
2289                         [
2290                             HoverGotoTypeData {
2291                                 mod_path: "core::future::Future",
2292                                 nav: NavigationTarget {
2293                                     file_id: FileId(
2294                                         1,
2295                                     ),
2296                                     full_range: 276..458,
2297                                     focus_range: 315..321,
2298                                     name: "Future",
2299                                     kind: Trait,
2300                                     description: "pub trait Future",
2301                                 },
2302                             },
2303                             HoverGotoTypeData {
2304                                 mod_path: "test::S",
2305                                 nav: NavigationTarget {
2306                                     file_id: FileId(
2307                                         0,
2308                                     ),
2309                                     full_range: 0..9,
2310                                     focus_range: 7..8,
2311                                     name: "S",
2312                                     kind: Struct,
2313                                     description: "struct S",
2314                                 },
2315                             },
2316                         ],
2317                     ),
2318                 ]
2319             "#]],
2320     );
2321 }
2322
2323 #[test]
2324 fn test_hover_arg_generic_impl_trait_has_goto_type_action() {
2325     check_actions(
2326         r#"
2327 trait Foo<T> {}
2328 struct S {}
2329 fn foo(ar$0g: &impl Foo<S>) {}
2330 "#,
2331         expect![[r#"
2332                 [
2333                     GoToType(
2334                         [
2335                             HoverGotoTypeData {
2336                                 mod_path: "test::Foo",
2337                                 nav: NavigationTarget {
2338                                     file_id: FileId(
2339                                         0,
2340                                     ),
2341                                     full_range: 0..15,
2342                                     focus_range: 6..9,
2343                                     name: "Foo",
2344                                     kind: Trait,
2345                                     description: "trait Foo<T>",
2346                                 },
2347                             },
2348                             HoverGotoTypeData {
2349                                 mod_path: "test::S",
2350                                 nav: NavigationTarget {
2351                                     file_id: FileId(
2352                                         0,
2353                                     ),
2354                                     full_range: 16..27,
2355                                     focus_range: 23..24,
2356                                     name: "S",
2357                                     kind: Struct,
2358                                     description: "struct S",
2359                                 },
2360                             },
2361                         ],
2362                     ),
2363                 ]
2364             "#]],
2365     );
2366 }
2367
2368 #[test]
2369 fn test_hover_dyn_return_has_goto_type_action() {
2370     check_actions(
2371         r#"
2372 trait Foo {}
2373 struct S;
2374 impl Foo for S {}
2375
2376 struct B<T>{}
2377 fn foo() -> B<dyn Foo> {}
2378
2379 fn main() { let s$0t = foo(); }
2380 "#,
2381         expect![[r#"
2382                 [
2383                     GoToType(
2384                         [
2385                             HoverGotoTypeData {
2386                                 mod_path: "test::B",
2387                                 nav: NavigationTarget {
2388                                     file_id: FileId(
2389                                         0,
2390                                     ),
2391                                     full_range: 42..55,
2392                                     focus_range: 49..50,
2393                                     name: "B",
2394                                     kind: Struct,
2395                                     description: "struct B<T>",
2396                                 },
2397                             },
2398                             HoverGotoTypeData {
2399                                 mod_path: "test::Foo",
2400                                 nav: NavigationTarget {
2401                                     file_id: FileId(
2402                                         0,
2403                                     ),
2404                                     full_range: 0..12,
2405                                     focus_range: 6..9,
2406                                     name: "Foo",
2407                                     kind: Trait,
2408                                     description: "trait Foo",
2409                                 },
2410                             },
2411                         ],
2412                     ),
2413                 ]
2414             "#]],
2415     );
2416 }
2417
2418 #[test]
2419 fn test_hover_dyn_arg_has_goto_type_action() {
2420     check_actions(
2421         r#"
2422 trait Foo {}
2423 fn foo(ar$0g: &dyn Foo) {}
2424 "#,
2425         expect![[r#"
2426                 [
2427                     GoToType(
2428                         [
2429                             HoverGotoTypeData {
2430                                 mod_path: "test::Foo",
2431                                 nav: NavigationTarget {
2432                                     file_id: FileId(
2433                                         0,
2434                                     ),
2435                                     full_range: 0..12,
2436                                     focus_range: 6..9,
2437                                     name: "Foo",
2438                                     kind: Trait,
2439                                     description: "trait Foo",
2440                                 },
2441                             },
2442                         ],
2443                     ),
2444                 ]
2445             "#]],
2446     );
2447 }
2448
2449 #[test]
2450 fn test_hover_generic_dyn_arg_has_goto_type_action() {
2451     check_actions(
2452         r#"
2453 trait Foo<T> {}
2454 struct S {}
2455 fn foo(ar$0g: &dyn Foo<S>) {}
2456 "#,
2457         expect![[r#"
2458                 [
2459                     GoToType(
2460                         [
2461                             HoverGotoTypeData {
2462                                 mod_path: "test::Foo",
2463                                 nav: NavigationTarget {
2464                                     file_id: FileId(
2465                                         0,
2466                                     ),
2467                                     full_range: 0..15,
2468                                     focus_range: 6..9,
2469                                     name: "Foo",
2470                                     kind: Trait,
2471                                     description: "trait Foo<T>",
2472                                 },
2473                             },
2474                             HoverGotoTypeData {
2475                                 mod_path: "test::S",
2476                                 nav: NavigationTarget {
2477                                     file_id: FileId(
2478                                         0,
2479                                     ),
2480                                     full_range: 16..27,
2481                                     focus_range: 23..24,
2482                                     name: "S",
2483                                     kind: Struct,
2484                                     description: "struct S",
2485                                 },
2486                             },
2487                         ],
2488                     ),
2489                 ]
2490             "#]],
2491     );
2492 }
2493
2494 #[test]
2495 fn test_hover_goto_type_action_links_order() {
2496     check_actions(
2497         r#"
2498 trait ImplTrait<T> {}
2499 trait DynTrait<T> {}
2500 struct B<T> {}
2501 struct S {}
2502
2503 fn foo(a$0rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
2504 "#,
2505         expect![[r#"
2506                 [
2507                     GoToType(
2508                         [
2509                             HoverGotoTypeData {
2510                                 mod_path: "test::ImplTrait",
2511                                 nav: NavigationTarget {
2512                                     file_id: FileId(
2513                                         0,
2514                                     ),
2515                                     full_range: 0..21,
2516                                     focus_range: 6..15,
2517                                     name: "ImplTrait",
2518                                     kind: Trait,
2519                                     description: "trait ImplTrait<T>",
2520                                 },
2521                             },
2522                             HoverGotoTypeData {
2523                                 mod_path: "test::B",
2524                                 nav: NavigationTarget {
2525                                     file_id: FileId(
2526                                         0,
2527                                     ),
2528                                     full_range: 43..57,
2529                                     focus_range: 50..51,
2530                                     name: "B",
2531                                     kind: Struct,
2532                                     description: "struct B<T>",
2533                                 },
2534                             },
2535                             HoverGotoTypeData {
2536                                 mod_path: "test::DynTrait",
2537                                 nav: NavigationTarget {
2538                                     file_id: FileId(
2539                                         0,
2540                                     ),
2541                                     full_range: 22..42,
2542                                     focus_range: 28..36,
2543                                     name: "DynTrait",
2544                                     kind: Trait,
2545                                     description: "trait DynTrait<T>",
2546                                 },
2547                             },
2548                             HoverGotoTypeData {
2549                                 mod_path: "test::S",
2550                                 nav: NavigationTarget {
2551                                     file_id: FileId(
2552                                         0,
2553                                     ),
2554                                     full_range: 58..69,
2555                                     focus_range: 65..66,
2556                                     name: "S",
2557                                     kind: Struct,
2558                                     description: "struct S",
2559                                 },
2560                             },
2561                         ],
2562                     ),
2563                 ]
2564             "#]],
2565     );
2566 }
2567
2568 #[test]
2569 fn test_hover_associated_type_has_goto_type_action() {
2570     check_actions(
2571         r#"
2572 trait Foo {
2573     type Item;
2574     fn get(self) -> Self::Item {}
2575 }
2576
2577 struct Bar{}
2578 struct S{}
2579
2580 impl Foo for S { type Item = Bar; }
2581
2582 fn test() -> impl Foo { S {} }
2583
2584 fn main() { let s$0t = test().get(); }
2585 "#,
2586         expect![[r#"
2587                 [
2588                     GoToType(
2589                         [
2590                             HoverGotoTypeData {
2591                                 mod_path: "test::Foo",
2592                                 nav: NavigationTarget {
2593                                     file_id: FileId(
2594                                         0,
2595                                     ),
2596                                     full_range: 0..62,
2597                                     focus_range: 6..9,
2598                                     name: "Foo",
2599                                     kind: Trait,
2600                                     description: "trait Foo",
2601                                 },
2602                             },
2603                         ],
2604                     ),
2605                 ]
2606             "#]],
2607     );
2608 }
2609
2610 #[test]
2611 fn test_hover_const_param_has_goto_type_action() {
2612     check_actions(
2613         r#"
2614 struct Bar;
2615 struct Foo<const BAR: Bar>;
2616
2617 impl<const BAR: Bar> Foo<BAR$0> {}
2618 "#,
2619         expect![[r#"
2620                 [
2621                     GoToType(
2622                         [
2623                             HoverGotoTypeData {
2624                                 mod_path: "test::Bar",
2625                                 nav: NavigationTarget {
2626                                     file_id: FileId(
2627                                         0,
2628                                     ),
2629                                     full_range: 0..11,
2630                                     focus_range: 7..10,
2631                                     name: "Bar",
2632                                     kind: Struct,
2633                                     description: "struct Bar",
2634                                 },
2635                             },
2636                         ],
2637                     ),
2638                 ]
2639             "#]],
2640     );
2641 }
2642
2643 #[test]
2644 fn test_hover_type_param_has_goto_type_action() {
2645     check_actions(
2646         r#"
2647 trait Foo {}
2648
2649 fn foo<T: Foo>(t: T$0){}
2650 "#,
2651         expect![[r#"
2652                 [
2653                     GoToType(
2654                         [
2655                             HoverGotoTypeData {
2656                                 mod_path: "test::Foo",
2657                                 nav: NavigationTarget {
2658                                     file_id: FileId(
2659                                         0,
2660                                     ),
2661                                     full_range: 0..12,
2662                                     focus_range: 6..9,
2663                                     name: "Foo",
2664                                     kind: Trait,
2665                                     description: "trait Foo",
2666                                 },
2667                             },
2668                         ],
2669                     ),
2670                 ]
2671             "#]],
2672     );
2673 }
2674
2675 #[test]
2676 fn test_hover_self_has_go_to_type() {
2677     check_actions(
2678         r#"
2679 struct Foo;
2680 impl Foo {
2681     fn foo(&self$0) {}
2682 }
2683 "#,
2684         expect![[r#"
2685                 [
2686                     GoToType(
2687                         [
2688                             HoverGotoTypeData {
2689                                 mod_path: "test::Foo",
2690                                 nav: NavigationTarget {
2691                                     file_id: FileId(
2692                                         0,
2693                                     ),
2694                                     full_range: 0..11,
2695                                     focus_range: 7..10,
2696                                     name: "Foo",
2697                                     kind: Struct,
2698                                     description: "struct Foo",
2699                                 },
2700                             },
2701                         ],
2702                     ),
2703                 ]
2704             "#]],
2705     );
2706 }
2707
2708 #[test]
2709 fn hover_displays_normalized_crate_names() {
2710     check(
2711         r#"
2712 //- /lib.rs crate:name-with-dashes
2713 pub mod wrapper {
2714     pub struct Thing { x: u32 }
2715
2716     impl Thing {
2717         pub fn new() -> Thing { Thing { x: 0 } }
2718     }
2719 }
2720
2721 //- /main.rs crate:main deps:name-with-dashes
2722 fn main() { let foo_test = name_with_dashes::wrapper::Thing::new$0(); }
2723 "#,
2724         expect![[r#"
2725             *new*
2726
2727             ```rust
2728             name_with_dashes::wrapper::Thing
2729             ```
2730
2731             ```rust
2732             pub fn new() -> Thing
2733             ```
2734             "#]],
2735     )
2736 }
2737
2738 #[test]
2739 fn hover_field_pat_shorthand_ref_match_ergonomics() {
2740     check(
2741         r#"
2742 struct S {
2743     f: i32,
2744 }
2745
2746 fn main() {
2747     let s = S { f: 0 };
2748     let S { f$0 } = &s;
2749 }
2750 "#,
2751         expect![[r#"
2752                 *f*
2753
2754                 ```rust
2755                 f: &i32
2756                 ```
2757                 ---
2758
2759                 ```rust
2760                 test::S
2761                 ```
2762
2763                 ```rust
2764                 f: i32
2765                 ```
2766             "#]],
2767     );
2768 }
2769
2770 #[test]
2771 fn hover_self_param_shows_type() {
2772     check(
2773         r#"
2774 struct Foo {}
2775 impl Foo {
2776     fn bar(&sel$0f) {}
2777 }
2778 "#,
2779         expect![[r#"
2780                 *self*
2781
2782                 ```rust
2783                 self: &Foo
2784                 ```
2785             "#]],
2786     );
2787 }
2788
2789 #[test]
2790 fn hover_self_param_shows_type_for_arbitrary_self_type() {
2791     check(
2792         r#"
2793 struct Arc<T>(T);
2794 struct Foo {}
2795 impl Foo {
2796     fn bar(sel$0f: Arc<Foo>) {}
2797 }
2798 "#,
2799         expect![[r#"
2800                 *self*
2801
2802                 ```rust
2803                 self: Arc<Foo>
2804                 ```
2805             "#]],
2806     );
2807 }
2808
2809 #[test]
2810 fn hover_doc_outer_inner() {
2811     check(
2812         r#"
2813 /// Be quick;
2814 mod Foo$0 {
2815     //! time is mana
2816
2817     /// This comment belongs to the function
2818     fn foo() {}
2819 }
2820 "#,
2821         expect![[r#"
2822                 *Foo*
2823
2824                 ```rust
2825                 test
2826                 ```
2827
2828                 ```rust
2829                 mod Foo
2830                 ```
2831
2832                 ---
2833
2834                 Be quick;
2835                 time is mana
2836             "#]],
2837     );
2838 }
2839
2840 #[test]
2841 fn hover_doc_outer_inner_attribue() {
2842     check(
2843         r#"
2844 #[doc = "Be quick;"]
2845 mod Foo$0 {
2846     #![doc = "time is mana"]
2847
2848     #[doc = "This comment belongs to the function"]
2849     fn foo() {}
2850 }
2851 "#,
2852         expect![[r#"
2853                 *Foo*
2854
2855                 ```rust
2856                 test
2857                 ```
2858
2859                 ```rust
2860                 mod Foo
2861                 ```
2862
2863                 ---
2864
2865                 Be quick;
2866                 time is mana
2867             "#]],
2868     );
2869 }
2870
2871 #[test]
2872 fn hover_doc_block_style_indentend() {
2873     check(
2874         r#"
2875 /**
2876     foo
2877     ```rust
2878     let x = 3;
2879     ```
2880 */
2881 fn foo$0() {}
2882 "#,
2883         expect![[r#"
2884                 *foo*
2885
2886                 ```rust
2887                 test
2888                 ```
2889
2890                 ```rust
2891                 fn foo()
2892                 ```
2893
2894                 ---
2895
2896                 foo
2897
2898                 ```rust
2899                 let x = 3;
2900                 ```
2901             "#]],
2902     );
2903 }
2904
2905 #[test]
2906 fn hover_comments_dont_highlight_parent() {
2907     cov_mark::check!(no_highlight_on_comment_hover);
2908     check_hover_no_result(
2909         r#"
2910 fn no_hover() {
2911     // no$0hover
2912 }
2913 "#,
2914     );
2915 }
2916
2917 #[test]
2918 fn hover_label() {
2919     check(
2920         r#"
2921 fn foo() {
2922     'label$0: loop {}
2923 }
2924 "#,
2925         expect![[r#"
2926             *'label*
2927
2928             ```rust
2929             'label
2930             ```
2931             "#]],
2932     );
2933 }
2934
2935 #[test]
2936 fn hover_lifetime() {
2937     check(
2938         r#"fn foo<'lifetime>(_: &'lifetime$0 ()) {}"#,
2939         expect![[r#"
2940             *'lifetime*
2941
2942             ```rust
2943             'lifetime
2944             ```
2945             "#]],
2946     );
2947 }
2948
2949 #[test]
2950 fn hover_type_param() {
2951     check(
2952         r#"
2953 //- minicore: sized
2954 struct Foo<T>(T);
2955 trait TraitA {}
2956 trait TraitB {}
2957 impl<T: TraitA + TraitB> Foo<T$0> where T: Sized {}
2958 "#,
2959         expect![[r#"
2960                 *T*
2961
2962                 ```rust
2963                 T: TraitA + TraitB
2964                 ```
2965             "#]],
2966     );
2967     check(
2968         r#"
2969 //- minicore: sized
2970 struct Foo<T>(T);
2971 impl<T> Foo<T$0> {}
2972 "#,
2973         expect![[r#"
2974                 *T*
2975
2976                 ```rust
2977                 T
2978                 ```
2979                 "#]],
2980     );
2981     // lifetimes bounds arent being tracked yet
2982     check(
2983         r#"
2984 //- minicore: sized
2985 struct Foo<T>(T);
2986 impl<T: 'static> Foo<T$0> {}
2987 "#,
2988         expect![[r#"
2989                 *T*
2990
2991                 ```rust
2992                 T
2993                 ```
2994                 "#]],
2995     );
2996 }
2997
2998 #[test]
2999 fn hover_type_param_sized_bounds() {
3000     // implicit `: Sized` bound
3001     check(
3002         r#"
3003 //- minicore: sized
3004 trait Trait {}
3005 struct Foo<T>(T);
3006 impl<T: Trait> Foo<T$0> {}
3007 "#,
3008         expect![[r#"
3009                 *T*
3010
3011                 ```rust
3012                 T: Trait
3013                 ```
3014             "#]],
3015     );
3016     check(
3017         r#"
3018 //- minicore: sized
3019 trait Trait {}
3020 struct Foo<T>(T);
3021 impl<T: Trait + ?Sized> Foo<T$0> {}
3022 "#,
3023         expect![[r#"
3024                 *T*
3025
3026                 ```rust
3027                 T: Trait + ?Sized
3028                 ```
3029             "#]],
3030     );
3031 }
3032
3033 mod type_param_sized_bounds {
3034     use super::*;
3035
3036     #[test]
3037     fn single_implicit() {
3038         check(
3039             r#"
3040 //- minicore: sized
3041 fn foo<T$0>() {}
3042 "#,
3043             expect![[r#"
3044                     *T*
3045
3046                     ```rust
3047                     T
3048                     ```
3049                 "#]],
3050         );
3051     }
3052
3053     #[test]
3054     fn single_explicit() {
3055         check(
3056             r#"
3057 //- minicore: sized
3058 fn foo<T$0: Sized>() {}
3059 "#,
3060             expect![[r#"
3061                     *T*
3062
3063                     ```rust
3064                     T
3065                     ```
3066                 "#]],
3067         );
3068     }
3069
3070     #[test]
3071     fn single_relaxed() {
3072         check(
3073             r#"
3074 //- minicore: sized
3075 fn foo<T$0: ?Sized>() {}
3076 "#,
3077             expect![[r#"
3078                     *T*
3079
3080                     ```rust
3081                     T: ?Sized
3082                     ```
3083                 "#]],
3084         );
3085     }
3086
3087     #[test]
3088     fn multiple_implicit() {
3089         check(
3090             r#"
3091 //- minicore: sized
3092 trait Trait {}
3093 fn foo<T$0: Trait>() {}
3094 "#,
3095             expect![[r#"
3096                     *T*
3097
3098                     ```rust
3099                     T: Trait
3100                     ```
3101                 "#]],
3102         );
3103     }
3104
3105     #[test]
3106     fn multiple_explicit() {
3107         check(
3108             r#"
3109 //- minicore: sized
3110 trait Trait {}
3111 fn foo<T$0: Trait + Sized>() {}
3112 "#,
3113             expect![[r#"
3114                     *T*
3115
3116                     ```rust
3117                     T: Trait
3118                     ```
3119                 "#]],
3120         );
3121     }
3122
3123     #[test]
3124     fn multiple_relaxed() {
3125         check(
3126             r#"
3127 //- minicore: sized
3128 trait Trait {}
3129 fn foo<T$0: Trait + ?Sized>() {}
3130 "#,
3131             expect![[r#"
3132                     *T*
3133
3134                     ```rust
3135                     T: Trait + ?Sized
3136                     ```
3137                 "#]],
3138         );
3139     }
3140
3141     #[test]
3142     fn mixed() {
3143         check(
3144             r#"
3145 //- minicore: sized
3146 fn foo<T$0: ?Sized + Sized + Sized>() {}
3147 "#,
3148             expect![[r#"
3149                     *T*
3150
3151                     ```rust
3152                     T
3153                     ```
3154                 "#]],
3155         );
3156         check(
3157             r#"
3158 //- minicore: sized
3159 trait Trait {}
3160 fn foo<T$0: Sized + ?Sized + Sized + Trait>() {}
3161 "#,
3162             expect![[r#"
3163                     *T*
3164
3165                     ```rust
3166                     T: Trait
3167                     ```
3168                 "#]],
3169         );
3170     }
3171 }
3172
3173 #[test]
3174 fn hover_const_param() {
3175     check(
3176         r#"
3177 struct Foo<const LEN: usize>;
3178 impl<const LEN: usize> Foo<LEN$0> {}
3179 "#,
3180         expect![[r#"
3181                 *LEN*
3182
3183                 ```rust
3184                 const LEN: usize
3185                 ```
3186             "#]],
3187     );
3188 }
3189
3190 #[test]
3191 fn hover_const_pat() {
3192     check(
3193         r#"
3194 /// This is a doc
3195 const FOO: usize = 3;
3196 fn foo() {
3197     match 5 {
3198         FOO$0 => (),
3199         _ => ()
3200     }
3201 }
3202 "#,
3203         expect![[r#"
3204             *FOO*
3205
3206             ```rust
3207             test
3208             ```
3209
3210             ```rust
3211             const FOO: usize = 3
3212             ```
3213
3214             ---
3215
3216             This is a doc
3217         "#]],
3218     );
3219 }
3220
3221 #[test]
3222 fn hover_mod_def() {
3223     check(
3224         r#"
3225 //- /main.rs
3226 mod foo$0;
3227 //- /foo.rs
3228 //! For the horde!
3229 "#,
3230         expect![[r#"
3231                 *foo*
3232
3233                 ```rust
3234                 test
3235                 ```
3236
3237                 ```rust
3238                 mod foo
3239                 ```
3240
3241                 ---
3242
3243                 For the horde!
3244             "#]],
3245     );
3246 }
3247
3248 #[test]
3249 fn hover_self_in_use() {
3250     check(
3251         r#"
3252 //! This should not appear
3253 mod foo {
3254     /// But this should appear
3255     pub mod bar {}
3256 }
3257 use foo::bar::{self$0};
3258 "#,
3259         expect![[r#"
3260                 *self*
3261
3262                 ```rust
3263                 test::foo
3264                 ```
3265
3266                 ```rust
3267                 mod bar
3268                 ```
3269
3270                 ---
3271
3272                 But this should appear
3273             "#]],
3274     )
3275 }
3276
3277 #[test]
3278 fn hover_keyword() {
3279     check(
3280         r#"
3281 //- /main.rs crate:main deps:std
3282 fn f() { retur$0n; }
3283 //- /libstd.rs crate:std
3284 /// Docs for return_keyword
3285 mod return_keyword {}
3286 "#,
3287         expect![[r#"
3288                 *return*
3289
3290                 ```rust
3291                 return
3292                 ```
3293
3294                 ---
3295
3296                 Docs for return_keyword
3297             "#]],
3298     );
3299 }
3300
3301 #[test]
3302 fn hover_builtin() {
3303     check(
3304         r#"
3305 //- /main.rs crate:main deps:std
3306 cosnt _: &str$0 = ""; }
3307
3308 //- /libstd.rs crate:std
3309 /// Docs for prim_str
3310 mod prim_str {}
3311 "#,
3312         expect![[r#"
3313                 *str*
3314
3315                 ```rust
3316                 str
3317                 ```
3318
3319                 ---
3320
3321                 Docs for prim_str
3322             "#]],
3323     );
3324 }
3325
3326 #[test]
3327 fn hover_macro_expanded_function() {
3328     check(
3329         r#"
3330 struct S<'a, T>(&'a T);
3331 trait Clone {}
3332 macro_rules! foo {
3333     () => {
3334         fn bar<'t, T: Clone + 't>(s: &mut S<'t, T>, t: u32) -> *mut u32 where
3335             't: 't + 't,
3336             for<'a> T: Clone + 'a
3337         { 0 as _ }
3338     };
3339 }
3340
3341 foo!();
3342
3343 fn main() {
3344     bar$0;
3345 }
3346 "#,
3347         expect![[r#"
3348                 *bar*
3349
3350                 ```rust
3351                 test
3352                 ```
3353
3354                 ```rust
3355                 fn bar<'t, T>(s: &mut S<'t, T>, t: u32) -> *mut u32
3356                 where
3357                     T: Clone + 't,
3358                     't: 't + 't,
3359                     for<'a> T: Clone + 'a,
3360                 ```
3361             "#]],
3362     )
3363 }
3364
3365 #[test]
3366 fn hover_intra_doc_links() {
3367     check(
3368         r#"
3369
3370 pub mod theitem {
3371     /// This is the item. Cool!
3372     pub struct TheItem;
3373 }
3374
3375 /// Gives you a [`TheItem$0`].
3376 ///
3377 /// [`TheItem`]: theitem::TheItem
3378 pub fn gimme() -> theitem::TheItem {
3379     theitem::TheItem
3380 }
3381 "#,
3382         expect![[r#"
3383                 *[`TheItem`]*
3384
3385                 ```rust
3386                 test::theitem
3387                 ```
3388
3389                 ```rust
3390                 pub struct TheItem
3391                 ```
3392
3393                 ---
3394
3395                 This is the item. Cool!
3396             "#]],
3397     );
3398 }
3399
3400 #[test]
3401 fn hover_generic_assoc() {
3402     check(
3403         r#"
3404 fn foo<T: A>() where T::Assoc$0: {}
3405
3406 trait A {
3407     type Assoc;
3408 }"#,
3409         expect![[r#"
3410                 *Assoc*
3411
3412                 ```rust
3413                 test
3414                 ```
3415
3416                 ```rust
3417                 type Assoc
3418                 ```
3419             "#]],
3420     );
3421     check(
3422         r#"
3423 fn foo<T: A>() {
3424     let _: <T>::Assoc$0;
3425 }
3426
3427 trait A {
3428     type Assoc;
3429 }"#,
3430         expect![[r#"
3431                 *Assoc*
3432
3433                 ```rust
3434                 test
3435                 ```
3436
3437                 ```rust
3438                 type Assoc
3439                 ```
3440             "#]],
3441     );
3442     check(
3443         r#"
3444 trait A where
3445     Self::Assoc$0: ,
3446 {
3447     type Assoc;
3448 }"#,
3449         expect![[r#"
3450                 *Assoc*
3451
3452                 ```rust
3453                 test
3454                 ```
3455
3456                 ```rust
3457                 type Assoc
3458                 ```
3459             "#]],
3460     );
3461 }
3462
3463 #[test]
3464 fn string_shadowed_with_inner_items() {
3465     check(
3466         r#"
3467 //- /main.rs crate:main deps:alloc
3468
3469 /// Custom `String` type.
3470 struct String;
3471
3472 fn f() {
3473     let _: String$0;
3474
3475     fn inner() {}
3476 }
3477
3478 //- /alloc.rs crate:alloc
3479 #[prelude_import]
3480 pub use string::*;
3481
3482 mod string {
3483     /// This is `alloc::String`.
3484     pub struct String;
3485 }
3486 "#,
3487         expect![[r#"
3488                 *String*
3489
3490                 ```rust
3491                 main
3492                 ```
3493
3494                 ```rust
3495                 struct String
3496                 ```
3497
3498                 ---
3499
3500                 Custom `String` type.
3501             "#]],
3502     )
3503 }
3504
3505 #[test]
3506 fn function_doesnt_shadow_crate_in_use_tree() {
3507     check(
3508         r#"
3509 //- /main.rs crate:main deps:foo
3510 use foo$0::{foo};
3511
3512 //- /foo.rs crate:foo
3513 pub fn foo() {}
3514 "#,
3515         expect![[r#"
3516                 *foo*
3517
3518                 ```rust
3519                 extern crate foo
3520                 ```
3521             "#]],
3522     )
3523 }
3524
3525 #[test]
3526 fn hover_feature() {
3527     check(
3528         r#"#![feature(box_syntax$0)]"#,
3529         expect![[r##"
3530                 *box_syntax*
3531                 ```
3532                 box_syntax
3533                 ```
3534                 ___
3535
3536                 # `box_syntax`
3537
3538                 The tracking issue for this feature is: [#49733]
3539
3540                 [#49733]: https://github.com/rust-lang/rust/issues/49733
3541
3542                 See also [`box_patterns`](box-patterns.md)
3543
3544                 ------------------------
3545
3546                 Currently the only stable way to create a `Box` is via the `Box::new` method.
3547                 Also it is not possible in stable Rust to destructure a `Box` in a match
3548                 pattern. The unstable `box` keyword can be used to create a `Box`. An example
3549                 usage would be:
3550
3551                 ```rust
3552                 #![feature(box_syntax)]
3553
3554                 fn main() {
3555                     let b = box 5;
3556                 }
3557                 ```
3558
3559             "##]],
3560     )
3561 }
3562
3563 #[test]
3564 fn hover_lint() {
3565     check(
3566         r#"#![allow(arithmetic_overflow$0)]"#,
3567         expect![[r#"
3568                 *arithmetic_overflow*
3569                 ```
3570                 arithmetic_overflow
3571                 ```
3572                 ___
3573
3574                 arithmetic operation overflows
3575             "#]],
3576     )
3577 }
3578
3579 #[test]
3580 fn hover_clippy_lint() {
3581     check(
3582         r#"#![allow(clippy::almost_swapped$0)]"#,
3583         expect![[r#"
3584                 *almost_swapped*
3585                 ```
3586                 clippy::almost_swapped
3587                 ```
3588                 ___
3589
3590                 Checks for `foo = bar; bar = foo` sequences.
3591             "#]],
3592     )
3593 }
3594
3595 #[test]
3596 fn hover_attr_path_qualifier() {
3597     cov_mark::check!(name_ref_classify_attr_path_qualifier);
3598     check(
3599         r#"
3600 //- /foo.rs crate:foo
3601
3602 //- /lib.rs crate:main.rs deps:foo
3603 #[fo$0o::bar()]
3604 struct Foo;
3605 "#,
3606         expect![[r#"
3607                 *foo*
3608
3609                 ```rust
3610                 extern crate foo
3611                 ```
3612             "#]],
3613     )
3614 }
3615
3616 #[test]
3617 fn hover_rename() {
3618     check(
3619         r#"
3620 use self as foo$0;
3621 "#,
3622         expect![[r#"
3623                 *foo*
3624
3625                 ```rust
3626                 extern crate test
3627                 ```
3628             "#]],
3629     );
3630     check(
3631         r#"
3632 mod bar {}
3633 use bar::{self as foo$0};
3634 "#,
3635         expect![[r#"
3636                 *foo*
3637
3638                 ```rust
3639                 test
3640                 ```
3641
3642                 ```rust
3643                 mod bar
3644                 ```
3645             "#]],
3646     );
3647     check(
3648         r#"
3649 mod bar {
3650     use super as foo$0;
3651 }
3652 "#,
3653         expect![[r#"
3654                 *foo*
3655
3656                 ```rust
3657                 extern crate test
3658                 ```
3659             "#]],
3660     );
3661     check(
3662         r#"
3663 use crate as foo$0;
3664 "#,
3665         expect![[r#"
3666                 *foo*
3667
3668                 ```rust
3669                 extern crate test
3670                 ```
3671             "#]],
3672     );
3673 }
3674
3675 #[test]
3676 fn hover_attribute_in_macro() {
3677     check(
3678         r#"
3679 //- minicore:derive
3680 macro_rules! identity {
3681     ($struct:item) => {
3682         $struct
3683     };
3684 }
3685 #[rustc_builtin_macro]
3686 pub macro Copy {}
3687 identity!{
3688     #[derive(Copy$0)]
3689     struct Foo;
3690 }
3691 "#,
3692         expect![[r#"
3693                 *Copy*
3694
3695                 ```rust
3696                 test
3697                 ```
3698
3699                 ```rust
3700                 pub macro Copy
3701                 ```
3702             "#]],
3703     );
3704 }
3705
3706 #[test]
3707 fn hover_derive_input() {
3708     check(
3709         r#"
3710 //- minicore:derive
3711 #[rustc_builtin_macro]
3712 pub macro Copy {}
3713 #[derive(Copy$0)]
3714 struct Foo;
3715 "#,
3716         expect![[r#"
3717                 *Copy*
3718
3719                 ```rust
3720                 test
3721                 ```
3722
3723                 ```rust
3724                 pub macro Copy
3725                 ```
3726             "#]],
3727     );
3728     check(
3729         r#"
3730 //- minicore:derive
3731 mod foo {
3732     #[rustc_builtin_macro]
3733     pub macro Copy {}
3734 }
3735 #[derive(foo::Copy$0)]
3736 struct Foo;
3737 "#,
3738         expect![[r#"
3739                 *Copy*
3740
3741                 ```rust
3742                 test
3743                 ```
3744
3745                 ```rust
3746                 pub macro Copy
3747                 ```
3748             "#]],
3749     );
3750 }
3751
3752 #[test]
3753 fn hover_range_math() {
3754     check_hover_range(
3755         r#"
3756 fn f() { let expr = $01 + 2 * 3$0 }
3757 "#,
3758         expect![[r#"
3759             ```rust
3760             i32
3761             ```"#]],
3762     );
3763
3764     check_hover_range(
3765         r#"
3766 fn f() { let expr = 1 $0+ 2 * $03 }
3767 "#,
3768         expect![[r#"
3769             ```rust
3770             i32
3771             ```"#]],
3772     );
3773
3774     check_hover_range(
3775         r#"
3776 fn f() { let expr = 1 + $02 * 3$0 }
3777 "#,
3778         expect![[r#"
3779             ```rust
3780             i32
3781             ```"#]],
3782     );
3783 }
3784
3785 #[test]
3786 fn hover_range_arrays() {
3787     check_hover_range(
3788         r#"
3789 fn f() { let expr = $0[1, 2, 3, 4]$0 }
3790 "#,
3791         expect![[r#"
3792             ```rust
3793             [i32; 4]
3794             ```"#]],
3795     );
3796
3797     check_hover_range(
3798         r#"
3799 fn f() { let expr = [1, 2, $03, 4]$0 }
3800 "#,
3801         expect![[r#"
3802             ```rust
3803             [i32; 4]
3804             ```"#]],
3805     );
3806
3807     check_hover_range(
3808         r#"
3809 fn f() { let expr = [1, 2, $03$0, 4] }
3810 "#,
3811         expect![[r#"
3812             ```rust
3813             i32
3814             ```"#]],
3815     );
3816 }
3817
3818 #[test]
3819 fn hover_range_functions() {
3820     check_hover_range(
3821         r#"
3822 fn f<T>(a: &[T]) { }
3823 fn b() { $0f$0(&[1, 2, 3, 4, 5]); }
3824 "#,
3825         expect![[r#"
3826             ```rust
3827             fn f<i32>(&[i32])
3828             ```"#]],
3829     );
3830
3831     check_hover_range(
3832         r#"
3833 fn f<T>(a: &[T]) { }
3834 fn b() { f($0&[1, 2, 3, 4, 5]$0); }
3835 "#,
3836         expect![[r#"
3837             ```rust
3838             &[i32; 5]
3839             ```"#]],
3840     );
3841 }
3842
3843 #[test]
3844 fn hover_range_shows_nothing_when_invalid() {
3845     check_hover_range_no_results(
3846         r#"
3847 fn f<T>(a: &[T]) { }
3848 fn b()$0 { f(&[1, 2, 3, 4, 5]); }$0
3849 "#,
3850     );
3851
3852     check_hover_range_no_results(
3853         r#"
3854 fn f<T>$0(a: &[T]) { }
3855 fn b() { f(&[1, 2, 3,$0 4, 5]); }
3856 "#,
3857     );
3858
3859     check_hover_range_no_results(
3860         r#"
3861 fn $0f() { let expr = [1, 2, 3, 4]$0 }
3862 "#,
3863     );
3864 }
3865
3866 #[test]
3867 fn hover_range_shows_unit_for_statements() {
3868     check_hover_range(
3869         r#"
3870 fn f<T>(a: &[T]) { }
3871 fn b() { $0f(&[1, 2, 3, 4, 5]); }$0
3872 "#,
3873         expect![[r#"
3874             ```rust
3875             ()
3876             ```"#]],
3877     );
3878
3879     check_hover_range(
3880         r#"
3881 fn f() { let expr$0 = $0[1, 2, 3, 4] }
3882 "#,
3883         expect![[r#"
3884             ```rust
3885             ()
3886             ```"#]],
3887     );
3888 }
3889
3890 #[test]
3891 fn hover_range_for_pat() {
3892     check_hover_range(
3893         r#"
3894 fn foo() {
3895     let $0x$0 = 0;
3896 }
3897 "#,
3898         expect![[r#"
3899                 ```rust
3900                 i32
3901                 ```"#]],
3902     );
3903
3904     check_hover_range(
3905         r#"
3906 fn foo() {
3907     let $0x$0 = "";
3908 }
3909 "#,
3910         expect![[r#"
3911                 ```rust
3912                 &str
3913                 ```"#]],
3914     );
3915 }
3916
3917 #[test]
3918 fn hover_range_shows_coercions_if_applicable_expr() {
3919     check_hover_range(
3920         r#"
3921 fn foo() {
3922     let x: &u32 = $0&&&&&0$0;
3923 }
3924 "#,
3925         expect![[r#"
3926                 ```text
3927                 Type:       &&&&&u32
3928                 Coerced to:     &u32
3929                 ```
3930             "#]],
3931     );
3932     check_hover_range(
3933         r#"
3934 fn foo() {
3935     let x: *const u32 = $0&0$0;
3936 }
3937 "#,
3938         expect![[r#"
3939                 ```text
3940                 Type:             &u32
3941                 Coerced to: *const u32
3942                 ```
3943             "#]],
3944     );
3945 }
3946
3947 #[test]
3948 fn hover_range_shows_type_actions() {
3949     check_actions(
3950         r#"
3951 struct Foo;
3952 fn foo() {
3953     let x: &Foo = $0&&&&&Foo$0;
3954 }
3955 "#,
3956         expect![[r#"
3957                 [
3958                     GoToType(
3959                         [
3960                             HoverGotoTypeData {
3961                                 mod_path: "test::Foo",
3962                                 nav: NavigationTarget {
3963                                     file_id: FileId(
3964                                         0,
3965                                     ),
3966                                     full_range: 0..11,
3967                                     focus_range: 7..10,
3968                                     name: "Foo",
3969                                     kind: Struct,
3970                                     description: "struct Foo",
3971                                 },
3972                             },
3973                         ],
3974                     ),
3975                 ]
3976             "#]],
3977     );
3978 }
3979
3980 #[test]
3981 fn hover_try_expr_res() {
3982     check_hover_range(
3983         r#"
3984 //- minicore:result
3985 struct FooError;
3986
3987 fn foo() -> Result<(), FooError> {
3988     Ok($0Result::<(), FooError>::Ok(())?$0)
3989 }
3990 "#,
3991         expect![[r#"
3992                 ```rust
3993                 ()
3994                 ```"#]],
3995     );
3996     check_hover_range(
3997         r#"
3998 //- minicore:result
3999 struct FooError;
4000 struct BarError;
4001
4002 fn foo() -> Result<(), FooError> {
4003     Ok($0Result::<(), BarError>::Ok(())?$0)
4004 }
4005 "#,
4006         expect![[r#"
4007                 ```text
4008                 Try Error Type: BarError
4009                 Propagated as:  FooError
4010                 ```
4011             "#]],
4012     );
4013 }
4014
4015 #[test]
4016 fn hover_try_expr() {
4017     check_hover_range(
4018         r#"
4019 struct NotResult<T, U>(T, U);
4020 struct Short;
4021 struct Looooong;
4022
4023 fn foo() -> NotResult<(), Looooong> {
4024     $0NotResult((), Short)?$0;
4025 }
4026 "#,
4027         expect![[r#"
4028                 ```text
4029                 Try Target Type:    NotResult<(), Short>
4030                 Propagated as:   NotResult<(), Looooong>
4031                 ```
4032             "#]],
4033     );
4034     check_hover_range(
4035         r#"
4036 struct NotResult<T, U>(T, U);
4037 struct Short;
4038 struct Looooong;
4039
4040 fn foo() -> NotResult<(), Short> {
4041     $0NotResult((), Looooong)?$0;
4042 }
4043 "#,
4044         expect![[r#"
4045                 ```text
4046                 Try Target Type: NotResult<(), Looooong>
4047                 Propagated as:      NotResult<(), Short>
4048                 ```
4049             "#]],
4050     );
4051 }
4052
4053 #[test]
4054 fn hover_try_expr_option() {
4055     cov_mark::check!(hover_try_expr_opt_opt);
4056     check_hover_range(
4057         r#"
4058 //- minicore: option, try
4059
4060 fn foo() -> Option<()> {
4061     $0Some(0)?$0;
4062     None
4063 }
4064 "#,
4065         expect![[r#"
4066                 ```rust
4067                 <Option<i32> as Try>::Output
4068                 ```"#]],
4069     );
4070 }
4071
4072 #[test]
4073 fn hover_deref_expr() {
4074     check_hover_range(
4075         r#"
4076 //- minicore: deref
4077 use core::ops::Deref;
4078
4079 struct DerefExample<T> {
4080     value: T
4081 }
4082
4083 impl<T> Deref for DerefExample<T> {
4084     type Target = T;
4085
4086     fn deref(&self) -> &Self::Target {
4087         &self.value
4088     }
4089 }
4090
4091 fn foo() {
4092     let x = DerefExample { value: 0 };
4093     let y: i32 = $0*x$0;
4094 }
4095 "#,
4096         expect![[r#"
4097                 ```text
4098                 Dereferenced from: DerefExample<i32>
4099                 To type:                         i32
4100                 ```
4101             "#]],
4102     );
4103 }
4104
4105 #[test]
4106 fn hover_deref_expr_with_coercion() {
4107     check_hover_range(
4108         r#"
4109 //- minicore: deref
4110 use core::ops::Deref;
4111
4112 struct DerefExample<T> {
4113     value: T
4114 }
4115
4116 impl<T> Deref for DerefExample<T> {
4117     type Target = T;
4118
4119     fn deref(&self) -> &Self::Target {
4120         &self.value
4121     }
4122 }
4123
4124 fn foo() {
4125     let x = DerefExample { value: &&&&&0 };
4126     let y: &i32 = $0*x$0;
4127 }
4128 "#,
4129         expect![[r#"
4130                 ```text
4131                 Dereferenced from: DerefExample<&&&&&i32>
4132                 To type:                         &&&&&i32
4133                 Coerced to:                          &i32
4134                 ```
4135             "#]],
4136     );
4137 }
4138
4139 #[test]
4140 fn hover_intra_in_macro() {
4141     check(
4142         r#"
4143 macro_rules! foo_macro {
4144     ($(#[$attr:meta])* $name:ident) => {
4145         $(#[$attr])*
4146         pub struct $name;
4147     }
4148 }
4149
4150 foo_macro!(
4151     /// Doc comment for [`Foo$0`]
4152     Foo
4153 );
4154 "#,
4155         expect![[r#"
4156             *[`Foo`]*
4157
4158             ```rust
4159             test
4160             ```
4161
4162             ```rust
4163             pub struct Foo
4164             ```
4165
4166             ---
4167
4168             Doc comment for [`Foo`](https://doc.rust-lang.org/nightly/test/struct.Foo.html)
4169         "#]],
4170     );
4171 }
4172
4173 #[test]
4174 fn hover_intra_in_attr() {
4175     check(
4176         r#"
4177 #[doc = "Doc comment for [`Foo$0`]"]
4178 pub struct Foo;
4179 "#,
4180         expect![[r#"
4181             *[`Foo`]*
4182
4183             ```rust
4184             test
4185             ```
4186
4187             ```rust
4188             pub struct Foo
4189             ```
4190
4191             ---
4192
4193             Doc comment for [`Foo`](https://doc.rust-lang.org/nightly/test/struct.Foo.html)
4194         "#]],
4195     );
4196 }