]> git.lizzy.rs Git - rust.git/blob - crates/ide/src/hover/tests.rs
feat: Resolve builtin-attr and tools in ide layer
[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
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     struct Thing { x: u32 }
827
828     impl Thing {
829         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                 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 //- minicore: future
2365 struct S;
2366 fn foo() {
2367     let fo$0o = async { S };
2368 }
2369 "#,
2370         expect![[r#"
2371                 [
2372                     GoToType(
2373                         [
2374                             HoverGotoTypeData {
2375                                 mod_path: "core::future::Future",
2376                                 nav: NavigationTarget {
2377                                     file_id: FileId(
2378                                         1,
2379                                     ),
2380                                     full_range: 276..458,
2381                                     focus_range: 315..321,
2382                                     name: "Future",
2383                                     kind: Trait,
2384                                     description: "pub trait Future",
2385                                 },
2386                             },
2387                             HoverGotoTypeData {
2388                                 mod_path: "test::S",
2389                                 nav: NavigationTarget {
2390                                     file_id: FileId(
2391                                         0,
2392                                     ),
2393                                     full_range: 0..9,
2394                                     focus_range: 7..8,
2395                                     name: "S",
2396                                     kind: Struct,
2397                                     description: "struct S",
2398                                 },
2399                             },
2400                         ],
2401                     ),
2402                 ]
2403             "#]],
2404     );
2405 }
2406
2407 #[test]
2408 fn test_hover_arg_generic_impl_trait_has_goto_type_action() {
2409     check_actions(
2410         r#"
2411 trait Foo<T> {}
2412 struct S {}
2413 fn foo(ar$0g: &impl Foo<S>) {}
2414 "#,
2415         expect![[r#"
2416                 [
2417                     GoToType(
2418                         [
2419                             HoverGotoTypeData {
2420                                 mod_path: "test::Foo",
2421                                 nav: NavigationTarget {
2422                                     file_id: FileId(
2423                                         0,
2424                                     ),
2425                                     full_range: 0..15,
2426                                     focus_range: 6..9,
2427                                     name: "Foo",
2428                                     kind: Trait,
2429                                     description: "trait Foo<T>",
2430                                 },
2431                             },
2432                             HoverGotoTypeData {
2433                                 mod_path: "test::S",
2434                                 nav: NavigationTarget {
2435                                     file_id: FileId(
2436                                         0,
2437                                     ),
2438                                     full_range: 16..27,
2439                                     focus_range: 23..24,
2440                                     name: "S",
2441                                     kind: Struct,
2442                                     description: "struct S",
2443                                 },
2444                             },
2445                         ],
2446                     ),
2447                 ]
2448             "#]],
2449     );
2450 }
2451
2452 #[test]
2453 fn test_hover_dyn_return_has_goto_type_action() {
2454     check_actions(
2455         r#"
2456 trait Foo {}
2457 struct S;
2458 impl Foo for S {}
2459
2460 struct B<T>{}
2461 fn foo() -> B<dyn Foo> {}
2462
2463 fn main() { let s$0t = foo(); }
2464 "#,
2465         expect![[r#"
2466                 [
2467                     GoToType(
2468                         [
2469                             HoverGotoTypeData {
2470                                 mod_path: "test::B",
2471                                 nav: NavigationTarget {
2472                                     file_id: FileId(
2473                                         0,
2474                                     ),
2475                                     full_range: 42..55,
2476                                     focus_range: 49..50,
2477                                     name: "B",
2478                                     kind: Struct,
2479                                     description: "struct B<T>",
2480                                 },
2481                             },
2482                             HoverGotoTypeData {
2483                                 mod_path: "test::Foo",
2484                                 nav: NavigationTarget {
2485                                     file_id: FileId(
2486                                         0,
2487                                     ),
2488                                     full_range: 0..12,
2489                                     focus_range: 6..9,
2490                                     name: "Foo",
2491                                     kind: Trait,
2492                                     description: "trait Foo",
2493                                 },
2494                             },
2495                         ],
2496                     ),
2497                 ]
2498             "#]],
2499     );
2500 }
2501
2502 #[test]
2503 fn test_hover_dyn_arg_has_goto_type_action() {
2504     check_actions(
2505         r#"
2506 trait Foo {}
2507 fn foo(ar$0g: &dyn Foo) {}
2508 "#,
2509         expect![[r#"
2510                 [
2511                     GoToType(
2512                         [
2513                             HoverGotoTypeData {
2514                                 mod_path: "test::Foo",
2515                                 nav: NavigationTarget {
2516                                     file_id: FileId(
2517                                         0,
2518                                     ),
2519                                     full_range: 0..12,
2520                                     focus_range: 6..9,
2521                                     name: "Foo",
2522                                     kind: Trait,
2523                                     description: "trait Foo",
2524                                 },
2525                             },
2526                         ],
2527                     ),
2528                 ]
2529             "#]],
2530     );
2531 }
2532
2533 #[test]
2534 fn test_hover_generic_dyn_arg_has_goto_type_action() {
2535     check_actions(
2536         r#"
2537 trait Foo<T> {}
2538 struct S {}
2539 fn foo(ar$0g: &dyn Foo<S>) {}
2540 "#,
2541         expect![[r#"
2542                 [
2543                     GoToType(
2544                         [
2545                             HoverGotoTypeData {
2546                                 mod_path: "test::Foo",
2547                                 nav: NavigationTarget {
2548                                     file_id: FileId(
2549                                         0,
2550                                     ),
2551                                     full_range: 0..15,
2552                                     focus_range: 6..9,
2553                                     name: "Foo",
2554                                     kind: Trait,
2555                                     description: "trait Foo<T>",
2556                                 },
2557                             },
2558                             HoverGotoTypeData {
2559                                 mod_path: "test::S",
2560                                 nav: NavigationTarget {
2561                                     file_id: FileId(
2562                                         0,
2563                                     ),
2564                                     full_range: 16..27,
2565                                     focus_range: 23..24,
2566                                     name: "S",
2567                                     kind: Struct,
2568                                     description: "struct S",
2569                                 },
2570                             },
2571                         ],
2572                     ),
2573                 ]
2574             "#]],
2575     );
2576 }
2577
2578 #[test]
2579 fn test_hover_goto_type_action_links_order() {
2580     check_actions(
2581         r#"
2582 trait ImplTrait<T> {}
2583 trait DynTrait<T> {}
2584 struct B<T> {}
2585 struct S {}
2586
2587 fn foo(a$0rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
2588 "#,
2589         expect![[r#"
2590                 [
2591                     GoToType(
2592                         [
2593                             HoverGotoTypeData {
2594                                 mod_path: "test::ImplTrait",
2595                                 nav: NavigationTarget {
2596                                     file_id: FileId(
2597                                         0,
2598                                     ),
2599                                     full_range: 0..21,
2600                                     focus_range: 6..15,
2601                                     name: "ImplTrait",
2602                                     kind: Trait,
2603                                     description: "trait ImplTrait<T>",
2604                                 },
2605                             },
2606                             HoverGotoTypeData {
2607                                 mod_path: "test::B",
2608                                 nav: NavigationTarget {
2609                                     file_id: FileId(
2610                                         0,
2611                                     ),
2612                                     full_range: 43..57,
2613                                     focus_range: 50..51,
2614                                     name: "B",
2615                                     kind: Struct,
2616                                     description: "struct B<T>",
2617                                 },
2618                             },
2619                             HoverGotoTypeData {
2620                                 mod_path: "test::DynTrait",
2621                                 nav: NavigationTarget {
2622                                     file_id: FileId(
2623                                         0,
2624                                     ),
2625                                     full_range: 22..42,
2626                                     focus_range: 28..36,
2627                                     name: "DynTrait",
2628                                     kind: Trait,
2629                                     description: "trait DynTrait<T>",
2630                                 },
2631                             },
2632                             HoverGotoTypeData {
2633                                 mod_path: "test::S",
2634                                 nav: NavigationTarget {
2635                                     file_id: FileId(
2636                                         0,
2637                                     ),
2638                                     full_range: 58..69,
2639                                     focus_range: 65..66,
2640                                     name: "S",
2641                                     kind: Struct,
2642                                     description: "struct S",
2643                                 },
2644                             },
2645                         ],
2646                     ),
2647                 ]
2648             "#]],
2649     );
2650 }
2651
2652 #[test]
2653 fn test_hover_associated_type_has_goto_type_action() {
2654     check_actions(
2655         r#"
2656 trait Foo {
2657     type Item;
2658     fn get(self) -> Self::Item {}
2659 }
2660
2661 struct Bar{}
2662 struct S{}
2663
2664 impl Foo for S { type Item = Bar; }
2665
2666 fn test() -> impl Foo { S {} }
2667
2668 fn main() { let s$0t = test().get(); }
2669 "#,
2670         expect![[r#"
2671                 [
2672                     GoToType(
2673                         [
2674                             HoverGotoTypeData {
2675                                 mod_path: "test::Foo",
2676                                 nav: NavigationTarget {
2677                                     file_id: FileId(
2678                                         0,
2679                                     ),
2680                                     full_range: 0..62,
2681                                     focus_range: 6..9,
2682                                     name: "Foo",
2683                                     kind: Trait,
2684                                     description: "trait Foo",
2685                                 },
2686                             },
2687                         ],
2688                     ),
2689                 ]
2690             "#]],
2691     );
2692 }
2693
2694 #[test]
2695 fn test_hover_const_param_has_goto_type_action() {
2696     check_actions(
2697         r#"
2698 struct Bar;
2699 struct Foo<const BAR: Bar>;
2700
2701 impl<const BAR: Bar> Foo<BAR$0> {}
2702 "#,
2703         expect![[r#"
2704                 [
2705                     GoToType(
2706                         [
2707                             HoverGotoTypeData {
2708                                 mod_path: "test::Bar",
2709                                 nav: NavigationTarget {
2710                                     file_id: FileId(
2711                                         0,
2712                                     ),
2713                                     full_range: 0..11,
2714                                     focus_range: 7..10,
2715                                     name: "Bar",
2716                                     kind: Struct,
2717                                     description: "struct Bar",
2718                                 },
2719                             },
2720                         ],
2721                     ),
2722                 ]
2723             "#]],
2724     );
2725 }
2726
2727 #[test]
2728 fn test_hover_type_param_has_goto_type_action() {
2729     check_actions(
2730         r#"
2731 trait Foo {}
2732
2733 fn foo<T: Foo>(t: T$0){}
2734 "#,
2735         expect![[r#"
2736                 [
2737                     GoToType(
2738                         [
2739                             HoverGotoTypeData {
2740                                 mod_path: "test::Foo",
2741                                 nav: NavigationTarget {
2742                                     file_id: FileId(
2743                                         0,
2744                                     ),
2745                                     full_range: 0..12,
2746                                     focus_range: 6..9,
2747                                     name: "Foo",
2748                                     kind: Trait,
2749                                     description: "trait Foo",
2750                                 },
2751                             },
2752                         ],
2753                     ),
2754                 ]
2755             "#]],
2756     );
2757 }
2758
2759 #[test]
2760 fn test_hover_self_has_go_to_type() {
2761     check_actions(
2762         r#"
2763 struct Foo;
2764 impl Foo {
2765     fn foo(&self$0) {}
2766 }
2767 "#,
2768         expect![[r#"
2769                 [
2770                     GoToType(
2771                         [
2772                             HoverGotoTypeData {
2773                                 mod_path: "test::Foo",
2774                                 nav: NavigationTarget {
2775                                     file_id: FileId(
2776                                         0,
2777                                     ),
2778                                     full_range: 0..11,
2779                                     focus_range: 7..10,
2780                                     name: "Foo",
2781                                     kind: Struct,
2782                                     description: "struct Foo",
2783                                 },
2784                             },
2785                         ],
2786                     ),
2787                 ]
2788             "#]],
2789     );
2790 }
2791
2792 #[test]
2793 fn hover_displays_normalized_crate_names() {
2794     check(
2795         r#"
2796 //- /lib.rs crate:name-with-dashes
2797 pub mod wrapper {
2798     pub struct Thing { x: u32 }
2799
2800     impl Thing {
2801         pub fn new() -> Thing { Thing { x: 0 } }
2802     }
2803 }
2804
2805 //- /main.rs crate:main deps:name-with-dashes
2806 fn main() { let foo_test = name_with_dashes::wrapper::Thing::new$0(); }
2807 "#,
2808         expect![[r#"
2809             *new*
2810
2811             ```rust
2812             name_with_dashes::wrapper::Thing
2813             ```
2814
2815             ```rust
2816             pub fn new() -> Thing
2817             ```
2818             "#]],
2819     )
2820 }
2821
2822 #[test]
2823 fn hover_field_pat_shorthand_ref_match_ergonomics() {
2824     check(
2825         r#"
2826 struct S {
2827     f: i32,
2828 }
2829
2830 fn main() {
2831     let s = S { f: 0 };
2832     let S { f$0 } = &s;
2833 }
2834 "#,
2835         expect![[r#"
2836             *f*
2837
2838             ```rust
2839             f: &i32
2840             ```
2841             ---
2842
2843             ```rust
2844             test::S
2845             ```
2846
2847             ```rust
2848             f: i32
2849             ```
2850         "#]],
2851     );
2852 }
2853
2854 #[test]
2855 fn hover_self_param_shows_type() {
2856     check(
2857         r#"
2858 struct Foo {}
2859 impl Foo {
2860     fn bar(&sel$0f) {}
2861 }
2862 "#,
2863         expect![[r#"
2864                 *self*
2865
2866                 ```rust
2867                 self: &Foo
2868                 ```
2869             "#]],
2870     );
2871 }
2872
2873 #[test]
2874 fn hover_self_param_shows_type_for_arbitrary_self_type() {
2875     check(
2876         r#"
2877 struct Arc<T>(T);
2878 struct Foo {}
2879 impl Foo {
2880     fn bar(sel$0f: Arc<Foo>) {}
2881 }
2882 "#,
2883         expect![[r#"
2884                 *self*
2885
2886                 ```rust
2887                 self: Arc<Foo>
2888                 ```
2889             "#]],
2890     );
2891 }
2892
2893 #[test]
2894 fn hover_doc_outer_inner() {
2895     check(
2896         r#"
2897 /// Be quick;
2898 mod Foo$0 {
2899     //! time is mana
2900
2901     /// This comment belongs to the function
2902     fn foo() {}
2903 }
2904 "#,
2905         expect![[r#"
2906                 *Foo*
2907
2908                 ```rust
2909                 test
2910                 ```
2911
2912                 ```rust
2913                 mod Foo
2914                 ```
2915
2916                 ---
2917
2918                 Be quick;
2919                 time is mana
2920             "#]],
2921     );
2922 }
2923
2924 #[test]
2925 fn hover_doc_outer_inner_attribue() {
2926     check(
2927         r#"
2928 #[doc = "Be quick;"]
2929 mod Foo$0 {
2930     #![doc = "time is mana"]
2931
2932     #[doc = "This comment belongs to the function"]
2933     fn foo() {}
2934 }
2935 "#,
2936         expect![[r#"
2937                 *Foo*
2938
2939                 ```rust
2940                 test
2941                 ```
2942
2943                 ```rust
2944                 mod Foo
2945                 ```
2946
2947                 ---
2948
2949                 Be quick;
2950                 time is mana
2951             "#]],
2952     );
2953 }
2954
2955 #[test]
2956 fn hover_doc_block_style_indentend() {
2957     check(
2958         r#"
2959 /**
2960     foo
2961     ```rust
2962     let x = 3;
2963     ```
2964 */
2965 fn foo$0() {}
2966 "#,
2967         expect![[r#"
2968                 *foo*
2969
2970                 ```rust
2971                 test
2972                 ```
2973
2974                 ```rust
2975                 fn foo()
2976                 ```
2977
2978                 ---
2979
2980                 foo
2981
2982                 ```rust
2983                 let x = 3;
2984                 ```
2985             "#]],
2986     );
2987 }
2988
2989 #[test]
2990 fn hover_comments_dont_highlight_parent() {
2991     cov_mark::check!(no_highlight_on_comment_hover);
2992     check_hover_no_result(
2993         r#"
2994 fn no_hover() {
2995     // no$0hover
2996 }
2997 "#,
2998     );
2999 }
3000
3001 #[test]
3002 fn hover_label() {
3003     check(
3004         r#"
3005 fn foo() {
3006     'label$0: loop {}
3007 }
3008 "#,
3009         expect![[r#"
3010             *'label*
3011
3012             ```rust
3013             'label
3014             ```
3015             "#]],
3016     );
3017 }
3018
3019 #[test]
3020 fn hover_lifetime() {
3021     check(
3022         r#"fn foo<'lifetime>(_: &'lifetime$0 ()) {}"#,
3023         expect![[r#"
3024             *'lifetime*
3025
3026             ```rust
3027             'lifetime
3028             ```
3029             "#]],
3030     );
3031 }
3032
3033 #[test]
3034 fn hover_type_param() {
3035     check(
3036         r#"
3037 //- minicore: sized
3038 struct Foo<T>(T);
3039 trait TraitA {}
3040 trait TraitB {}
3041 impl<T: TraitA + TraitB> Foo<T$0> where T: Sized {}
3042 "#,
3043         expect![[r#"
3044                 *T*
3045
3046                 ```rust
3047                 T: TraitA + TraitB
3048                 ```
3049             "#]],
3050     );
3051     check(
3052         r#"
3053 //- minicore: sized
3054 struct Foo<T>(T);
3055 impl<T> Foo<T$0> {}
3056 "#,
3057         expect![[r#"
3058                 *T*
3059
3060                 ```rust
3061                 T
3062                 ```
3063                 "#]],
3064     );
3065     // lifetimes bounds arent being tracked yet
3066     check(
3067         r#"
3068 //- minicore: sized
3069 struct Foo<T>(T);
3070 impl<T: 'static> Foo<T$0> {}
3071 "#,
3072         expect![[r#"
3073                 *T*
3074
3075                 ```rust
3076                 T
3077                 ```
3078                 "#]],
3079     );
3080 }
3081
3082 #[test]
3083 fn hover_type_param_sized_bounds() {
3084     // implicit `: Sized` bound
3085     check(
3086         r#"
3087 //- minicore: sized
3088 trait Trait {}
3089 struct Foo<T>(T);
3090 impl<T: Trait> Foo<T$0> {}
3091 "#,
3092         expect![[r#"
3093                 *T*
3094
3095                 ```rust
3096                 T: Trait
3097                 ```
3098             "#]],
3099     );
3100     check(
3101         r#"
3102 //- minicore: sized
3103 trait Trait {}
3104 struct Foo<T>(T);
3105 impl<T: Trait + ?Sized> Foo<T$0> {}
3106 "#,
3107         expect![[r#"
3108                 *T*
3109
3110                 ```rust
3111                 T: Trait + ?Sized
3112                 ```
3113             "#]],
3114     );
3115 }
3116
3117 mod type_param_sized_bounds {
3118     use super::*;
3119
3120     #[test]
3121     fn single_implicit() {
3122         check(
3123             r#"
3124 //- minicore: sized
3125 fn foo<T$0>() {}
3126 "#,
3127             expect![[r#"
3128                     *T*
3129
3130                     ```rust
3131                     T
3132                     ```
3133                 "#]],
3134         );
3135     }
3136
3137     #[test]
3138     fn single_explicit() {
3139         check(
3140             r#"
3141 //- minicore: sized
3142 fn foo<T$0: Sized>() {}
3143 "#,
3144             expect![[r#"
3145                     *T*
3146
3147                     ```rust
3148                     T
3149                     ```
3150                 "#]],
3151         );
3152     }
3153
3154     #[test]
3155     fn single_relaxed() {
3156         check(
3157             r#"
3158 //- minicore: sized
3159 fn foo<T$0: ?Sized>() {}
3160 "#,
3161             expect![[r#"
3162                     *T*
3163
3164                     ```rust
3165                     T: ?Sized
3166                     ```
3167                 "#]],
3168         );
3169     }
3170
3171     #[test]
3172     fn multiple_implicit() {
3173         check(
3174             r#"
3175 //- minicore: sized
3176 trait Trait {}
3177 fn foo<T$0: Trait>() {}
3178 "#,
3179             expect![[r#"
3180                     *T*
3181
3182                     ```rust
3183                     T: Trait
3184                     ```
3185                 "#]],
3186         );
3187     }
3188
3189     #[test]
3190     fn multiple_explicit() {
3191         check(
3192             r#"
3193 //- minicore: sized
3194 trait Trait {}
3195 fn foo<T$0: Trait + Sized>() {}
3196 "#,
3197             expect![[r#"
3198                     *T*
3199
3200                     ```rust
3201                     T: Trait
3202                     ```
3203                 "#]],
3204         );
3205     }
3206
3207     #[test]
3208     fn multiple_relaxed() {
3209         check(
3210             r#"
3211 //- minicore: sized
3212 trait Trait {}
3213 fn foo<T$0: Trait + ?Sized>() {}
3214 "#,
3215             expect![[r#"
3216                     *T*
3217
3218                     ```rust
3219                     T: Trait + ?Sized
3220                     ```
3221                 "#]],
3222         );
3223     }
3224
3225     #[test]
3226     fn mixed() {
3227         check(
3228             r#"
3229 //- minicore: sized
3230 fn foo<T$0: ?Sized + Sized + Sized>() {}
3231 "#,
3232             expect![[r#"
3233                     *T*
3234
3235                     ```rust
3236                     T
3237                     ```
3238                 "#]],
3239         );
3240         check(
3241             r#"
3242 //- minicore: sized
3243 trait Trait {}
3244 fn foo<T$0: Sized + ?Sized + Sized + Trait>() {}
3245 "#,
3246             expect![[r#"
3247                     *T*
3248
3249                     ```rust
3250                     T: Trait
3251                     ```
3252                 "#]],
3253         );
3254     }
3255 }
3256
3257 #[test]
3258 fn hover_const_param() {
3259     check(
3260         r#"
3261 struct Foo<const LEN: usize>;
3262 impl<const LEN: usize> Foo<LEN$0> {}
3263 "#,
3264         expect![[r#"
3265                 *LEN*
3266
3267                 ```rust
3268                 const LEN: usize
3269                 ```
3270             "#]],
3271     );
3272 }
3273
3274 #[test]
3275 fn hover_const_pat() {
3276     check(
3277         r#"
3278 /// This is a doc
3279 const FOO: usize = 3;
3280 fn foo() {
3281     match 5 {
3282         FOO$0 => (),
3283         _ => ()
3284     }
3285 }
3286 "#,
3287         expect![[r#"
3288             *FOO*
3289
3290             ```rust
3291             test
3292             ```
3293
3294             ```rust
3295             const FOO: usize = 3
3296             ```
3297
3298             ---
3299
3300             This is a doc
3301         "#]],
3302     );
3303 }
3304
3305 #[test]
3306 fn hover_mod_def() {
3307     check(
3308         r#"
3309 //- /main.rs
3310 mod foo$0;
3311 //- /foo.rs
3312 //! For the horde!
3313 "#,
3314         expect![[r#"
3315                 *foo*
3316
3317                 ```rust
3318                 test
3319                 ```
3320
3321                 ```rust
3322                 mod foo
3323                 ```
3324
3325                 ---
3326
3327                 For the horde!
3328             "#]],
3329     );
3330 }
3331
3332 #[test]
3333 fn hover_self_in_use() {
3334     check(
3335         r#"
3336 //! This should not appear
3337 mod foo {
3338     /// But this should appear
3339     pub mod bar {}
3340 }
3341 use foo::bar::{self$0};
3342 "#,
3343         expect![[r#"
3344                 *self*
3345
3346                 ```rust
3347                 test::foo
3348                 ```
3349
3350                 ```rust
3351                 mod bar
3352                 ```
3353
3354                 ---
3355
3356                 But this should appear
3357             "#]],
3358     )
3359 }
3360
3361 #[test]
3362 fn hover_keyword() {
3363     check(
3364         r#"
3365 //- /main.rs crate:main deps:std
3366 fn f() { retur$0n; }
3367 //- /libstd.rs crate:std
3368 /// Docs for return_keyword
3369 mod return_keyword {}
3370 "#,
3371         expect![[r#"
3372                 *return*
3373
3374                 ```rust
3375                 return
3376                 ```
3377
3378                 ---
3379
3380                 Docs for return_keyword
3381             "#]],
3382     );
3383 }
3384
3385 #[test]
3386 fn hover_builtin() {
3387     check(
3388         r#"
3389 //- /main.rs crate:main deps:std
3390 cosnt _: &str$0 = ""; }
3391
3392 //- /libstd.rs crate:std
3393 /// Docs for prim_str
3394 mod prim_str {}
3395 "#,
3396         expect![[r#"
3397                 *str*
3398
3399                 ```rust
3400                 str
3401                 ```
3402
3403                 ---
3404
3405                 Docs for prim_str
3406             "#]],
3407     );
3408 }
3409
3410 #[test]
3411 fn hover_macro_expanded_function() {
3412     check(
3413         r#"
3414 struct S<'a, T>(&'a T);
3415 trait Clone {}
3416 macro_rules! foo {
3417     () => {
3418         fn bar<'t, T: Clone + 't>(s: &mut S<'t, T>, t: u32) -> *mut u32 where
3419             't: 't + 't,
3420             for<'a> T: Clone + 'a
3421         { 0 as _ }
3422     };
3423 }
3424
3425 foo!();
3426
3427 fn main() {
3428     bar$0;
3429 }
3430 "#,
3431         expect![[r#"
3432                 *bar*
3433
3434                 ```rust
3435                 test
3436                 ```
3437
3438                 ```rust
3439                 fn bar<'t, T>(s: &mut S<'t, T>, t: u32) -> *mut u32
3440                 where
3441                     T: Clone + 't,
3442                     't: 't + 't,
3443                     for<'a> T: Clone + 'a,
3444                 ```
3445             "#]],
3446     )
3447 }
3448
3449 #[test]
3450 fn hover_intra_doc_links() {
3451     check(
3452         r#"
3453
3454 pub mod theitem {
3455     /// This is the item. Cool!
3456     pub struct TheItem;
3457 }
3458
3459 /// Gives you a [`TheItem$0`].
3460 ///
3461 /// [`TheItem`]: theitem::TheItem
3462 pub fn gimme() -> theitem::TheItem {
3463     theitem::TheItem
3464 }
3465 "#,
3466         expect![[r#"
3467                 *[`TheItem`]*
3468
3469                 ```rust
3470                 test::theitem
3471                 ```
3472
3473                 ```rust
3474                 pub struct TheItem
3475                 ```
3476
3477                 ---
3478
3479                 This is the item. Cool!
3480             "#]],
3481     );
3482 }
3483
3484 #[test]
3485 fn hover_generic_assoc() {
3486     check(
3487         r#"
3488 fn foo<T: A>() where T::Assoc$0: {}
3489
3490 trait A {
3491     type Assoc;
3492 }"#,
3493         expect![[r#"
3494                 *Assoc*
3495
3496                 ```rust
3497                 test
3498                 ```
3499
3500                 ```rust
3501                 type Assoc
3502                 ```
3503             "#]],
3504     );
3505     check(
3506         r#"
3507 fn foo<T: A>() {
3508     let _: <T>::Assoc$0;
3509 }
3510
3511 trait A {
3512     type Assoc;
3513 }"#,
3514         expect![[r#"
3515                 *Assoc*
3516
3517                 ```rust
3518                 test
3519                 ```
3520
3521                 ```rust
3522                 type Assoc
3523                 ```
3524             "#]],
3525     );
3526     check(
3527         r#"
3528 trait A where
3529     Self::Assoc$0: ,
3530 {
3531     type Assoc;
3532 }"#,
3533         expect![[r#"
3534                 *Assoc*
3535
3536                 ```rust
3537                 test
3538                 ```
3539
3540                 ```rust
3541                 type Assoc
3542                 ```
3543             "#]],
3544     );
3545 }
3546
3547 #[test]
3548 fn string_shadowed_with_inner_items() {
3549     check(
3550         r#"
3551 //- /main.rs crate:main deps:alloc
3552
3553 /// Custom `String` type.
3554 struct String;
3555
3556 fn f() {
3557     let _: String$0;
3558
3559     fn inner() {}
3560 }
3561
3562 //- /alloc.rs crate:alloc
3563 #[prelude_import]
3564 pub use string::*;
3565
3566 mod string {
3567     /// This is `alloc::String`.
3568     pub struct String;
3569 }
3570 "#,
3571         expect![[r#"
3572                 *String*
3573
3574                 ```rust
3575                 main
3576                 ```
3577
3578                 ```rust
3579                 struct String
3580                 ```
3581
3582                 ---
3583
3584                 Custom `String` type.
3585             "#]],
3586     )
3587 }
3588
3589 #[test]
3590 fn function_doesnt_shadow_crate_in_use_tree() {
3591     check(
3592         r#"
3593 //- /main.rs crate:main deps:foo
3594 use foo$0::{foo};
3595
3596 //- /foo.rs crate:foo
3597 pub fn foo() {}
3598 "#,
3599         expect![[r#"
3600                 *foo*
3601
3602                 ```rust
3603                 extern crate foo
3604                 ```
3605             "#]],
3606     )
3607 }
3608
3609 #[test]
3610 fn hover_feature() {
3611     check(
3612         r#"#![feature(box_syntax$0)]"#,
3613         expect![[r##"
3614                 *box_syntax*
3615                 ```
3616                 box_syntax
3617                 ```
3618                 ___
3619
3620                 # `box_syntax`
3621
3622                 The tracking issue for this feature is: [#49733]
3623
3624                 [#49733]: https://github.com/rust-lang/rust/issues/49733
3625
3626                 See also [`box_patterns`](box-patterns.md)
3627
3628                 ------------------------
3629
3630                 Currently the only stable way to create a `Box` is via the `Box::new` method.
3631                 Also it is not possible in stable Rust to destructure a `Box` in a match
3632                 pattern. The unstable `box` keyword can be used to create a `Box`. An example
3633                 usage would be:
3634
3635                 ```rust
3636                 #![feature(box_syntax)]
3637
3638                 fn main() {
3639                     let b = box 5;
3640                 }
3641                 ```
3642
3643             "##]],
3644     )
3645 }
3646
3647 #[test]
3648 fn hover_lint() {
3649     check(
3650         r#"#![allow(arithmetic_overflow$0)]"#,
3651         expect![[r#"
3652                 *arithmetic_overflow*
3653                 ```
3654                 arithmetic_overflow
3655                 ```
3656                 ___
3657
3658                 arithmetic operation overflows
3659             "#]],
3660     )
3661 }
3662
3663 #[test]
3664 fn hover_clippy_lint() {
3665     check(
3666         r#"#![allow(clippy::almost_swapped$0)]"#,
3667         expect![[r#"
3668                 *almost_swapped*
3669                 ```
3670                 clippy::almost_swapped
3671                 ```
3672                 ___
3673
3674                 Checks for `foo = bar; bar = foo` sequences.
3675             "#]],
3676     )
3677 }
3678
3679 #[test]
3680 fn hover_attr_path_qualifier() {
3681     check(
3682         r#"
3683 //- /foo.rs crate:foo
3684
3685 //- /lib.rs crate:main.rs deps:foo
3686 #[fo$0o::bar()]
3687 struct Foo;
3688 "#,
3689         expect![[r#"
3690                 *foo*
3691
3692                 ```rust
3693                 extern crate foo
3694                 ```
3695             "#]],
3696     )
3697 }
3698
3699 #[test]
3700 fn hover_rename() {
3701     check(
3702         r#"
3703 use self as foo$0;
3704 "#,
3705         expect![[r#"
3706                 *foo*
3707
3708                 ```rust
3709                 extern crate test
3710                 ```
3711             "#]],
3712     );
3713     check(
3714         r#"
3715 mod bar {}
3716 use bar::{self as foo$0};
3717 "#,
3718         expect![[r#"
3719                 *foo*
3720
3721                 ```rust
3722                 test
3723                 ```
3724
3725                 ```rust
3726                 mod bar
3727                 ```
3728             "#]],
3729     );
3730     check(
3731         r#"
3732 mod bar {
3733     use super as foo$0;
3734 }
3735 "#,
3736         expect![[r#"
3737                 *foo*
3738
3739                 ```rust
3740                 extern crate test
3741                 ```
3742             "#]],
3743     );
3744     check(
3745         r#"
3746 use crate as foo$0;
3747 "#,
3748         expect![[r#"
3749                 *foo*
3750
3751                 ```rust
3752                 extern crate test
3753                 ```
3754             "#]],
3755     );
3756 }
3757
3758 #[test]
3759 fn hover_attribute_in_macro() {
3760     check(
3761         r#"
3762 //- minicore:derive
3763 macro_rules! identity {
3764     ($struct:item) => {
3765         $struct
3766     };
3767 }
3768 #[rustc_builtin_macro]
3769 pub macro Copy {}
3770 identity!{
3771     #[derive(Copy$0)]
3772     struct Foo;
3773 }
3774 "#,
3775         expect![[r#"
3776                 *Copy*
3777
3778                 ```rust
3779                 test
3780                 ```
3781
3782                 ```rust
3783                 pub macro Copy
3784                 ```
3785             "#]],
3786     );
3787 }
3788
3789 #[test]
3790 fn hover_derive_input() {
3791     check(
3792         r#"
3793 //- minicore:derive
3794 #[rustc_builtin_macro]
3795 pub macro Copy {}
3796 #[derive(Copy$0)]
3797 struct Foo;
3798 "#,
3799         expect![[r#"
3800                 *Copy*
3801
3802                 ```rust
3803                 test
3804                 ```
3805
3806                 ```rust
3807                 pub macro Copy
3808                 ```
3809             "#]],
3810     );
3811     check(
3812         r#"
3813 //- minicore:derive
3814 mod foo {
3815     #[rustc_builtin_macro]
3816     pub macro Copy {}
3817 }
3818 #[derive(foo::Copy$0)]
3819 struct Foo;
3820 "#,
3821         expect![[r#"
3822                 *Copy*
3823
3824                 ```rust
3825                 test
3826                 ```
3827
3828                 ```rust
3829                 pub macro Copy
3830                 ```
3831             "#]],
3832     );
3833 }
3834
3835 #[test]
3836 fn hover_range_math() {
3837     check_hover_range(
3838         r#"
3839 fn f() { let expr = $01 + 2 * 3$0 }
3840 "#,
3841         expect![[r#"
3842             ```rust
3843             i32
3844             ```"#]],
3845     );
3846
3847     check_hover_range(
3848         r#"
3849 fn f() { let expr = 1 $0+ 2 * $03 }
3850 "#,
3851         expect![[r#"
3852             ```rust
3853             i32
3854             ```"#]],
3855     );
3856
3857     check_hover_range(
3858         r#"
3859 fn f() { let expr = 1 + $02 * 3$0 }
3860 "#,
3861         expect![[r#"
3862             ```rust
3863             i32
3864             ```"#]],
3865     );
3866 }
3867
3868 #[test]
3869 fn hover_range_arrays() {
3870     check_hover_range(
3871         r#"
3872 fn f() { let expr = $0[1, 2, 3, 4]$0 }
3873 "#,
3874         expect![[r#"
3875             ```rust
3876             [i32; 4]
3877             ```"#]],
3878     );
3879
3880     check_hover_range(
3881         r#"
3882 fn f() { let expr = [1, 2, $03, 4]$0 }
3883 "#,
3884         expect![[r#"
3885             ```rust
3886             [i32; 4]
3887             ```"#]],
3888     );
3889
3890     check_hover_range(
3891         r#"
3892 fn f() { let expr = [1, 2, $03$0, 4] }
3893 "#,
3894         expect![[r#"
3895             ```rust
3896             i32
3897             ```"#]],
3898     );
3899 }
3900
3901 #[test]
3902 fn hover_range_functions() {
3903     check_hover_range(
3904         r#"
3905 fn f<T>(a: &[T]) { }
3906 fn b() { $0f$0(&[1, 2, 3, 4, 5]); }
3907 "#,
3908         expect![[r#"
3909             ```rust
3910             fn f<i32>(&[i32])
3911             ```"#]],
3912     );
3913
3914     check_hover_range(
3915         r#"
3916 fn f<T>(a: &[T]) { }
3917 fn b() { f($0&[1, 2, 3, 4, 5]$0); }
3918 "#,
3919         expect![[r#"
3920             ```rust
3921             &[i32; 5]
3922             ```"#]],
3923     );
3924 }
3925
3926 #[test]
3927 fn hover_range_shows_nothing_when_invalid() {
3928     check_hover_range_no_results(
3929         r#"
3930 fn f<T>(a: &[T]) { }
3931 fn b()$0 { f(&[1, 2, 3, 4, 5]); }$0
3932 "#,
3933     );
3934
3935     check_hover_range_no_results(
3936         r#"
3937 fn f<T>$0(a: &[T]) { }
3938 fn b() { f(&[1, 2, 3,$0 4, 5]); }
3939 "#,
3940     );
3941
3942     check_hover_range_no_results(
3943         r#"
3944 fn $0f() { let expr = [1, 2, 3, 4]$0 }
3945 "#,
3946     );
3947 }
3948
3949 #[test]
3950 fn hover_range_shows_unit_for_statements() {
3951     check_hover_range(
3952         r#"
3953 fn f<T>(a: &[T]) { }
3954 fn b() { $0f(&[1, 2, 3, 4, 5]); }$0
3955 "#,
3956         expect![[r#"
3957             ```rust
3958             ()
3959             ```"#]],
3960     );
3961
3962     check_hover_range(
3963         r#"
3964 fn f() { let expr$0 = $0[1, 2, 3, 4] }
3965 "#,
3966         expect![[r#"
3967             ```rust
3968             ()
3969             ```"#]],
3970     );
3971 }
3972
3973 #[test]
3974 fn hover_range_for_pat() {
3975     check_hover_range(
3976         r#"
3977 fn foo() {
3978     let $0x$0 = 0;
3979 }
3980 "#,
3981         expect![[r#"
3982                 ```rust
3983                 i32
3984                 ```"#]],
3985     );
3986
3987     check_hover_range(
3988         r#"
3989 fn foo() {
3990     let $0x$0 = "";
3991 }
3992 "#,
3993         expect![[r#"
3994                 ```rust
3995                 &str
3996                 ```"#]],
3997     );
3998 }
3999
4000 #[test]
4001 fn hover_range_shows_coercions_if_applicable_expr() {
4002     check_hover_range(
4003         r#"
4004 fn foo() {
4005     let x: &u32 = $0&&&&&0$0;
4006 }
4007 "#,
4008         expect![[r#"
4009                 ```text
4010                 Type:       &&&&&u32
4011                 Coerced to:     &u32
4012                 ```
4013             "#]],
4014     );
4015     check_hover_range(
4016         r#"
4017 fn foo() {
4018     let x: *const u32 = $0&0$0;
4019 }
4020 "#,
4021         expect![[r#"
4022                 ```text
4023                 Type:             &u32
4024                 Coerced to: *const u32
4025                 ```
4026             "#]],
4027     );
4028 }
4029
4030 #[test]
4031 fn hover_range_shows_type_actions() {
4032     check_actions(
4033         r#"
4034 struct Foo;
4035 fn foo() {
4036     let x: &Foo = $0&&&&&Foo$0;
4037 }
4038 "#,
4039         expect![[r#"
4040                 [
4041                     GoToType(
4042                         [
4043                             HoverGotoTypeData {
4044                                 mod_path: "test::Foo",
4045                                 nav: NavigationTarget {
4046                                     file_id: FileId(
4047                                         0,
4048                                     ),
4049                                     full_range: 0..11,
4050                                     focus_range: 7..10,
4051                                     name: "Foo",
4052                                     kind: Struct,
4053                                     description: "struct Foo",
4054                                 },
4055                             },
4056                         ],
4057                     ),
4058                 ]
4059             "#]],
4060     );
4061 }
4062
4063 #[test]
4064 fn hover_try_expr_res() {
4065     check_hover_range(
4066         r#"
4067 //- minicore:result
4068 struct FooError;
4069
4070 fn foo() -> Result<(), FooError> {
4071     Ok($0Result::<(), FooError>::Ok(())?$0)
4072 }
4073 "#,
4074         expect![[r#"
4075                 ```rust
4076                 ()
4077                 ```"#]],
4078     );
4079     check_hover_range(
4080         r#"
4081 //- minicore:result
4082 struct FooError;
4083 struct BarError;
4084
4085 fn foo() -> Result<(), FooError> {
4086     Ok($0Result::<(), BarError>::Ok(())?$0)
4087 }
4088 "#,
4089         expect![[r#"
4090                 ```text
4091                 Try Error Type: BarError
4092                 Propagated as:  FooError
4093                 ```
4094             "#]],
4095     );
4096 }
4097
4098 #[test]
4099 fn hover_try_expr() {
4100     check_hover_range(
4101         r#"
4102 struct NotResult<T, U>(T, U);
4103 struct Short;
4104 struct Looooong;
4105
4106 fn foo() -> NotResult<(), Looooong> {
4107     $0NotResult((), Short)?$0;
4108 }
4109 "#,
4110         expect![[r#"
4111                 ```text
4112                 Try Target Type:    NotResult<(), Short>
4113                 Propagated as:   NotResult<(), Looooong>
4114                 ```
4115             "#]],
4116     );
4117     check_hover_range(
4118         r#"
4119 struct NotResult<T, U>(T, U);
4120 struct Short;
4121 struct Looooong;
4122
4123 fn foo() -> NotResult<(), Short> {
4124     $0NotResult((), Looooong)?$0;
4125 }
4126 "#,
4127         expect![[r#"
4128                 ```text
4129                 Try Target Type: NotResult<(), Looooong>
4130                 Propagated as:      NotResult<(), Short>
4131                 ```
4132             "#]],
4133     );
4134 }
4135
4136 #[test]
4137 fn hover_try_expr_option() {
4138     cov_mark::check!(hover_try_expr_opt_opt);
4139     check_hover_range(
4140         r#"
4141 //- minicore: option, try
4142
4143 fn foo() -> Option<()> {
4144     $0Some(0)?$0;
4145     None
4146 }
4147 "#,
4148         expect![[r#"
4149                 ```rust
4150                 <Option<i32> as Try>::Output
4151                 ```"#]],
4152     );
4153 }
4154
4155 #[test]
4156 fn hover_deref_expr() {
4157     check_hover_range(
4158         r#"
4159 //- minicore: deref
4160 use core::ops::Deref;
4161
4162 struct DerefExample<T> {
4163     value: T
4164 }
4165
4166 impl<T> Deref for DerefExample<T> {
4167     type Target = T;
4168
4169     fn deref(&self) -> &Self::Target {
4170         &self.value
4171     }
4172 }
4173
4174 fn foo() {
4175     let x = DerefExample { value: 0 };
4176     let y: i32 = $0*x$0;
4177 }
4178 "#,
4179         expect![[r#"
4180                 ```text
4181                 Dereferenced from: DerefExample<i32>
4182                 To type:                         i32
4183                 ```
4184             "#]],
4185     );
4186 }
4187
4188 #[test]
4189 fn hover_deref_expr_with_coercion() {
4190     check_hover_range(
4191         r#"
4192 //- minicore: deref
4193 use core::ops::Deref;
4194
4195 struct DerefExample<T> {
4196     value: T
4197 }
4198
4199 impl<T> Deref for DerefExample<T> {
4200     type Target = T;
4201
4202     fn deref(&self) -> &Self::Target {
4203         &self.value
4204     }
4205 }
4206
4207 fn foo() {
4208     let x = DerefExample { value: &&&&&0 };
4209     let y: &i32 = $0*x$0;
4210 }
4211 "#,
4212         expect![[r#"
4213                 ```text
4214                 Dereferenced from: DerefExample<&&&&&i32>
4215                 To type:                         &&&&&i32
4216                 Coerced to:                          &i32
4217                 ```
4218             "#]],
4219     );
4220 }
4221
4222 #[test]
4223 fn hover_intra_in_macro() {
4224     check(
4225         r#"
4226 macro_rules! foo_macro {
4227     ($(#[$attr:meta])* $name:ident) => {
4228         $(#[$attr])*
4229         pub struct $name;
4230     }
4231 }
4232
4233 foo_macro!(
4234     /// Doc comment for [`Foo$0`]
4235     Foo
4236 );
4237 "#,
4238         expect![[r#"
4239             *[`Foo`]*
4240
4241             ```rust
4242             test
4243             ```
4244
4245             ```rust
4246             pub struct Foo
4247             ```
4248
4249             ---
4250
4251             Doc comment for [`Foo`](https://doc.rust-lang.org/nightly/test/struct.Foo.html)
4252         "#]],
4253     );
4254 }
4255
4256 #[test]
4257 fn hover_intra_in_attr() {
4258     check(
4259         r#"
4260 #[doc = "Doc comment for [`Foo$0`]"]
4261 pub struct Foo;
4262 "#,
4263         expect![[r#"
4264             *[`Foo`]*
4265
4266             ```rust
4267             test
4268             ```
4269
4270             ```rust
4271             pub struct Foo
4272             ```
4273
4274             ---
4275
4276             Doc comment for [`Foo`](https://doc.rust-lang.org/nightly/test/struct.Foo.html)
4277         "#]],
4278     );
4279 }