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