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