]> git.lizzy.rs Git - rust.git/blob - crates/ide/src/hover/tests.rs
Merge #10805
[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_multiple_actions() {
1140     check_actions(
1141         r#"
1142 struct Bar;
1143 struct Foo { bar: Bar }
1144
1145 fn foo(Foo { b$0ar }: &Foo) {}
1146         "#,
1147         expect![[r#"
1148             [
1149                 GoToType(
1150                     [
1151                         HoverGotoTypeData {
1152                             mod_path: "test::Bar",
1153                             nav: NavigationTarget {
1154                                 file_id: FileId(
1155                                     0,
1156                                 ),
1157                                 full_range: 0..11,
1158                                 focus_range: 7..10,
1159                                 name: "Bar",
1160                                 kind: Struct,
1161                                 description: "struct Bar",
1162                             },
1163                         },
1164                     ],
1165                 ),
1166             ]
1167         "#]],
1168     )
1169 }
1170
1171 #[test]
1172 fn test_hover_through_literal_string_in_builtin_macro() {
1173     check_hover_no_result(
1174         r#"
1175             #[rustc_builtin_macro]
1176             macro_rules! format {}
1177
1178             fn foo() {
1179                 format!("hel$0lo {}", 0);
1180             }
1181 "#,
1182     );
1183 }
1184
1185 #[test]
1186 fn test_hover_non_ascii_space_doc() {
1187     check(
1188         "
1189 /// <- `\u{3000}` here
1190 fn foo() { }
1191
1192 fn bar() { fo$0o(); }
1193 ",
1194         expect![[r#"
1195                 *foo*
1196
1197                 ```rust
1198                 test
1199                 ```
1200
1201                 ```rust
1202                 fn foo()
1203                 ```
1204
1205                 ---
1206
1207                 \<- ` ` here
1208             "#]],
1209     );
1210 }
1211
1212 #[test]
1213 fn test_hover_function_show_qualifiers() {
1214     check(
1215         r#"async fn foo$0() {}"#,
1216         expect![[r#"
1217                 *foo*
1218
1219                 ```rust
1220                 test
1221                 ```
1222
1223                 ```rust
1224                 async fn foo()
1225                 ```
1226             "#]],
1227     );
1228     check(
1229         r#"pub const unsafe fn foo$0() {}"#,
1230         expect![[r#"
1231                 *foo*
1232
1233                 ```rust
1234                 test
1235                 ```
1236
1237                 ```rust
1238                 pub const unsafe fn foo()
1239                 ```
1240             "#]],
1241     );
1242     // Top level `pub(crate)` will be displayed as no visibility.
1243     check(
1244         r#"mod m { pub(crate) async unsafe extern "C" fn foo$0() {} }"#,
1245         expect![[r#"
1246                 *foo*
1247
1248                 ```rust
1249                 test::m
1250                 ```
1251
1252                 ```rust
1253                 pub(crate) async unsafe extern "C" fn foo()
1254                 ```
1255             "#]],
1256     );
1257 }
1258
1259 #[test]
1260 fn test_hover_trait_show_qualifiers() {
1261     check_actions(
1262         r"unsafe trait foo$0() {}",
1263         expect![[r#"
1264                 [
1265                     Implementation(
1266                         FilePosition {
1267                             file_id: FileId(
1268                                 0,
1269                             ),
1270                             offset: 13,
1271                         },
1272                     ),
1273                 ]
1274             "#]],
1275     );
1276 }
1277
1278 #[test]
1279 fn test_hover_extern_crate() {
1280     check(
1281         r#"
1282 //- /main.rs crate:main deps:std
1283 extern crate st$0d;
1284 //- /std/lib.rs crate:std
1285 //! Standard library for this test
1286 //!
1287 //! Printed?
1288 //! abc123
1289 "#,
1290         expect![[r#"
1291                 *std*
1292
1293                 ```rust
1294                 extern crate std
1295                 ```
1296
1297                 ---
1298
1299                 Standard library for this test
1300
1301                 Printed?
1302                 abc123
1303             "#]],
1304     );
1305     check(
1306         r#"
1307 //- /main.rs crate:main deps:std
1308 extern crate std as ab$0c;
1309 //- /std/lib.rs crate:std
1310 //! Standard library for this test
1311 //!
1312 //! Printed?
1313 //! abc123
1314 "#,
1315         expect![[r#"
1316                 *abc*
1317
1318                 ```rust
1319                 extern crate std
1320                 ```
1321
1322                 ---
1323
1324                 Standard library for this test
1325
1326                 Printed?
1327                 abc123
1328             "#]],
1329     );
1330 }
1331
1332 #[test]
1333 fn test_hover_mod_with_same_name_as_function() {
1334     check(
1335         r#"
1336 use self::m$0y::Bar;
1337 mod my { pub struct Bar; }
1338
1339 fn my() {}
1340 "#,
1341         expect![[r#"
1342                 *my*
1343
1344                 ```rust
1345                 test
1346                 ```
1347
1348                 ```rust
1349                 mod my
1350                 ```
1351             "#]],
1352     );
1353 }
1354
1355 #[test]
1356 fn test_hover_struct_doc_comment() {
1357     check(
1358         r#"
1359 /// This is an example
1360 /// multiline doc
1361 ///
1362 /// # Example
1363 ///
1364 /// ```
1365 /// let five = 5;
1366 ///
1367 /// assert_eq!(6, my_crate::add_one(5));
1368 /// ```
1369 struct Bar;
1370
1371 fn foo() { let bar = Ba$0r; }
1372 "#,
1373         expect![[r##"
1374                 *Bar*
1375
1376                 ```rust
1377                 test
1378                 ```
1379
1380                 ```rust
1381                 struct Bar
1382                 ```
1383
1384                 ---
1385
1386                 This is an example
1387                 multiline doc
1388
1389                 # Example
1390
1391                 ```
1392                 let five = 5;
1393
1394                 assert_eq!(6, my_crate::add_one(5));
1395                 ```
1396             "##]],
1397     );
1398 }
1399
1400 #[test]
1401 fn test_hover_struct_doc_attr() {
1402     check(
1403         r#"
1404 #[doc = "bar docs"]
1405 struct Bar;
1406
1407 fn foo() { let bar = Ba$0r; }
1408 "#,
1409         expect![[r#"
1410                 *Bar*
1411
1412                 ```rust
1413                 test
1414                 ```
1415
1416                 ```rust
1417                 struct Bar
1418                 ```
1419
1420                 ---
1421
1422                 bar docs
1423             "#]],
1424     );
1425 }
1426
1427 #[test]
1428 fn test_hover_struct_doc_attr_multiple_and_mixed() {
1429     check(
1430         r#"
1431 /// bar docs 0
1432 #[doc = "bar docs 1"]
1433 #[doc = "bar docs 2"]
1434 struct Bar;
1435
1436 fn foo() { let bar = Ba$0r; }
1437 "#,
1438         expect![[r#"
1439                 *Bar*
1440
1441                 ```rust
1442                 test
1443                 ```
1444
1445                 ```rust
1446                 struct Bar
1447                 ```
1448
1449                 ---
1450
1451                 bar docs 0
1452                 bar docs 1
1453                 bar docs 2
1454             "#]],
1455     );
1456 }
1457
1458 #[test]
1459 fn test_hover_external_url() {
1460     check(
1461         r#"
1462 pub struct Foo;
1463 /// [external](https://www.google.com)
1464 pub struct B$0ar
1465 "#,
1466         expect![[r#"
1467                 *Bar*
1468
1469                 ```rust
1470                 test
1471                 ```
1472
1473                 ```rust
1474                 pub struct Bar
1475                 ```
1476
1477                 ---
1478
1479                 [external](https://www.google.com)
1480             "#]],
1481     );
1482 }
1483
1484 // Check that we don't rewrite links which we can't identify
1485 #[test]
1486 fn test_hover_unknown_target() {
1487     check(
1488         r#"
1489 pub struct Foo;
1490 /// [baz](Baz)
1491 pub struct B$0ar
1492 "#,
1493         expect![[r#"
1494                 *Bar*
1495
1496                 ```rust
1497                 test
1498                 ```
1499
1500                 ```rust
1501                 pub struct Bar
1502                 ```
1503
1504                 ---
1505
1506                 [baz](Baz)
1507             "#]],
1508     );
1509 }
1510
1511 #[test]
1512 fn test_hover_no_links() {
1513     check_hover_no_links(
1514         r#"
1515 /// Test cases:
1516 /// case 1.  bare URL: https://www.example.com/
1517 /// case 2.  inline URL with title: [example](https://www.example.com/)
1518 /// case 3.  code reference: [`Result`]
1519 /// case 4.  code reference but miss footnote: [`String`]
1520 /// case 5.  autolink: <http://www.example.com/>
1521 /// case 6.  email address: <test@example.com>
1522 /// case 7.  reference: [example][example]
1523 /// case 8.  collapsed link: [example][]
1524 /// case 9.  shortcut link: [example]
1525 /// case 10. inline without URL: [example]()
1526 /// case 11. reference: [foo][foo]
1527 /// case 12. reference: [foo][bar]
1528 /// case 13. collapsed link: [foo][]
1529 /// case 14. shortcut link: [foo]
1530 /// case 15. inline without URL: [foo]()
1531 /// case 16. just escaped text: \[foo]
1532 /// case 17. inline link: [Foo](foo::Foo)
1533 ///
1534 /// [`Result`]: ../../std/result/enum.Result.html
1535 /// [^example]: https://www.example.com/
1536 pub fn fo$0o() {}
1537 "#,
1538         expect![[r#"
1539                 *foo*
1540
1541                 ```rust
1542                 test
1543                 ```
1544
1545                 ```rust
1546                 pub fn foo()
1547                 ```
1548
1549                 ---
1550
1551                 Test cases:
1552                 case 1.  bare URL: https://www.example.com/
1553                 case 2.  inline URL with title: [example](https://www.example.com/)
1554                 case 3.  code reference: `Result`
1555                 case 4.  code reference but miss footnote: `String`
1556                 case 5.  autolink: http://www.example.com/
1557                 case 6.  email address: test@example.com
1558                 case 7.  reference: example
1559                 case 8.  collapsed link: example
1560                 case 9.  shortcut link: example
1561                 case 10. inline without URL: example
1562                 case 11. reference: foo
1563                 case 12. reference: foo
1564                 case 13. collapsed link: foo
1565                 case 14. shortcut link: foo
1566                 case 15. inline without URL: foo
1567                 case 16. just escaped text: \[foo\]
1568                 case 17. inline link: Foo
1569
1570                 [^example]: https://www.example.com/
1571             "#]],
1572     );
1573 }
1574
1575 #[test]
1576 fn test_hover_macro_generated_struct_fn_doc_comment() {
1577     cov_mark::check!(hover_macro_generated_struct_fn_doc_comment);
1578
1579     check(
1580         r#"
1581 macro_rules! bar {
1582     () => {
1583         struct Bar;
1584         impl Bar {
1585             /// Do the foo
1586             fn foo(&self) {}
1587         }
1588     }
1589 }
1590
1591 bar!();
1592
1593 fn foo() { let bar = Bar; bar.fo$0o(); }
1594 "#,
1595         expect![[r#"
1596                 *foo*
1597
1598                 ```rust
1599                 test::Bar
1600                 ```
1601
1602                 ```rust
1603                 fn foo(&self)
1604                 ```
1605
1606                 ---
1607
1608                 Do the foo
1609             "#]],
1610     );
1611 }
1612
1613 #[test]
1614 fn test_hover_macro_generated_struct_fn_doc_attr() {
1615     cov_mark::check!(hover_macro_generated_struct_fn_doc_attr);
1616
1617     check(
1618         r#"
1619 macro_rules! bar {
1620     () => {
1621         struct Bar;
1622         impl Bar {
1623             #[doc = "Do the foo"]
1624             fn foo(&self) {}
1625         }
1626     }
1627 }
1628
1629 bar!();
1630
1631 fn foo() { let bar = Bar; bar.fo$0o(); }
1632 "#,
1633         expect![[r#"
1634                 *foo*
1635
1636                 ```rust
1637                 test::Bar
1638                 ```
1639
1640                 ```rust
1641                 fn foo(&self)
1642                 ```
1643
1644                 ---
1645
1646                 Do the foo
1647             "#]],
1648     );
1649 }
1650
1651 #[test]
1652 fn test_hover_trait_has_impl_action() {
1653     check_actions(
1654         r#"trait foo$0() {}"#,
1655         expect![[r#"
1656                 [
1657                     Implementation(
1658                         FilePosition {
1659                             file_id: FileId(
1660                                 0,
1661                             ),
1662                             offset: 6,
1663                         },
1664                     ),
1665                 ]
1666             "#]],
1667     );
1668 }
1669
1670 #[test]
1671 fn test_hover_struct_has_impl_action() {
1672     check_actions(
1673         r"struct foo$0() {}",
1674         expect![[r#"
1675                 [
1676                     Implementation(
1677                         FilePosition {
1678                             file_id: FileId(
1679                                 0,
1680                             ),
1681                             offset: 7,
1682                         },
1683                     ),
1684                 ]
1685             "#]],
1686     );
1687 }
1688
1689 #[test]
1690 fn test_hover_union_has_impl_action() {
1691     check_actions(
1692         r#"union foo$0() {}"#,
1693         expect![[r#"
1694                 [
1695                     Implementation(
1696                         FilePosition {
1697                             file_id: FileId(
1698                                 0,
1699                             ),
1700                             offset: 6,
1701                         },
1702                     ),
1703                 ]
1704             "#]],
1705     );
1706 }
1707
1708 #[test]
1709 fn test_hover_enum_has_impl_action() {
1710     check_actions(
1711         r"enum foo$0() { A, B }",
1712         expect![[r#"
1713                 [
1714                     Implementation(
1715                         FilePosition {
1716                             file_id: FileId(
1717                                 0,
1718                             ),
1719                             offset: 5,
1720                         },
1721                     ),
1722                 ]
1723             "#]],
1724     );
1725 }
1726
1727 #[test]
1728 fn test_hover_self_has_impl_action() {
1729     check_actions(
1730         r#"struct foo where Self$0:;"#,
1731         expect![[r#"
1732                 [
1733                     Implementation(
1734                         FilePosition {
1735                             file_id: FileId(
1736                                 0,
1737                             ),
1738                             offset: 7,
1739                         },
1740                     ),
1741                 ]
1742             "#]],
1743     );
1744 }
1745
1746 #[test]
1747 fn test_hover_test_has_action() {
1748     check_actions(
1749         r#"
1750 #[test]
1751 fn foo_$0test() {}
1752 "#,
1753         expect![[r#"
1754             [
1755                 Reference(
1756                     FilePosition {
1757                         file_id: FileId(
1758                             0,
1759                         ),
1760                         offset: 11,
1761                     },
1762                 ),
1763                 Runnable(
1764                     Runnable {
1765                         use_name_in_title: false,
1766                         nav: NavigationTarget {
1767                             file_id: FileId(
1768                                 0,
1769                             ),
1770                             full_range: 0..24,
1771                             focus_range: 11..19,
1772                             name: "foo_test",
1773                             kind: Function,
1774                         },
1775                         kind: Test {
1776                             test_id: Path(
1777                                 "foo_test",
1778                             ),
1779                             attr: TestAttr {
1780                                 ignore: false,
1781                             },
1782                         },
1783                         cfg: None,
1784                     },
1785                 ),
1786             ]
1787         "#]],
1788     );
1789 }
1790
1791 #[test]
1792 fn test_hover_test_mod_has_action() {
1793     check_actions(
1794         r#"
1795 mod tests$0 {
1796     #[test]
1797     fn foo_test() {}
1798 }
1799 "#,
1800         expect![[r#"
1801                 [
1802                     Runnable(
1803                         Runnable {
1804                             use_name_in_title: false,
1805                             nav: NavigationTarget {
1806                                 file_id: FileId(
1807                                     0,
1808                                 ),
1809                                 full_range: 0..46,
1810                                 focus_range: 4..9,
1811                                 name: "tests",
1812                                 kind: Module,
1813                                 description: "mod tests",
1814                             },
1815                             kind: TestMod {
1816                                 path: "tests",
1817                             },
1818                             cfg: None,
1819                         },
1820                     ),
1821                 ]
1822             "#]],
1823     );
1824 }
1825
1826 #[test]
1827 fn test_hover_struct_has_goto_type_action() {
1828     check_actions(
1829         r#"
1830 struct S{ f1: u32 }
1831
1832 fn main() { let s$0t = S{ f1:0 }; }
1833 "#,
1834         expect![[r#"
1835                 [
1836                     GoToType(
1837                         [
1838                             HoverGotoTypeData {
1839                                 mod_path: "test::S",
1840                                 nav: NavigationTarget {
1841                                     file_id: FileId(
1842                                         0,
1843                                     ),
1844                                     full_range: 0..19,
1845                                     focus_range: 7..8,
1846                                     name: "S",
1847                                     kind: Struct,
1848                                     description: "struct S",
1849                                 },
1850                             },
1851                         ],
1852                     ),
1853                 ]
1854             "#]],
1855     );
1856 }
1857
1858 #[test]
1859 fn test_hover_generic_struct_has_goto_type_actions() {
1860     check_actions(
1861         r#"
1862 struct Arg(u32);
1863 struct S<T>{ f1: T }
1864
1865 fn main() { let s$0t = S{ f1:Arg(0) }; }
1866 "#,
1867         expect![[r#"
1868                 [
1869                     GoToType(
1870                         [
1871                             HoverGotoTypeData {
1872                                 mod_path: "test::S",
1873                                 nav: NavigationTarget {
1874                                     file_id: FileId(
1875                                         0,
1876                                     ),
1877                                     full_range: 17..37,
1878                                     focus_range: 24..25,
1879                                     name: "S",
1880                                     kind: Struct,
1881                                     description: "struct S<T>",
1882                                 },
1883                             },
1884                             HoverGotoTypeData {
1885                                 mod_path: "test::Arg",
1886                                 nav: NavigationTarget {
1887                                     file_id: FileId(
1888                                         0,
1889                                     ),
1890                                     full_range: 0..16,
1891                                     focus_range: 7..10,
1892                                     name: "Arg",
1893                                     kind: Struct,
1894                                     description: "struct Arg",
1895                                 },
1896                             },
1897                         ],
1898                     ),
1899                 ]
1900             "#]],
1901     );
1902 }
1903
1904 #[test]
1905 fn test_hover_generic_struct_has_flattened_goto_type_actions() {
1906     check_actions(
1907         r#"
1908 struct Arg(u32);
1909 struct S<T>{ f1: T }
1910
1911 fn main() { let s$0t = S{ f1: S{ f1: Arg(0) } }; }
1912 "#,
1913         expect![[r#"
1914                 [
1915                     GoToType(
1916                         [
1917                             HoverGotoTypeData {
1918                                 mod_path: "test::S",
1919                                 nav: NavigationTarget {
1920                                     file_id: FileId(
1921                                         0,
1922                                     ),
1923                                     full_range: 17..37,
1924                                     focus_range: 24..25,
1925                                     name: "S",
1926                                     kind: Struct,
1927                                     description: "struct S<T>",
1928                                 },
1929                             },
1930                             HoverGotoTypeData {
1931                                 mod_path: "test::Arg",
1932                                 nav: NavigationTarget {
1933                                     file_id: FileId(
1934                                         0,
1935                                     ),
1936                                     full_range: 0..16,
1937                                     focus_range: 7..10,
1938                                     name: "Arg",
1939                                     kind: Struct,
1940                                     description: "struct Arg",
1941                                 },
1942                             },
1943                         ],
1944                     ),
1945                 ]
1946             "#]],
1947     );
1948 }
1949
1950 #[test]
1951 fn test_hover_tuple_has_goto_type_actions() {
1952     check_actions(
1953         r#"
1954 struct A(u32);
1955 struct B(u32);
1956 mod M {
1957     pub struct C(u32);
1958 }
1959
1960 fn main() { let s$0t = (A(1), B(2), M::C(3) ); }
1961 "#,
1962         expect![[r#"
1963                 [
1964                     GoToType(
1965                         [
1966                             HoverGotoTypeData {
1967                                 mod_path: "test::A",
1968                                 nav: NavigationTarget {
1969                                     file_id: FileId(
1970                                         0,
1971                                     ),
1972                                     full_range: 0..14,
1973                                     focus_range: 7..8,
1974                                     name: "A",
1975                                     kind: Struct,
1976                                     description: "struct A",
1977                                 },
1978                             },
1979                             HoverGotoTypeData {
1980                                 mod_path: "test::B",
1981                                 nav: NavigationTarget {
1982                                     file_id: FileId(
1983                                         0,
1984                                     ),
1985                                     full_range: 15..29,
1986                                     focus_range: 22..23,
1987                                     name: "B",
1988                                     kind: Struct,
1989                                     description: "struct B",
1990                                 },
1991                             },
1992                             HoverGotoTypeData {
1993                                 mod_path: "test::M::C",
1994                                 nav: NavigationTarget {
1995                                     file_id: FileId(
1996                                         0,
1997                                     ),
1998                                     full_range: 42..60,
1999                                     focus_range: 53..54,
2000                                     name: "C",
2001                                     kind: Struct,
2002                                     description: "pub struct C",
2003                                 },
2004                             },
2005                         ],
2006                     ),
2007                 ]
2008             "#]],
2009     );
2010 }
2011
2012 #[test]
2013 fn test_hover_return_impl_trait_has_goto_type_action() {
2014     check_actions(
2015         r#"
2016 trait Foo {}
2017 fn foo() -> impl Foo {}
2018
2019 fn main() { let s$0t = foo(); }
2020 "#,
2021         expect![[r#"
2022                 [
2023                     GoToType(
2024                         [
2025                             HoverGotoTypeData {
2026                                 mod_path: "test::Foo",
2027                                 nav: NavigationTarget {
2028                                     file_id: FileId(
2029                                         0,
2030                                     ),
2031                                     full_range: 0..12,
2032                                     focus_range: 6..9,
2033                                     name: "Foo",
2034                                     kind: Trait,
2035                                     description: "trait Foo",
2036                                 },
2037                             },
2038                         ],
2039                     ),
2040                 ]
2041             "#]],
2042     );
2043 }
2044
2045 #[test]
2046 fn test_hover_generic_return_impl_trait_has_goto_type_action() {
2047     check_actions(
2048         r#"
2049 trait Foo<T> {}
2050 struct S;
2051 fn foo() -> impl Foo<S> {}
2052
2053 fn main() { let s$0t = foo(); }
2054 "#,
2055         expect![[r#"
2056                 [
2057                     GoToType(
2058                         [
2059                             HoverGotoTypeData {
2060                                 mod_path: "test::Foo",
2061                                 nav: NavigationTarget {
2062                                     file_id: FileId(
2063                                         0,
2064                                     ),
2065                                     full_range: 0..15,
2066                                     focus_range: 6..9,
2067                                     name: "Foo",
2068                                     kind: Trait,
2069                                     description: "trait Foo<T>",
2070                                 },
2071                             },
2072                             HoverGotoTypeData {
2073                                 mod_path: "test::S",
2074                                 nav: NavigationTarget {
2075                                     file_id: FileId(
2076                                         0,
2077                                     ),
2078                                     full_range: 16..25,
2079                                     focus_range: 23..24,
2080                                     name: "S",
2081                                     kind: Struct,
2082                                     description: "struct S",
2083                                 },
2084                             },
2085                         ],
2086                     ),
2087                 ]
2088             "#]],
2089     );
2090 }
2091
2092 #[test]
2093 fn test_hover_return_impl_traits_has_goto_type_action() {
2094     check_actions(
2095         r#"
2096 trait Foo {}
2097 trait Bar {}
2098 fn foo() -> impl Foo + Bar {}
2099
2100 fn main() { let s$0t = foo(); }
2101 "#,
2102         expect![[r#"
2103                 [
2104                     GoToType(
2105                         [
2106                             HoverGotoTypeData {
2107                                 mod_path: "test::Foo",
2108                                 nav: NavigationTarget {
2109                                     file_id: FileId(
2110                                         0,
2111                                     ),
2112                                     full_range: 0..12,
2113                                     focus_range: 6..9,
2114                                     name: "Foo",
2115                                     kind: Trait,
2116                                     description: "trait Foo",
2117                                 },
2118                             },
2119                             HoverGotoTypeData {
2120                                 mod_path: "test::Bar",
2121                                 nav: NavigationTarget {
2122                                     file_id: FileId(
2123                                         0,
2124                                     ),
2125                                     full_range: 13..25,
2126                                     focus_range: 19..22,
2127                                     name: "Bar",
2128                                     kind: Trait,
2129                                     description: "trait Bar",
2130                                 },
2131                             },
2132                         ],
2133                     ),
2134                 ]
2135             "#]],
2136     );
2137 }
2138
2139 #[test]
2140 fn test_hover_generic_return_impl_traits_has_goto_type_action() {
2141     check_actions(
2142         r#"
2143 trait Foo<T> {}
2144 trait Bar<T> {}
2145 struct S1 {}
2146 struct S2 {}
2147
2148 fn foo() -> impl Foo<S1> + Bar<S2> {}
2149
2150 fn main() { let s$0t = foo(); }
2151 "#,
2152         expect![[r#"
2153                 [
2154                     GoToType(
2155                         [
2156                             HoverGotoTypeData {
2157                                 mod_path: "test::Foo",
2158                                 nav: NavigationTarget {
2159                                     file_id: FileId(
2160                                         0,
2161                                     ),
2162                                     full_range: 0..15,
2163                                     focus_range: 6..9,
2164                                     name: "Foo",
2165                                     kind: Trait,
2166                                     description: "trait Foo<T>",
2167                                 },
2168                             },
2169                             HoverGotoTypeData {
2170                                 mod_path: "test::Bar",
2171                                 nav: NavigationTarget {
2172                                     file_id: FileId(
2173                                         0,
2174                                     ),
2175                                     full_range: 16..31,
2176                                     focus_range: 22..25,
2177                                     name: "Bar",
2178                                     kind: Trait,
2179                                     description: "trait Bar<T>",
2180                                 },
2181                             },
2182                             HoverGotoTypeData {
2183                                 mod_path: "test::S1",
2184                                 nav: NavigationTarget {
2185                                     file_id: FileId(
2186                                         0,
2187                                     ),
2188                                     full_range: 32..44,
2189                                     focus_range: 39..41,
2190                                     name: "S1",
2191                                     kind: Struct,
2192                                     description: "struct S1",
2193                                 },
2194                             },
2195                             HoverGotoTypeData {
2196                                 mod_path: "test::S2",
2197                                 nav: NavigationTarget {
2198                                     file_id: FileId(
2199                                         0,
2200                                     ),
2201                                     full_range: 45..57,
2202                                     focus_range: 52..54,
2203                                     name: "S2",
2204                                     kind: Struct,
2205                                     description: "struct S2",
2206                                 },
2207                             },
2208                         ],
2209                     ),
2210                 ]
2211             "#]],
2212     );
2213 }
2214
2215 #[test]
2216 fn test_hover_arg_impl_trait_has_goto_type_action() {
2217     check_actions(
2218         r#"
2219 trait Foo {}
2220 fn foo(ar$0g: &impl Foo) {}
2221 "#,
2222         expect![[r#"
2223                 [
2224                     GoToType(
2225                         [
2226                             HoverGotoTypeData {
2227                                 mod_path: "test::Foo",
2228                                 nav: NavigationTarget {
2229                                     file_id: FileId(
2230                                         0,
2231                                     ),
2232                                     full_range: 0..12,
2233                                     focus_range: 6..9,
2234                                     name: "Foo",
2235                                     kind: Trait,
2236                                     description: "trait Foo",
2237                                 },
2238                             },
2239                         ],
2240                     ),
2241                 ]
2242             "#]],
2243     );
2244 }
2245
2246 #[test]
2247 fn test_hover_arg_impl_traits_has_goto_type_action() {
2248     check_actions(
2249         r#"
2250 trait Foo {}
2251 trait Bar<T> {}
2252 struct S{}
2253
2254 fn foo(ar$0g: &impl Foo + Bar<S>) {}
2255 "#,
2256         expect![[r#"
2257                 [
2258                     GoToType(
2259                         [
2260                             HoverGotoTypeData {
2261                                 mod_path: "test::Foo",
2262                                 nav: NavigationTarget {
2263                                     file_id: FileId(
2264                                         0,
2265                                     ),
2266                                     full_range: 0..12,
2267                                     focus_range: 6..9,
2268                                     name: "Foo",
2269                                     kind: Trait,
2270                                     description: "trait Foo",
2271                                 },
2272                             },
2273                             HoverGotoTypeData {
2274                                 mod_path: "test::Bar",
2275                                 nav: NavigationTarget {
2276                                     file_id: FileId(
2277                                         0,
2278                                     ),
2279                                     full_range: 13..28,
2280                                     focus_range: 19..22,
2281                                     name: "Bar",
2282                                     kind: Trait,
2283                                     description: "trait Bar<T>",
2284                                 },
2285                             },
2286                             HoverGotoTypeData {
2287                                 mod_path: "test::S",
2288                                 nav: NavigationTarget {
2289                                     file_id: FileId(
2290                                         0,
2291                                     ),
2292                                     full_range: 29..39,
2293                                     focus_range: 36..37,
2294                                     name: "S",
2295                                     kind: Struct,
2296                                     description: "struct S",
2297                                 },
2298                             },
2299                         ],
2300                     ),
2301                 ]
2302             "#]],
2303     );
2304 }
2305
2306 #[test]
2307 fn test_hover_async_block_impl_trait_has_goto_type_action() {
2308     check_actions(
2309         r#"
2310 //- minicore: future
2311 struct S;
2312 fn foo() {
2313     let fo$0o = async { S };
2314 }
2315 "#,
2316         expect![[r#"
2317                 [
2318                     GoToType(
2319                         [
2320                             HoverGotoTypeData {
2321                                 mod_path: "core::future::Future",
2322                                 nav: NavigationTarget {
2323                                     file_id: FileId(
2324                                         1,
2325                                     ),
2326                                     full_range: 276..458,
2327                                     focus_range: 315..321,
2328                                     name: "Future",
2329                                     kind: Trait,
2330                                     description: "pub trait Future",
2331                                 },
2332                             },
2333                             HoverGotoTypeData {
2334                                 mod_path: "test::S",
2335                                 nav: NavigationTarget {
2336                                     file_id: FileId(
2337                                         0,
2338                                     ),
2339                                     full_range: 0..9,
2340                                     focus_range: 7..8,
2341                                     name: "S",
2342                                     kind: Struct,
2343                                     description: "struct S",
2344                                 },
2345                             },
2346                         ],
2347                     ),
2348                 ]
2349             "#]],
2350     );
2351 }
2352
2353 #[test]
2354 fn test_hover_arg_generic_impl_trait_has_goto_type_action() {
2355     check_actions(
2356         r#"
2357 trait Foo<T> {}
2358 struct S {}
2359 fn foo(ar$0g: &impl Foo<S>) {}
2360 "#,
2361         expect![[r#"
2362                 [
2363                     GoToType(
2364                         [
2365                             HoverGotoTypeData {
2366                                 mod_path: "test::Foo",
2367                                 nav: NavigationTarget {
2368                                     file_id: FileId(
2369                                         0,
2370                                     ),
2371                                     full_range: 0..15,
2372                                     focus_range: 6..9,
2373                                     name: "Foo",
2374                                     kind: Trait,
2375                                     description: "trait Foo<T>",
2376                                 },
2377                             },
2378                             HoverGotoTypeData {
2379                                 mod_path: "test::S",
2380                                 nav: NavigationTarget {
2381                                     file_id: FileId(
2382                                         0,
2383                                     ),
2384                                     full_range: 16..27,
2385                                     focus_range: 23..24,
2386                                     name: "S",
2387                                     kind: Struct,
2388                                     description: "struct S",
2389                                 },
2390                             },
2391                         ],
2392                     ),
2393                 ]
2394             "#]],
2395     );
2396 }
2397
2398 #[test]
2399 fn test_hover_dyn_return_has_goto_type_action() {
2400     check_actions(
2401         r#"
2402 trait Foo {}
2403 struct S;
2404 impl Foo for S {}
2405
2406 struct B<T>{}
2407 fn foo() -> B<dyn Foo> {}
2408
2409 fn main() { let s$0t = foo(); }
2410 "#,
2411         expect![[r#"
2412                 [
2413                     GoToType(
2414                         [
2415                             HoverGotoTypeData {
2416                                 mod_path: "test::B",
2417                                 nav: NavigationTarget {
2418                                     file_id: FileId(
2419                                         0,
2420                                     ),
2421                                     full_range: 42..55,
2422                                     focus_range: 49..50,
2423                                     name: "B",
2424                                     kind: Struct,
2425                                     description: "struct B<T>",
2426                                 },
2427                             },
2428                             HoverGotoTypeData {
2429                                 mod_path: "test::Foo",
2430                                 nav: NavigationTarget {
2431                                     file_id: FileId(
2432                                         0,
2433                                     ),
2434                                     full_range: 0..12,
2435                                     focus_range: 6..9,
2436                                     name: "Foo",
2437                                     kind: Trait,
2438                                     description: "trait Foo",
2439                                 },
2440                             },
2441                         ],
2442                     ),
2443                 ]
2444             "#]],
2445     );
2446 }
2447
2448 #[test]
2449 fn test_hover_dyn_arg_has_goto_type_action() {
2450     check_actions(
2451         r#"
2452 trait Foo {}
2453 fn foo(ar$0g: &dyn Foo) {}
2454 "#,
2455         expect![[r#"
2456                 [
2457                     GoToType(
2458                         [
2459                             HoverGotoTypeData {
2460                                 mod_path: "test::Foo",
2461                                 nav: NavigationTarget {
2462                                     file_id: FileId(
2463                                         0,
2464                                     ),
2465                                     full_range: 0..12,
2466                                     focus_range: 6..9,
2467                                     name: "Foo",
2468                                     kind: Trait,
2469                                     description: "trait Foo",
2470                                 },
2471                             },
2472                         ],
2473                     ),
2474                 ]
2475             "#]],
2476     );
2477 }
2478
2479 #[test]
2480 fn test_hover_generic_dyn_arg_has_goto_type_action() {
2481     check_actions(
2482         r#"
2483 trait Foo<T> {}
2484 struct S {}
2485 fn foo(ar$0g: &dyn Foo<S>) {}
2486 "#,
2487         expect![[r#"
2488                 [
2489                     GoToType(
2490                         [
2491                             HoverGotoTypeData {
2492                                 mod_path: "test::Foo",
2493                                 nav: NavigationTarget {
2494                                     file_id: FileId(
2495                                         0,
2496                                     ),
2497                                     full_range: 0..15,
2498                                     focus_range: 6..9,
2499                                     name: "Foo",
2500                                     kind: Trait,
2501                                     description: "trait Foo<T>",
2502                                 },
2503                             },
2504                             HoverGotoTypeData {
2505                                 mod_path: "test::S",
2506                                 nav: NavigationTarget {
2507                                     file_id: FileId(
2508                                         0,
2509                                     ),
2510                                     full_range: 16..27,
2511                                     focus_range: 23..24,
2512                                     name: "S",
2513                                     kind: Struct,
2514                                     description: "struct S",
2515                                 },
2516                             },
2517                         ],
2518                     ),
2519                 ]
2520             "#]],
2521     );
2522 }
2523
2524 #[test]
2525 fn test_hover_goto_type_action_links_order() {
2526     check_actions(
2527         r#"
2528 trait ImplTrait<T> {}
2529 trait DynTrait<T> {}
2530 struct B<T> {}
2531 struct S {}
2532
2533 fn foo(a$0rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
2534 "#,
2535         expect![[r#"
2536                 [
2537                     GoToType(
2538                         [
2539                             HoverGotoTypeData {
2540                                 mod_path: "test::ImplTrait",
2541                                 nav: NavigationTarget {
2542                                     file_id: FileId(
2543                                         0,
2544                                     ),
2545                                     full_range: 0..21,
2546                                     focus_range: 6..15,
2547                                     name: "ImplTrait",
2548                                     kind: Trait,
2549                                     description: "trait ImplTrait<T>",
2550                                 },
2551                             },
2552                             HoverGotoTypeData {
2553                                 mod_path: "test::B",
2554                                 nav: NavigationTarget {
2555                                     file_id: FileId(
2556                                         0,
2557                                     ),
2558                                     full_range: 43..57,
2559                                     focus_range: 50..51,
2560                                     name: "B",
2561                                     kind: Struct,
2562                                     description: "struct B<T>",
2563                                 },
2564                             },
2565                             HoverGotoTypeData {
2566                                 mod_path: "test::DynTrait",
2567                                 nav: NavigationTarget {
2568                                     file_id: FileId(
2569                                         0,
2570                                     ),
2571                                     full_range: 22..42,
2572                                     focus_range: 28..36,
2573                                     name: "DynTrait",
2574                                     kind: Trait,
2575                                     description: "trait DynTrait<T>",
2576                                 },
2577                             },
2578                             HoverGotoTypeData {
2579                                 mod_path: "test::S",
2580                                 nav: NavigationTarget {
2581                                     file_id: FileId(
2582                                         0,
2583                                     ),
2584                                     full_range: 58..69,
2585                                     focus_range: 65..66,
2586                                     name: "S",
2587                                     kind: Struct,
2588                                     description: "struct S",
2589                                 },
2590                             },
2591                         ],
2592                     ),
2593                 ]
2594             "#]],
2595     );
2596 }
2597
2598 #[test]
2599 fn test_hover_associated_type_has_goto_type_action() {
2600     check_actions(
2601         r#"
2602 trait Foo {
2603     type Item;
2604     fn get(self) -> Self::Item {}
2605 }
2606
2607 struct Bar{}
2608 struct S{}
2609
2610 impl Foo for S { type Item = Bar; }
2611
2612 fn test() -> impl Foo { S {} }
2613
2614 fn main() { let s$0t = test().get(); }
2615 "#,
2616         expect![[r#"
2617                 [
2618                     GoToType(
2619                         [
2620                             HoverGotoTypeData {
2621                                 mod_path: "test::Foo",
2622                                 nav: NavigationTarget {
2623                                     file_id: FileId(
2624                                         0,
2625                                     ),
2626                                     full_range: 0..62,
2627                                     focus_range: 6..9,
2628                                     name: "Foo",
2629                                     kind: Trait,
2630                                     description: "trait Foo",
2631                                 },
2632                             },
2633                         ],
2634                     ),
2635                 ]
2636             "#]],
2637     );
2638 }
2639
2640 #[test]
2641 fn test_hover_const_param_has_goto_type_action() {
2642     check_actions(
2643         r#"
2644 struct Bar;
2645 struct Foo<const BAR: Bar>;
2646
2647 impl<const BAR: Bar> Foo<BAR$0> {}
2648 "#,
2649         expect![[r#"
2650                 [
2651                     GoToType(
2652                         [
2653                             HoverGotoTypeData {
2654                                 mod_path: "test::Bar",
2655                                 nav: NavigationTarget {
2656                                     file_id: FileId(
2657                                         0,
2658                                     ),
2659                                     full_range: 0..11,
2660                                     focus_range: 7..10,
2661                                     name: "Bar",
2662                                     kind: Struct,
2663                                     description: "struct Bar",
2664                                 },
2665                             },
2666                         ],
2667                     ),
2668                 ]
2669             "#]],
2670     );
2671 }
2672
2673 #[test]
2674 fn test_hover_type_param_has_goto_type_action() {
2675     check_actions(
2676         r#"
2677 trait Foo {}
2678
2679 fn foo<T: Foo>(t: T$0){}
2680 "#,
2681         expect![[r#"
2682                 [
2683                     GoToType(
2684                         [
2685                             HoverGotoTypeData {
2686                                 mod_path: "test::Foo",
2687                                 nav: NavigationTarget {
2688                                     file_id: FileId(
2689                                         0,
2690                                     ),
2691                                     full_range: 0..12,
2692                                     focus_range: 6..9,
2693                                     name: "Foo",
2694                                     kind: Trait,
2695                                     description: "trait Foo",
2696                                 },
2697                             },
2698                         ],
2699                     ),
2700                 ]
2701             "#]],
2702     );
2703 }
2704
2705 #[test]
2706 fn test_hover_self_has_go_to_type() {
2707     check_actions(
2708         r#"
2709 struct Foo;
2710 impl Foo {
2711     fn foo(&self$0) {}
2712 }
2713 "#,
2714         expect![[r#"
2715                 [
2716                     GoToType(
2717                         [
2718                             HoverGotoTypeData {
2719                                 mod_path: "test::Foo",
2720                                 nav: NavigationTarget {
2721                                     file_id: FileId(
2722                                         0,
2723                                     ),
2724                                     full_range: 0..11,
2725                                     focus_range: 7..10,
2726                                     name: "Foo",
2727                                     kind: Struct,
2728                                     description: "struct Foo",
2729                                 },
2730                             },
2731                         ],
2732                     ),
2733                 ]
2734             "#]],
2735     );
2736 }
2737
2738 #[test]
2739 fn hover_displays_normalized_crate_names() {
2740     check(
2741         r#"
2742 //- /lib.rs crate:name-with-dashes
2743 pub mod wrapper {
2744     pub struct Thing { x: u32 }
2745
2746     impl Thing {
2747         pub fn new() -> Thing { Thing { x: 0 } }
2748     }
2749 }
2750
2751 //- /main.rs crate:main deps:name-with-dashes
2752 fn main() { let foo_test = name_with_dashes::wrapper::Thing::new$0(); }
2753 "#,
2754         expect![[r#"
2755             *new*
2756
2757             ```rust
2758             name_with_dashes::wrapper::Thing
2759             ```
2760
2761             ```rust
2762             pub fn new() -> Thing
2763             ```
2764             "#]],
2765     )
2766 }
2767
2768 #[test]
2769 fn hover_field_pat_shorthand_ref_match_ergonomics() {
2770     check(
2771         r#"
2772 struct S {
2773     f: i32,
2774 }
2775
2776 fn main() {
2777     let s = S { f: 0 };
2778     let S { f$0 } = &s;
2779 }
2780 "#,
2781         expect![[r#"
2782             *f*
2783
2784             ```rust
2785             f: &i32
2786             ```
2787             ---
2788
2789             ```rust
2790             test::S
2791             ```
2792
2793             ```rust
2794             f: i32
2795             ```
2796         "#]],
2797     );
2798 }
2799
2800 #[test]
2801 fn hover_self_param_shows_type() {
2802     check(
2803         r#"
2804 struct Foo {}
2805 impl Foo {
2806     fn bar(&sel$0f) {}
2807 }
2808 "#,
2809         expect![[r#"
2810                 *self*
2811
2812                 ```rust
2813                 self: &Foo
2814                 ```
2815             "#]],
2816     );
2817 }
2818
2819 #[test]
2820 fn hover_self_param_shows_type_for_arbitrary_self_type() {
2821     check(
2822         r#"
2823 struct Arc<T>(T);
2824 struct Foo {}
2825 impl Foo {
2826     fn bar(sel$0f: Arc<Foo>) {}
2827 }
2828 "#,
2829         expect![[r#"
2830                 *self*
2831
2832                 ```rust
2833                 self: Arc<Foo>
2834                 ```
2835             "#]],
2836     );
2837 }
2838
2839 #[test]
2840 fn hover_doc_outer_inner() {
2841     check(
2842         r#"
2843 /// Be quick;
2844 mod Foo$0 {
2845     //! time is mana
2846
2847     /// This comment belongs to the function
2848     fn foo() {}
2849 }
2850 "#,
2851         expect![[r#"
2852                 *Foo*
2853
2854                 ```rust
2855                 test
2856                 ```
2857
2858                 ```rust
2859                 mod Foo
2860                 ```
2861
2862                 ---
2863
2864                 Be quick;
2865                 time is mana
2866             "#]],
2867     );
2868 }
2869
2870 #[test]
2871 fn hover_doc_outer_inner_attribue() {
2872     check(
2873         r#"
2874 #[doc = "Be quick;"]
2875 mod Foo$0 {
2876     #![doc = "time is mana"]
2877
2878     #[doc = "This comment belongs to the function"]
2879     fn foo() {}
2880 }
2881 "#,
2882         expect![[r#"
2883                 *Foo*
2884
2885                 ```rust
2886                 test
2887                 ```
2888
2889                 ```rust
2890                 mod Foo
2891                 ```
2892
2893                 ---
2894
2895                 Be quick;
2896                 time is mana
2897             "#]],
2898     );
2899 }
2900
2901 #[test]
2902 fn hover_doc_block_style_indentend() {
2903     check(
2904         r#"
2905 /**
2906     foo
2907     ```rust
2908     let x = 3;
2909     ```
2910 */
2911 fn foo$0() {}
2912 "#,
2913         expect![[r#"
2914                 *foo*
2915
2916                 ```rust
2917                 test
2918                 ```
2919
2920                 ```rust
2921                 fn foo()
2922                 ```
2923
2924                 ---
2925
2926                 foo
2927
2928                 ```rust
2929                 let x = 3;
2930                 ```
2931             "#]],
2932     );
2933 }
2934
2935 #[test]
2936 fn hover_comments_dont_highlight_parent() {
2937     cov_mark::check!(no_highlight_on_comment_hover);
2938     check_hover_no_result(
2939         r#"
2940 fn no_hover() {
2941     // no$0hover
2942 }
2943 "#,
2944     );
2945 }
2946
2947 #[test]
2948 fn hover_label() {
2949     check(
2950         r#"
2951 fn foo() {
2952     'label$0: loop {}
2953 }
2954 "#,
2955         expect![[r#"
2956             *'label*
2957
2958             ```rust
2959             'label
2960             ```
2961             "#]],
2962     );
2963 }
2964
2965 #[test]
2966 fn hover_lifetime() {
2967     check(
2968         r#"fn foo<'lifetime>(_: &'lifetime$0 ()) {}"#,
2969         expect![[r#"
2970             *'lifetime*
2971
2972             ```rust
2973             'lifetime
2974             ```
2975             "#]],
2976     );
2977 }
2978
2979 #[test]
2980 fn hover_type_param() {
2981     check(
2982         r#"
2983 //- minicore: sized
2984 struct Foo<T>(T);
2985 trait TraitA {}
2986 trait TraitB {}
2987 impl<T: TraitA + TraitB> Foo<T$0> where T: Sized {}
2988 "#,
2989         expect![[r#"
2990                 *T*
2991
2992                 ```rust
2993                 T: TraitA + TraitB
2994                 ```
2995             "#]],
2996     );
2997     check(
2998         r#"
2999 //- minicore: sized
3000 struct Foo<T>(T);
3001 impl<T> Foo<T$0> {}
3002 "#,
3003         expect![[r#"
3004                 *T*
3005
3006                 ```rust
3007                 T
3008                 ```
3009                 "#]],
3010     );
3011     // lifetimes bounds arent being tracked yet
3012     check(
3013         r#"
3014 //- minicore: sized
3015 struct Foo<T>(T);
3016 impl<T: 'static> Foo<T$0> {}
3017 "#,
3018         expect![[r#"
3019                 *T*
3020
3021                 ```rust
3022                 T
3023                 ```
3024                 "#]],
3025     );
3026 }
3027
3028 #[test]
3029 fn hover_type_param_sized_bounds() {
3030     // implicit `: Sized` bound
3031     check(
3032         r#"
3033 //- minicore: sized
3034 trait Trait {}
3035 struct Foo<T>(T);
3036 impl<T: Trait> Foo<T$0> {}
3037 "#,
3038         expect![[r#"
3039                 *T*
3040
3041                 ```rust
3042                 T: Trait
3043                 ```
3044             "#]],
3045     );
3046     check(
3047         r#"
3048 //- minicore: sized
3049 trait Trait {}
3050 struct Foo<T>(T);
3051 impl<T: Trait + ?Sized> Foo<T$0> {}
3052 "#,
3053         expect![[r#"
3054                 *T*
3055
3056                 ```rust
3057                 T: Trait + ?Sized
3058                 ```
3059             "#]],
3060     );
3061 }
3062
3063 mod type_param_sized_bounds {
3064     use super::*;
3065
3066     #[test]
3067     fn single_implicit() {
3068         check(
3069             r#"
3070 //- minicore: sized
3071 fn foo<T$0>() {}
3072 "#,
3073             expect![[r#"
3074                     *T*
3075
3076                     ```rust
3077                     T
3078                     ```
3079                 "#]],
3080         );
3081     }
3082
3083     #[test]
3084     fn single_explicit() {
3085         check(
3086             r#"
3087 //- minicore: sized
3088 fn foo<T$0: Sized>() {}
3089 "#,
3090             expect![[r#"
3091                     *T*
3092
3093                     ```rust
3094                     T
3095                     ```
3096                 "#]],
3097         );
3098     }
3099
3100     #[test]
3101     fn single_relaxed() {
3102         check(
3103             r#"
3104 //- minicore: sized
3105 fn foo<T$0: ?Sized>() {}
3106 "#,
3107             expect![[r#"
3108                     *T*
3109
3110                     ```rust
3111                     T: ?Sized
3112                     ```
3113                 "#]],
3114         );
3115     }
3116
3117     #[test]
3118     fn multiple_implicit() {
3119         check(
3120             r#"
3121 //- minicore: sized
3122 trait Trait {}
3123 fn foo<T$0: Trait>() {}
3124 "#,
3125             expect![[r#"
3126                     *T*
3127
3128                     ```rust
3129                     T: Trait
3130                     ```
3131                 "#]],
3132         );
3133     }
3134
3135     #[test]
3136     fn multiple_explicit() {
3137         check(
3138             r#"
3139 //- minicore: sized
3140 trait Trait {}
3141 fn foo<T$0: Trait + Sized>() {}
3142 "#,
3143             expect![[r#"
3144                     *T*
3145
3146                     ```rust
3147                     T: Trait
3148                     ```
3149                 "#]],
3150         );
3151     }
3152
3153     #[test]
3154     fn multiple_relaxed() {
3155         check(
3156             r#"
3157 //- minicore: sized
3158 trait Trait {}
3159 fn foo<T$0: Trait + ?Sized>() {}
3160 "#,
3161             expect![[r#"
3162                     *T*
3163
3164                     ```rust
3165                     T: Trait + ?Sized
3166                     ```
3167                 "#]],
3168         );
3169     }
3170
3171     #[test]
3172     fn mixed() {
3173         check(
3174             r#"
3175 //- minicore: sized
3176 fn foo<T$0: ?Sized + Sized + Sized>() {}
3177 "#,
3178             expect![[r#"
3179                     *T*
3180
3181                     ```rust
3182                     T
3183                     ```
3184                 "#]],
3185         );
3186         check(
3187             r#"
3188 //- minicore: sized
3189 trait Trait {}
3190 fn foo<T$0: Sized + ?Sized + Sized + Trait>() {}
3191 "#,
3192             expect![[r#"
3193                     *T*
3194
3195                     ```rust
3196                     T: Trait
3197                     ```
3198                 "#]],
3199         );
3200     }
3201 }
3202
3203 #[test]
3204 fn hover_const_param() {
3205     check(
3206         r#"
3207 struct Foo<const LEN: usize>;
3208 impl<const LEN: usize> Foo<LEN$0> {}
3209 "#,
3210         expect![[r#"
3211                 *LEN*
3212
3213                 ```rust
3214                 const LEN: usize
3215                 ```
3216             "#]],
3217     );
3218 }
3219
3220 #[test]
3221 fn hover_const_pat() {
3222     check(
3223         r#"
3224 /// This is a doc
3225 const FOO: usize = 3;
3226 fn foo() {
3227     match 5 {
3228         FOO$0 => (),
3229         _ => ()
3230     }
3231 }
3232 "#,
3233         expect![[r#"
3234             *FOO*
3235
3236             ```rust
3237             test
3238             ```
3239
3240             ```rust
3241             const FOO: usize = 3
3242             ```
3243
3244             ---
3245
3246             This is a doc
3247         "#]],
3248     );
3249 }
3250
3251 #[test]
3252 fn hover_mod_def() {
3253     check(
3254         r#"
3255 //- /main.rs
3256 mod foo$0;
3257 //- /foo.rs
3258 //! For the horde!
3259 "#,
3260         expect![[r#"
3261                 *foo*
3262
3263                 ```rust
3264                 test
3265                 ```
3266
3267                 ```rust
3268                 mod foo
3269                 ```
3270
3271                 ---
3272
3273                 For the horde!
3274             "#]],
3275     );
3276 }
3277
3278 #[test]
3279 fn hover_self_in_use() {
3280     check(
3281         r#"
3282 //! This should not appear
3283 mod foo {
3284     /// But this should appear
3285     pub mod bar {}
3286 }
3287 use foo::bar::{self$0};
3288 "#,
3289         expect![[r#"
3290                 *self*
3291
3292                 ```rust
3293                 test::foo
3294                 ```
3295
3296                 ```rust
3297                 mod bar
3298                 ```
3299
3300                 ---
3301
3302                 But this should appear
3303             "#]],
3304     )
3305 }
3306
3307 #[test]
3308 fn hover_keyword() {
3309     check(
3310         r#"
3311 //- /main.rs crate:main deps:std
3312 fn f() { retur$0n; }
3313 //- /libstd.rs crate:std
3314 /// Docs for return_keyword
3315 mod return_keyword {}
3316 "#,
3317         expect![[r#"
3318                 *return*
3319
3320                 ```rust
3321                 return
3322                 ```
3323
3324                 ---
3325
3326                 Docs for return_keyword
3327             "#]],
3328     );
3329 }
3330
3331 #[test]
3332 fn hover_builtin() {
3333     check(
3334         r#"
3335 //- /main.rs crate:main deps:std
3336 cosnt _: &str$0 = ""; }
3337
3338 //- /libstd.rs crate:std
3339 /// Docs for prim_str
3340 mod prim_str {}
3341 "#,
3342         expect![[r#"
3343                 *str*
3344
3345                 ```rust
3346                 str
3347                 ```
3348
3349                 ---
3350
3351                 Docs for prim_str
3352             "#]],
3353     );
3354 }
3355
3356 #[test]
3357 fn hover_macro_expanded_function() {
3358     check(
3359         r#"
3360 struct S<'a, T>(&'a T);
3361 trait Clone {}
3362 macro_rules! foo {
3363     () => {
3364         fn bar<'t, T: Clone + 't>(s: &mut S<'t, T>, t: u32) -> *mut u32 where
3365             't: 't + 't,
3366             for<'a> T: Clone + 'a
3367         { 0 as _ }
3368     };
3369 }
3370
3371 foo!();
3372
3373 fn main() {
3374     bar$0;
3375 }
3376 "#,
3377         expect![[r#"
3378                 *bar*
3379
3380                 ```rust
3381                 test
3382                 ```
3383
3384                 ```rust
3385                 fn bar<'t, T>(s: &mut S<'t, T>, t: u32) -> *mut u32
3386                 where
3387                     T: Clone + 't,
3388                     't: 't + 't,
3389                     for<'a> T: Clone + 'a,
3390                 ```
3391             "#]],
3392     )
3393 }
3394
3395 #[test]
3396 fn hover_intra_doc_links() {
3397     check(
3398         r#"
3399
3400 pub mod theitem {
3401     /// This is the item. Cool!
3402     pub struct TheItem;
3403 }
3404
3405 /// Gives you a [`TheItem$0`].
3406 ///
3407 /// [`TheItem`]: theitem::TheItem
3408 pub fn gimme() -> theitem::TheItem {
3409     theitem::TheItem
3410 }
3411 "#,
3412         expect![[r#"
3413                 *[`TheItem`]*
3414
3415                 ```rust
3416                 test::theitem
3417                 ```
3418
3419                 ```rust
3420                 pub struct TheItem
3421                 ```
3422
3423                 ---
3424
3425                 This is the item. Cool!
3426             "#]],
3427     );
3428 }
3429
3430 #[test]
3431 fn hover_generic_assoc() {
3432     check(
3433         r#"
3434 fn foo<T: A>() where T::Assoc$0: {}
3435
3436 trait A {
3437     type Assoc;
3438 }"#,
3439         expect![[r#"
3440                 *Assoc*
3441
3442                 ```rust
3443                 test
3444                 ```
3445
3446                 ```rust
3447                 type Assoc
3448                 ```
3449             "#]],
3450     );
3451     check(
3452         r#"
3453 fn foo<T: A>() {
3454     let _: <T>::Assoc$0;
3455 }
3456
3457 trait A {
3458     type Assoc;
3459 }"#,
3460         expect![[r#"
3461                 *Assoc*
3462
3463                 ```rust
3464                 test
3465                 ```
3466
3467                 ```rust
3468                 type Assoc
3469                 ```
3470             "#]],
3471     );
3472     check(
3473         r#"
3474 trait A where
3475     Self::Assoc$0: ,
3476 {
3477     type Assoc;
3478 }"#,
3479         expect![[r#"
3480                 *Assoc*
3481
3482                 ```rust
3483                 test
3484                 ```
3485
3486                 ```rust
3487                 type Assoc
3488                 ```
3489             "#]],
3490     );
3491 }
3492
3493 #[test]
3494 fn string_shadowed_with_inner_items() {
3495     check(
3496         r#"
3497 //- /main.rs crate:main deps:alloc
3498
3499 /// Custom `String` type.
3500 struct String;
3501
3502 fn f() {
3503     let _: String$0;
3504
3505     fn inner() {}
3506 }
3507
3508 //- /alloc.rs crate:alloc
3509 #[prelude_import]
3510 pub use string::*;
3511
3512 mod string {
3513     /// This is `alloc::String`.
3514     pub struct String;
3515 }
3516 "#,
3517         expect![[r#"
3518                 *String*
3519
3520                 ```rust
3521                 main
3522                 ```
3523
3524                 ```rust
3525                 struct String
3526                 ```
3527
3528                 ---
3529
3530                 Custom `String` type.
3531             "#]],
3532     )
3533 }
3534
3535 #[test]
3536 fn function_doesnt_shadow_crate_in_use_tree() {
3537     check(
3538         r#"
3539 //- /main.rs crate:main deps:foo
3540 use foo$0::{foo};
3541
3542 //- /foo.rs crate:foo
3543 pub fn foo() {}
3544 "#,
3545         expect![[r#"
3546                 *foo*
3547
3548                 ```rust
3549                 extern crate foo
3550                 ```
3551             "#]],
3552     )
3553 }
3554
3555 #[test]
3556 fn hover_feature() {
3557     check(
3558         r#"#![feature(box_syntax$0)]"#,
3559         expect![[r##"
3560                 *box_syntax*
3561                 ```
3562                 box_syntax
3563                 ```
3564                 ___
3565
3566                 # `box_syntax`
3567
3568                 The tracking issue for this feature is: [#49733]
3569
3570                 [#49733]: https://github.com/rust-lang/rust/issues/49733
3571
3572                 See also [`box_patterns`](box-patterns.md)
3573
3574                 ------------------------
3575
3576                 Currently the only stable way to create a `Box` is via the `Box::new` method.
3577                 Also it is not possible in stable Rust to destructure a `Box` in a match
3578                 pattern. The unstable `box` keyword can be used to create a `Box`. An example
3579                 usage would be:
3580
3581                 ```rust
3582                 #![feature(box_syntax)]
3583
3584                 fn main() {
3585                     let b = box 5;
3586                 }
3587                 ```
3588
3589             "##]],
3590     )
3591 }
3592
3593 #[test]
3594 fn hover_lint() {
3595     check(
3596         r#"#![allow(arithmetic_overflow$0)]"#,
3597         expect![[r#"
3598                 *arithmetic_overflow*
3599                 ```
3600                 arithmetic_overflow
3601                 ```
3602                 ___
3603
3604                 arithmetic operation overflows
3605             "#]],
3606     )
3607 }
3608
3609 #[test]
3610 fn hover_clippy_lint() {
3611     check(
3612         r#"#![allow(clippy::almost_swapped$0)]"#,
3613         expect![[r#"
3614                 *almost_swapped*
3615                 ```
3616                 clippy::almost_swapped
3617                 ```
3618                 ___
3619
3620                 Checks for `foo = bar; bar = foo` sequences.
3621             "#]],
3622     )
3623 }
3624
3625 #[test]
3626 fn hover_attr_path_qualifier() {
3627     cov_mark::check!(name_ref_classify_attr_path_qualifier);
3628     check(
3629         r#"
3630 //- /foo.rs crate:foo
3631
3632 //- /lib.rs crate:main.rs deps:foo
3633 #[fo$0o::bar()]
3634 struct Foo;
3635 "#,
3636         expect![[r#"
3637                 *foo*
3638
3639                 ```rust
3640                 extern crate foo
3641                 ```
3642             "#]],
3643     )
3644 }
3645
3646 #[test]
3647 fn hover_rename() {
3648     check(
3649         r#"
3650 use self as foo$0;
3651 "#,
3652         expect![[r#"
3653                 *foo*
3654
3655                 ```rust
3656                 extern crate test
3657                 ```
3658             "#]],
3659     );
3660     check(
3661         r#"
3662 mod bar {}
3663 use bar::{self as foo$0};
3664 "#,
3665         expect![[r#"
3666                 *foo*
3667
3668                 ```rust
3669                 test
3670                 ```
3671
3672                 ```rust
3673                 mod bar
3674                 ```
3675             "#]],
3676     );
3677     check(
3678         r#"
3679 mod bar {
3680     use super as foo$0;
3681 }
3682 "#,
3683         expect![[r#"
3684                 *foo*
3685
3686                 ```rust
3687                 extern crate test
3688                 ```
3689             "#]],
3690     );
3691     check(
3692         r#"
3693 use crate as foo$0;
3694 "#,
3695         expect![[r#"
3696                 *foo*
3697
3698                 ```rust
3699                 extern crate test
3700                 ```
3701             "#]],
3702     );
3703 }
3704
3705 #[test]
3706 fn hover_attribute_in_macro() {
3707     check(
3708         r#"
3709 //- minicore:derive
3710 macro_rules! identity {
3711     ($struct:item) => {
3712         $struct
3713     };
3714 }
3715 #[rustc_builtin_macro]
3716 pub macro Copy {}
3717 identity!{
3718     #[derive(Copy$0)]
3719     struct Foo;
3720 }
3721 "#,
3722         expect![[r#"
3723                 *Copy*
3724
3725                 ```rust
3726                 test
3727                 ```
3728
3729                 ```rust
3730                 pub macro Copy
3731                 ```
3732             "#]],
3733     );
3734 }
3735
3736 #[test]
3737 fn hover_derive_input() {
3738     check(
3739         r#"
3740 //- minicore:derive
3741 #[rustc_builtin_macro]
3742 pub macro Copy {}
3743 #[derive(Copy$0)]
3744 struct Foo;
3745 "#,
3746         expect![[r#"
3747                 *Copy*
3748
3749                 ```rust
3750                 test
3751                 ```
3752
3753                 ```rust
3754                 pub macro Copy
3755                 ```
3756             "#]],
3757     );
3758     check(
3759         r#"
3760 //- minicore:derive
3761 mod foo {
3762     #[rustc_builtin_macro]
3763     pub macro Copy {}
3764 }
3765 #[derive(foo::Copy$0)]
3766 struct Foo;
3767 "#,
3768         expect![[r#"
3769                 *Copy*
3770
3771                 ```rust
3772                 test
3773                 ```
3774
3775                 ```rust
3776                 pub macro Copy
3777                 ```
3778             "#]],
3779     );
3780 }
3781
3782 #[test]
3783 fn hover_range_math() {
3784     check_hover_range(
3785         r#"
3786 fn f() { let expr = $01 + 2 * 3$0 }
3787 "#,
3788         expect![[r#"
3789             ```rust
3790             i32
3791             ```"#]],
3792     );
3793
3794     check_hover_range(
3795         r#"
3796 fn f() { let expr = 1 $0+ 2 * $03 }
3797 "#,
3798         expect![[r#"
3799             ```rust
3800             i32
3801             ```"#]],
3802     );
3803
3804     check_hover_range(
3805         r#"
3806 fn f() { let expr = 1 + $02 * 3$0 }
3807 "#,
3808         expect![[r#"
3809             ```rust
3810             i32
3811             ```"#]],
3812     );
3813 }
3814
3815 #[test]
3816 fn hover_range_arrays() {
3817     check_hover_range(
3818         r#"
3819 fn f() { let expr = $0[1, 2, 3, 4]$0 }
3820 "#,
3821         expect![[r#"
3822             ```rust
3823             [i32; 4]
3824             ```"#]],
3825     );
3826
3827     check_hover_range(
3828         r#"
3829 fn f() { let expr = [1, 2, $03, 4]$0 }
3830 "#,
3831         expect![[r#"
3832             ```rust
3833             [i32; 4]
3834             ```"#]],
3835     );
3836
3837     check_hover_range(
3838         r#"
3839 fn f() { let expr = [1, 2, $03$0, 4] }
3840 "#,
3841         expect![[r#"
3842             ```rust
3843             i32
3844             ```"#]],
3845     );
3846 }
3847
3848 #[test]
3849 fn hover_range_functions() {
3850     check_hover_range(
3851         r#"
3852 fn f<T>(a: &[T]) { }
3853 fn b() { $0f$0(&[1, 2, 3, 4, 5]); }
3854 "#,
3855         expect![[r#"
3856             ```rust
3857             fn f<i32>(&[i32])
3858             ```"#]],
3859     );
3860
3861     check_hover_range(
3862         r#"
3863 fn f<T>(a: &[T]) { }
3864 fn b() { f($0&[1, 2, 3, 4, 5]$0); }
3865 "#,
3866         expect![[r#"
3867             ```rust
3868             &[i32; 5]
3869             ```"#]],
3870     );
3871 }
3872
3873 #[test]
3874 fn hover_range_shows_nothing_when_invalid() {
3875     check_hover_range_no_results(
3876         r#"
3877 fn f<T>(a: &[T]) { }
3878 fn b()$0 { f(&[1, 2, 3, 4, 5]); }$0
3879 "#,
3880     );
3881
3882     check_hover_range_no_results(
3883         r#"
3884 fn f<T>$0(a: &[T]) { }
3885 fn b() { f(&[1, 2, 3,$0 4, 5]); }
3886 "#,
3887     );
3888
3889     check_hover_range_no_results(
3890         r#"
3891 fn $0f() { let expr = [1, 2, 3, 4]$0 }
3892 "#,
3893     );
3894 }
3895
3896 #[test]
3897 fn hover_range_shows_unit_for_statements() {
3898     check_hover_range(
3899         r#"
3900 fn f<T>(a: &[T]) { }
3901 fn b() { $0f(&[1, 2, 3, 4, 5]); }$0
3902 "#,
3903         expect![[r#"
3904             ```rust
3905             ()
3906             ```"#]],
3907     );
3908
3909     check_hover_range(
3910         r#"
3911 fn f() { let expr$0 = $0[1, 2, 3, 4] }
3912 "#,
3913         expect![[r#"
3914             ```rust
3915             ()
3916             ```"#]],
3917     );
3918 }
3919
3920 #[test]
3921 fn hover_range_for_pat() {
3922     check_hover_range(
3923         r#"
3924 fn foo() {
3925     let $0x$0 = 0;
3926 }
3927 "#,
3928         expect![[r#"
3929                 ```rust
3930                 i32
3931                 ```"#]],
3932     );
3933
3934     check_hover_range(
3935         r#"
3936 fn foo() {
3937     let $0x$0 = "";
3938 }
3939 "#,
3940         expect![[r#"
3941                 ```rust
3942                 &str
3943                 ```"#]],
3944     );
3945 }
3946
3947 #[test]
3948 fn hover_range_shows_coercions_if_applicable_expr() {
3949     check_hover_range(
3950         r#"
3951 fn foo() {
3952     let x: &u32 = $0&&&&&0$0;
3953 }
3954 "#,
3955         expect![[r#"
3956                 ```text
3957                 Type:       &&&&&u32
3958                 Coerced to:     &u32
3959                 ```
3960             "#]],
3961     );
3962     check_hover_range(
3963         r#"
3964 fn foo() {
3965     let x: *const u32 = $0&0$0;
3966 }
3967 "#,
3968         expect![[r#"
3969                 ```text
3970                 Type:             &u32
3971                 Coerced to: *const u32
3972                 ```
3973             "#]],
3974     );
3975 }
3976
3977 #[test]
3978 fn hover_range_shows_type_actions() {
3979     check_actions(
3980         r#"
3981 struct Foo;
3982 fn foo() {
3983     let x: &Foo = $0&&&&&Foo$0;
3984 }
3985 "#,
3986         expect![[r#"
3987                 [
3988                     GoToType(
3989                         [
3990                             HoverGotoTypeData {
3991                                 mod_path: "test::Foo",
3992                                 nav: NavigationTarget {
3993                                     file_id: FileId(
3994                                         0,
3995                                     ),
3996                                     full_range: 0..11,
3997                                     focus_range: 7..10,
3998                                     name: "Foo",
3999                                     kind: Struct,
4000                                     description: "struct Foo",
4001                                 },
4002                             },
4003                         ],
4004                     ),
4005                 ]
4006             "#]],
4007     );
4008 }
4009
4010 #[test]
4011 fn hover_try_expr_res() {
4012     check_hover_range(
4013         r#"
4014 //- minicore:result
4015 struct FooError;
4016
4017 fn foo() -> Result<(), FooError> {
4018     Ok($0Result::<(), FooError>::Ok(())?$0)
4019 }
4020 "#,
4021         expect![[r#"
4022                 ```rust
4023                 ()
4024                 ```"#]],
4025     );
4026     check_hover_range(
4027         r#"
4028 //- minicore:result
4029 struct FooError;
4030 struct BarError;
4031
4032 fn foo() -> Result<(), FooError> {
4033     Ok($0Result::<(), BarError>::Ok(())?$0)
4034 }
4035 "#,
4036         expect![[r#"
4037                 ```text
4038                 Try Error Type: BarError
4039                 Propagated as:  FooError
4040                 ```
4041             "#]],
4042     );
4043 }
4044
4045 #[test]
4046 fn hover_try_expr() {
4047     check_hover_range(
4048         r#"
4049 struct NotResult<T, U>(T, U);
4050 struct Short;
4051 struct Looooong;
4052
4053 fn foo() -> NotResult<(), Looooong> {
4054     $0NotResult((), Short)?$0;
4055 }
4056 "#,
4057         expect![[r#"
4058                 ```text
4059                 Try Target Type:    NotResult<(), Short>
4060                 Propagated as:   NotResult<(), Looooong>
4061                 ```
4062             "#]],
4063     );
4064     check_hover_range(
4065         r#"
4066 struct NotResult<T, U>(T, U);
4067 struct Short;
4068 struct Looooong;
4069
4070 fn foo() -> NotResult<(), Short> {
4071     $0NotResult((), Looooong)?$0;
4072 }
4073 "#,
4074         expect![[r#"
4075                 ```text
4076                 Try Target Type: NotResult<(), Looooong>
4077                 Propagated as:      NotResult<(), Short>
4078                 ```
4079             "#]],
4080     );
4081 }
4082
4083 #[test]
4084 fn hover_try_expr_option() {
4085     cov_mark::check!(hover_try_expr_opt_opt);
4086     check_hover_range(
4087         r#"
4088 //- minicore: option, try
4089
4090 fn foo() -> Option<()> {
4091     $0Some(0)?$0;
4092     None
4093 }
4094 "#,
4095         expect![[r#"
4096                 ```rust
4097                 <Option<i32> as Try>::Output
4098                 ```"#]],
4099     );
4100 }
4101
4102 #[test]
4103 fn hover_deref_expr() {
4104     check_hover_range(
4105         r#"
4106 //- minicore: deref
4107 use core::ops::Deref;
4108
4109 struct DerefExample<T> {
4110     value: T
4111 }
4112
4113 impl<T> Deref for DerefExample<T> {
4114     type Target = T;
4115
4116     fn deref(&self) -> &Self::Target {
4117         &self.value
4118     }
4119 }
4120
4121 fn foo() {
4122     let x = DerefExample { value: 0 };
4123     let y: i32 = $0*x$0;
4124 }
4125 "#,
4126         expect![[r#"
4127                 ```text
4128                 Dereferenced from: DerefExample<i32>
4129                 To type:                         i32
4130                 ```
4131             "#]],
4132     );
4133 }
4134
4135 #[test]
4136 fn hover_deref_expr_with_coercion() {
4137     check_hover_range(
4138         r#"
4139 //- minicore: deref
4140 use core::ops::Deref;
4141
4142 struct DerefExample<T> {
4143     value: T
4144 }
4145
4146 impl<T> Deref for DerefExample<T> {
4147     type Target = T;
4148
4149     fn deref(&self) -> &Self::Target {
4150         &self.value
4151     }
4152 }
4153
4154 fn foo() {
4155     let x = DerefExample { value: &&&&&0 };
4156     let y: &i32 = $0*x$0;
4157 }
4158 "#,
4159         expect![[r#"
4160                 ```text
4161                 Dereferenced from: DerefExample<&&&&&i32>
4162                 To type:                         &&&&&i32
4163                 Coerced to:                          &i32
4164                 ```
4165             "#]],
4166     );
4167 }
4168
4169 #[test]
4170 fn hover_intra_in_macro() {
4171     check(
4172         r#"
4173 macro_rules! foo_macro {
4174     ($(#[$attr:meta])* $name:ident) => {
4175         $(#[$attr])*
4176         pub struct $name;
4177     }
4178 }
4179
4180 foo_macro!(
4181     /// Doc comment for [`Foo$0`]
4182     Foo
4183 );
4184 "#,
4185         expect![[r#"
4186             *[`Foo`]*
4187
4188             ```rust
4189             test
4190             ```
4191
4192             ```rust
4193             pub struct Foo
4194             ```
4195
4196             ---
4197
4198             Doc comment for [`Foo`](https://doc.rust-lang.org/nightly/test/struct.Foo.html)
4199         "#]],
4200     );
4201 }
4202
4203 #[test]
4204 fn hover_intra_in_attr() {
4205     check(
4206         r#"
4207 #[doc = "Doc comment for [`Foo$0`]"]
4208 pub struct Foo;
4209 "#,
4210         expect![[r#"
4211             *[`Foo`]*
4212
4213             ```rust
4214             test
4215             ```
4216
4217             ```rust
4218             pub struct Foo
4219             ```
4220
4221             ---
4222
4223             Doc comment for [`Foo`](https://doc.rust-lang.org/nightly/test/struct.Foo.html)
4224         "#]],
4225     );
4226 }