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