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