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