]> git.lizzy.rs Git - rust.git/blob - src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
:arrow_up: rust-analyzer
[rust.git] / src / tools / rust-analyzer / 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 {
12                 links_in_hover: true,
13                 documentation: Some(HoverDocFormat::Markdown),
14                 keywords: true,
15             },
16             FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
17         )
18         .unwrap();
19     assert!(hover.is_none(), "hover not expected but found: {:?}", hover.unwrap());
20 }
21
22 #[track_caller]
23 fn check(ra_fixture: &str, expect: Expect) {
24     let (analysis, position) = fixture::position(ra_fixture);
25     let hover = analysis
26         .hover(
27             &HoverConfig {
28                 links_in_hover: true,
29                 documentation: Some(HoverDocFormat::Markdown),
30                 keywords: true,
31             },
32             FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
33         )
34         .unwrap()
35         .unwrap();
36
37     let content = analysis.db.file_text(position.file_id);
38     let hovered_element = &content[hover.range];
39
40     let actual = format!("*{}*\n{}\n", hovered_element, hover.info.markup);
41     expect.assert_eq(&actual)
42 }
43
44 fn check_hover_no_links(ra_fixture: &str, expect: Expect) {
45     let (analysis, position) = fixture::position(ra_fixture);
46     let hover = analysis
47         .hover(
48             &HoverConfig {
49                 links_in_hover: false,
50                 documentation: Some(HoverDocFormat::Markdown),
51                 keywords: true,
52             },
53             FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
54         )
55         .unwrap()
56         .unwrap();
57
58     let content = analysis.db.file_text(position.file_id);
59     let hovered_element = &content[hover.range];
60
61     let actual = format!("*{}*\n{}\n", hovered_element, hover.info.markup);
62     expect.assert_eq(&actual)
63 }
64
65 fn check_hover_no_markdown(ra_fixture: &str, expect: Expect) {
66     let (analysis, position) = fixture::position(ra_fixture);
67     let hover = analysis
68         .hover(
69             &HoverConfig {
70                 links_in_hover: true,
71                 documentation: Some(HoverDocFormat::PlainText),
72                 keywords: true,
73             },
74             FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
75         )
76         .unwrap()
77         .unwrap();
78
79     let content = analysis.db.file_text(position.file_id);
80     let hovered_element = &content[hover.range];
81
82     let actual = format!("*{}*\n{}\n", hovered_element, hover.info.markup);
83     expect.assert_eq(&actual)
84 }
85
86 fn check_actions(ra_fixture: &str, expect: Expect) {
87     let (analysis, file_id, position) = fixture::range_or_position(ra_fixture);
88     let hover = analysis
89         .hover(
90             &HoverConfig {
91                 links_in_hover: true,
92                 documentation: Some(HoverDocFormat::Markdown),
93                 keywords: true,
94             },
95             FileRange { file_id, range: position.range_or_empty() },
96         )
97         .unwrap()
98         .unwrap();
99     expect.assert_debug_eq(&hover.info.actions)
100 }
101
102 fn check_hover_range(ra_fixture: &str, expect: Expect) {
103     let (analysis, range) = fixture::range(ra_fixture);
104     let hover = analysis
105         .hover(
106             &HoverConfig {
107                 links_in_hover: false,
108                 documentation: Some(HoverDocFormat::Markdown),
109                 keywords: true,
110             },
111             range,
112         )
113         .unwrap()
114         .unwrap();
115     expect.assert_eq(hover.info.markup.as_str())
116 }
117
118 fn check_hover_range_no_results(ra_fixture: &str) {
119     let (analysis, range) = fixture::range(ra_fixture);
120     let hover = analysis
121         .hover(
122             &HoverConfig {
123                 links_in_hover: false,
124                 documentation: Some(HoverDocFormat::Markdown),
125                 keywords: true,
126             },
127             range,
128         )
129         .unwrap();
130     assert!(hover.is_none());
131 }
132
133 #[test]
134 fn hover_descend_macros_avoids_duplicates() {
135     check(
136         r#"
137 macro_rules! dupe_use {
138     ($local:ident) => {
139         {
140             $local;
141             $local;
142         }
143     }
144 }
145 fn foo() {
146     let local = 0;
147     dupe_use!(local$0);
148 }
149 "#,
150         expect![[r#"
151             *local*
152
153             ```rust
154             let local: i32
155             ```
156         "#]],
157     );
158 }
159
160 #[test]
161 fn hover_shows_all_macro_descends() {
162     check(
163         r#"
164 macro_rules! m {
165     ($name:ident) => {
166         /// Outer
167         fn $name() {}
168
169         mod module {
170             /// Inner
171             fn $name() {}
172         }
173     };
174 }
175
176 m!(ab$0c);
177             "#,
178         expect![[r#"
179             *abc*
180
181             ```rust
182             test::module
183             ```
184
185             ```rust
186             fn abc()
187             ```
188
189             ---
190
191             Inner
192             ---
193
194             ```rust
195             test
196             ```
197
198             ```rust
199             fn abc()
200             ```
201
202             ---
203
204             Outer
205         "#]],
206     );
207 }
208
209 #[test]
210 fn hover_shows_type_of_an_expression() {
211     check(
212         r#"
213 pub fn foo() -> u32 { 1 }
214
215 fn main() {
216     let foo_test = foo()$0;
217 }
218 "#,
219         expect![[r#"
220             *foo()*
221             ```rust
222             u32
223             ```
224         "#]],
225     );
226 }
227
228 #[test]
229 fn hover_remove_markdown_if_configured() {
230     check_hover_no_markdown(
231         r#"
232 pub fn foo() -> u32 { 1 }
233
234 fn main() {
235     let foo_test = foo()$0;
236 }
237 "#,
238         expect![[r#"
239             *foo()*
240             u32
241         "#]],
242     );
243 }
244
245 #[test]
246 fn hover_shows_long_type_of_an_expression() {
247     check(
248         r#"
249 struct Scan<A, B, C> { a: A, b: B, c: C }
250 struct Iter<I> { inner: I }
251 enum Option<T> { Some(T), None }
252
253 struct OtherStruct<T> { i: T }
254
255 fn scan<A, B, C>(a: A, b: B, c: C) -> Iter<Scan<OtherStruct<A>, B, C>> {
256     Iter { inner: Scan { a, b, c } }
257 }
258
259 fn main() {
260     let num: i32 = 55;
261     let closure = |memo: &mut u32, value: &u32, _another: &mut u32| -> Option<u32> {
262         Option::Some(*memo + value)
263     };
264     let number = 5u32;
265     let mut iter$0 = scan(OtherStruct { i: num }, closure, number);
266 }
267 "#,
268         expect![[r#"
269                 *iter*
270
271                 ```rust
272                 let mut iter: Iter<Scan<OtherStruct<OtherStruct<i32>>, |&mut u32, &u32, &mut u32| -> Option<u32>, u32>>
273                 ```
274             "#]],
275     );
276 }
277
278 #[test]
279 fn hover_shows_fn_signature() {
280     // Single file with result
281     check(
282         r#"
283 pub fn foo() -> u32 { 1 }
284
285 fn main() { let foo_test = fo$0o(); }
286 "#,
287         expect![[r#"
288                 *foo*
289
290                 ```rust
291                 test
292                 ```
293
294                 ```rust
295                 pub fn foo() -> u32
296                 ```
297             "#]],
298     );
299
300     // Multiple candidates but results are ambiguous.
301     check(
302         r#"
303 //- /a.rs
304 pub fn foo() -> u32 { 1 }
305
306 //- /b.rs
307 pub fn foo() -> &str { "" }
308
309 //- /c.rs
310 pub fn foo(a: u32, b: u32) {}
311
312 //- /main.rs
313 mod a;
314 mod b;
315 mod c;
316
317 fn main() { let foo_test = fo$0o(); }
318         "#,
319         expect![[r#"
320                 *foo*
321                 ```rust
322                 {unknown}
323                 ```
324             "#]],
325     );
326
327     // Use literal `crate` in path
328     check(
329         r#"
330 pub struct X;
331
332 fn foo() -> crate::X { X }
333
334 fn main() { f$0oo(); }
335         "#,
336         expect![[r#"
337             *foo*
338
339             ```rust
340             test
341             ```
342
343             ```rust
344             fn foo() -> crate::X
345             ```
346         "#]],
347     );
348
349     // Check `super` in path
350     check(
351         r#"
352 pub struct X;
353
354 mod m { pub fn foo() -> super::X { super::X } }
355
356 fn main() { m::f$0oo(); }
357         "#,
358         expect![[r#"
359                 *foo*
360
361                 ```rust
362                 test::m
363                 ```
364
365                 ```rust
366                 pub fn foo() -> super::X
367                 ```
368             "#]],
369     );
370 }
371
372 #[test]
373 fn hover_omits_unnamed_where_preds() {
374     check(
375         r#"
376 pub fn foo(bar: impl T) { }
377
378 fn main() { fo$0o(); }
379         "#,
380         expect![[r#"
381             *foo*
382
383             ```rust
384             test
385             ```
386
387             ```rust
388             pub fn foo(bar: impl T)
389             ```
390         "#]],
391     );
392     check(
393         r#"
394 pub fn foo<V: AsRef<str>>(bar: impl T, baz: V) { }
395
396 fn main() { fo$0o(); }
397         "#,
398         expect![[r#"
399             *foo*
400
401             ```rust
402             test
403             ```
404
405             ```rust
406             pub fn foo<V>(bar: impl T, baz: V)
407             where
408                 V: AsRef<str>,
409             ```
410         "#]],
411     );
412 }
413
414 #[test]
415 fn hover_shows_fn_signature_with_type_params() {
416     check(
417         r#"
418 pub fn foo<'a, T: AsRef<str>>(b: &'a T) -> &'a str { }
419
420 fn main() { let foo_test = fo$0o(); }
421         "#,
422         expect![[r#"
423                 *foo*
424
425                 ```rust
426                 test
427                 ```
428
429                 ```rust
430                 pub fn foo<'a, T>(b: &'a T) -> &'a str
431                 where
432                     T: AsRef<str>,
433                 ```
434             "#]],
435     );
436 }
437
438 #[test]
439 fn hover_shows_fn_signature_on_fn_name() {
440     check(
441         r#"
442 pub fn foo$0(a: u32, b: u32) -> u32 {}
443
444 fn main() { }
445 "#,
446         expect![[r#"
447                 *foo*
448
449                 ```rust
450                 test
451                 ```
452
453                 ```rust
454                 pub fn foo(a: u32, b: u32) -> u32
455                 ```
456             "#]],
457     );
458 }
459
460 #[test]
461 fn hover_shows_fn_doc() {
462     check(
463         r#"
464 /// # Example
465 /// ```
466 /// # use std::path::Path;
467 /// #
468 /// foo(Path::new("hello, world!"))
469 /// ```
470 pub fn foo$0(_: &Path) {}
471
472 fn main() { }
473 "#,
474         expect![[r##"
475                 *foo*
476
477                 ```rust
478                 test
479                 ```
480
481                 ```rust
482                 pub fn foo(_: &Path)
483                 ```
484
485                 ---
486
487                 # Example
488
489                 ```
490                 # use std::path::Path;
491                 #
492                 foo(Path::new("hello, world!"))
493                 ```
494             "##]],
495     );
496 }
497
498 #[test]
499 fn hover_shows_fn_doc_attr_raw_string() {
500     check(
501         r##"
502 #[doc = r#"Raw string doc attr"#]
503 pub fn foo$0(_: &Path) {}
504
505 fn main() { }
506 "##,
507         expect![[r##"
508                 *foo*
509
510                 ```rust
511                 test
512                 ```
513
514                 ```rust
515                 pub fn foo(_: &Path)
516                 ```
517
518                 ---
519
520                 Raw string doc attr
521             "##]],
522     );
523 }
524
525 #[test]
526 fn hover_shows_struct_field_info() {
527     // Hovering over the field when instantiating
528     check(
529         r#"
530 struct Foo { field_a: u32 }
531
532 fn main() {
533     let foo = Foo { field_a$0: 0, };
534 }
535 "#,
536         expect![[r#"
537                 *field_a*
538
539                 ```rust
540                 test::Foo
541                 ```
542
543                 ```rust
544                 field_a: u32
545                 ```
546             "#]],
547     );
548
549     // Hovering over the field in the definition
550     check(
551         r#"
552 struct Foo { field_a$0: u32 }
553
554 fn main() {
555     let foo = Foo { field_a: 0 };
556 }
557 "#,
558         expect![[r#"
559                 *field_a*
560
561                 ```rust
562                 test::Foo
563                 ```
564
565                 ```rust
566                 field_a: u32
567                 ```
568             "#]],
569     );
570 }
571
572 #[test]
573 fn hover_const_static() {
574     check(
575         r#"const foo$0: u32 = 123;"#,
576         expect![[r#"
577             *foo*
578
579             ```rust
580             test
581             ```
582
583             ```rust
584             const foo: u32 = 123 (0x7B)
585             ```
586         "#]],
587     );
588     check(
589         r#"
590 const foo$0: u32 = {
591     let x = foo();
592     x + 100
593 };"#,
594         expect![[r#"
595             *foo*
596
597             ```rust
598             test
599             ```
600
601             ```rust
602             const foo: u32 = {
603                 let x = foo();
604                 x + 100
605             }
606             ```
607         "#]],
608     );
609
610     check(
611         r#"static foo$0: u32 = 456;"#,
612         expect![[r#"
613             *foo*
614
615             ```rust
616             test
617             ```
618
619             ```rust
620             static foo: u32 = 456
621             ```
622         "#]],
623     );
624 }
625
626 #[test]
627 fn hover_default_generic_types() {
628     check(
629         r#"
630 struct Test<K, T = u8> { k: K, t: T }
631
632 fn main() {
633     let zz$0 = Test { t: 23u8, k: 33 };
634 }"#,
635         expect![[r#"
636                 *zz*
637
638                 ```rust
639                 let zz: Test<i32>
640                 ```
641             "#]],
642     );
643     check_hover_range(
644         r#"
645 struct Test<K, T = u8> { k: K, t: T }
646
647 fn main() {
648     let $0zz$0 = Test { t: 23u8, k: 33 };
649 }"#,
650         expect![[r#"
651             ```rust
652             Test<i32, u8>
653             ```"#]],
654     );
655 }
656
657 #[test]
658 fn hover_some() {
659     check(
660         r#"
661 enum Option<T> { Some(T) }
662 use Option::Some;
663
664 fn main() { So$0me(12); }
665 "#,
666         expect![[r#"
667                 *Some*
668
669                 ```rust
670                 test::Option
671                 ```
672
673                 ```rust
674                 Some(T)
675                 ```
676             "#]],
677     );
678
679     check(
680         r#"
681 enum Option<T> { Some(T) }
682 use Option::Some;
683
684 fn main() { let b$0ar = Some(12); }
685 "#,
686         expect![[r#"
687                 *bar*
688
689                 ```rust
690                 let bar: Option<i32>
691                 ```
692             "#]],
693     );
694 }
695
696 #[test]
697 fn hover_enum_variant() {
698     check(
699         r#"
700 enum Option<T> {
701     Some(T)
702     /// The None variant
703     Non$0e
704 }
705 "#,
706         expect![[r#"
707                 *None*
708
709                 ```rust
710                 test::Option
711                 ```
712
713                 ```rust
714                 None
715                 ```
716
717                 ---
718
719                 The None variant
720             "#]],
721     );
722
723     check(
724         r#"
725 enum Option<T> {
726     /// The Some variant
727     Some(T)
728 }
729 fn main() {
730     let s = Option::Som$0e(12);
731 }
732 "#,
733         expect![[r#"
734                 *Some*
735
736                 ```rust
737                 test::Option
738                 ```
739
740                 ```rust
741                 Some(T)
742                 ```
743
744                 ---
745
746                 The Some variant
747             "#]],
748     );
749 }
750
751 #[test]
752 fn hover_for_local_variable() {
753     check(
754         r#"fn func(foo: i32) { fo$0o; }"#,
755         expect![[r#"
756                 *foo*
757
758                 ```rust
759                 foo: i32
760                 ```
761             "#]],
762     )
763 }
764
765 #[test]
766 fn hover_for_local_variable_pat() {
767     check(
768         r#"fn func(fo$0o: i32) {}"#,
769         expect![[r#"
770                 *foo*
771
772                 ```rust
773                 foo: i32
774                 ```
775             "#]],
776     )
777 }
778
779 #[test]
780 fn hover_local_var_edge() {
781     check(
782         r#"fn func(foo: i32) { if true { $0foo; }; }"#,
783         expect![[r#"
784                 *foo*
785
786                 ```rust
787                 foo: i32
788                 ```
789             "#]],
790     )
791 }
792
793 #[test]
794 fn hover_for_param_edge() {
795     check(
796         r#"fn func($0foo: i32) {}"#,
797         expect![[r#"
798                 *foo*
799
800                 ```rust
801                 foo: i32
802                 ```
803             "#]],
804     )
805 }
806
807 #[test]
808 fn hover_for_param_with_multiple_traits() {
809     check(
810         r#"
811             //- minicore: sized
812             trait Deref {
813                 type Target: ?Sized;
814             }
815             trait DerefMut {
816                 type Target: ?Sized;
817             }
818             fn f(_x$0: impl Deref<Target=u8> + DerefMut<Target=u8>) {}"#,
819         expect![[r#"
820                 *_x*
821
822                 ```rust
823                 _x: impl Deref<Target = u8> + DerefMut<Target = u8>
824                 ```
825             "#]],
826     )
827 }
828
829 #[test]
830 fn test_hover_infer_associated_method_result() {
831     check(
832         r#"
833 struct Thing { x: u32 }
834
835 impl Thing {
836     fn new() -> Thing { Thing { x: 0 } }
837 }
838
839 fn main() { let foo_$0test = Thing::new(); }
840 "#,
841         expect![[r#"
842                 *foo_test*
843
844                 ```rust
845                 let foo_test: Thing
846                 ```
847             "#]],
848     )
849 }
850
851 #[test]
852 fn test_hover_infer_associated_method_exact() {
853     check(
854         r#"
855 mod wrapper {
856     pub struct Thing { x: u32 }
857
858     impl Thing {
859         pub fn new() -> Thing { Thing { x: 0 } }
860     }
861 }
862
863 fn main() { let foo_test = wrapper::Thing::new$0(); }
864 "#,
865         expect![[r#"
866                 *new*
867
868                 ```rust
869                 test::wrapper::Thing
870                 ```
871
872                 ```rust
873                 pub fn new() -> Thing
874                 ```
875         "#]],
876     )
877 }
878
879 #[test]
880 fn test_hover_infer_associated_const_in_pattern() {
881     check(
882         r#"
883 struct X;
884 impl X {
885     const C: u32 = 1;
886 }
887
888 fn main() {
889     match 1 {
890         X::C$0 => {},
891         2 => {},
892         _ => {}
893     };
894 }
895 "#,
896         expect![[r#"
897             *C*
898
899             ```rust
900             test
901             ```
902
903             ```rust
904             const C: u32 = 1
905             ```
906         "#]],
907     )
908 }
909
910 #[test]
911 fn test_hover_self() {
912     check(
913         r#"
914 struct Thing { x: u32 }
915 impl Thing {
916     fn new() -> Self { Self$0 { x: 0 } }
917 }
918 "#,
919         expect![[r#"
920                 *Self*
921
922                 ```rust
923                 test
924                 ```
925
926                 ```rust
927                 struct Thing
928                 ```
929             "#]],
930     );
931     check(
932         r#"
933 struct Thing { x: u32 }
934 impl Thing {
935     fn new() -> Self$0 { Self { x: 0 } }
936 }
937 "#,
938         expect![[r#"
939                 *Self*
940
941                 ```rust
942                 test
943                 ```
944
945                 ```rust
946                 struct Thing
947                 ```
948             "#]],
949     );
950     check(
951         r#"
952 enum Thing { A }
953 impl Thing {
954     pub fn new() -> Self$0 { Thing::A }
955 }
956 "#,
957         expect![[r#"
958                 *Self*
959
960                 ```rust
961                 test
962                 ```
963
964                 ```rust
965                 enum Thing
966                 ```
967             "#]],
968     );
969     check(
970         r#"
971         enum Thing { A }
972         impl Thing {
973             pub fn thing(a: Self$0) {}
974         }
975         "#,
976         expect![[r#"
977                 *Self*
978
979                 ```rust
980                 test
981                 ```
982
983                 ```rust
984                 enum Thing
985                 ```
986             "#]],
987     );
988 }
989
990 #[test]
991 fn test_hover_shadowing_pat() {
992     check(
993         r#"
994 fn x() {}
995
996 fn y() {
997     let x = 0i32;
998     x$0;
999 }
1000 "#,
1001         expect![[r#"
1002                 *x*
1003
1004                 ```rust
1005                 let x: i32
1006                 ```
1007             "#]],
1008     )
1009 }
1010
1011 #[test]
1012 fn test_hover_macro_invocation() {
1013     check(
1014         r#"
1015 macro_rules! foo { () => {} }
1016
1017 fn f() { fo$0o!(); }
1018 "#,
1019         expect![[r#"
1020                 *foo*
1021
1022                 ```rust
1023                 test
1024                 ```
1025
1026                 ```rust
1027                 macro_rules! foo
1028                 ```
1029             "#]],
1030     )
1031 }
1032
1033 #[test]
1034 fn test_hover_macro2_invocation() {
1035     check(
1036         r#"
1037 /// foo bar
1038 ///
1039 /// foo bar baz
1040 macro foo() {}
1041
1042 fn f() { fo$0o!(); }
1043 "#,
1044         expect![[r#"
1045                 *foo*
1046
1047                 ```rust
1048                 test
1049                 ```
1050
1051                 ```rust
1052                 macro foo
1053                 ```
1054
1055                 ---
1056
1057                 foo bar
1058
1059                 foo bar baz
1060             "#]],
1061     )
1062 }
1063
1064 #[test]
1065 fn test_hover_tuple_field() {
1066     check(
1067         r#"struct TS(String, i32$0);"#,
1068         expect![[r#"
1069                 *i32*
1070
1071                 ```rust
1072                 i32
1073                 ```
1074             "#]],
1075     )
1076 }
1077
1078 #[test]
1079 fn test_hover_through_macro() {
1080     check(
1081         r#"
1082 macro_rules! id { ($($tt:tt)*) => { $($tt)* } }
1083 fn foo() {}
1084 id! {
1085     fn bar() { fo$0o(); }
1086 }
1087 "#,
1088         expect![[r#"
1089                 *foo*
1090
1091                 ```rust
1092                 test
1093                 ```
1094
1095                 ```rust
1096                 fn foo()
1097                 ```
1098             "#]],
1099     );
1100 }
1101
1102 #[test]
1103 fn test_hover_through_attr() {
1104     check(
1105         r#"
1106 //- proc_macros: identity
1107 #[proc_macros::identity]
1108 fn foo$0() {}
1109 "#,
1110         expect![[r#"
1111                 *foo*
1112
1113                 ```rust
1114                 test
1115                 ```
1116
1117                 ```rust
1118                 fn foo()
1119                 ```
1120             "#]],
1121     );
1122 }
1123
1124 #[test]
1125 fn test_hover_through_expr_in_macro() {
1126     check(
1127         r#"
1128 macro_rules! id { ($($tt:tt)*) => { $($tt)* } }
1129 fn foo(bar:u32) { let a = id!(ba$0r); }
1130 "#,
1131         expect![[r#"
1132                 *bar*
1133
1134                 ```rust
1135                 bar: u32
1136                 ```
1137             "#]],
1138     );
1139 }
1140
1141 #[test]
1142 fn test_hover_through_expr_in_macro_recursive() {
1143     check(
1144         r#"
1145 macro_rules! id_deep { ($($tt:tt)*) => { $($tt)* } }
1146 macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } }
1147 fn foo(bar:u32) { let a = id!(ba$0r); }
1148 "#,
1149         expect![[r#"
1150                 *bar*
1151
1152                 ```rust
1153                 bar: u32
1154                 ```
1155             "#]],
1156     );
1157 }
1158
1159 #[test]
1160 fn test_hover_through_func_in_macro_recursive() {
1161     check(
1162         r#"
1163 macro_rules! id_deep { ($($tt:tt)*) => { $($tt)* } }
1164 macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } }
1165 fn bar() -> u32 { 0 }
1166 fn foo() { let a = id!([0u32, bar($0)] ); }
1167 "#,
1168         expect![[r#"
1169                 *bar()*
1170                 ```rust
1171                 u32
1172                 ```
1173             "#]],
1174     );
1175 }
1176
1177 #[test]
1178 fn test_hover_through_literal_string_in_macro() {
1179     check(
1180         r#"
1181 macro_rules! arr { ($($tt:tt)*) => { [$($tt)*] } }
1182 fn foo() {
1183     let mastered_for_itunes = "";
1184     let _ = arr!("Tr$0acks", &mastered_for_itunes);
1185 }
1186 "#,
1187         expect![[r#"
1188                 *"Tracks"*
1189                 ```rust
1190                 &str
1191                 ```
1192             "#]],
1193     );
1194 }
1195
1196 #[test]
1197 fn test_hover_through_assert_macro() {
1198     check(
1199         r#"
1200 #[rustc_builtin_macro]
1201 macro_rules! assert {}
1202
1203 fn bar() -> bool { true }
1204 fn foo() {
1205     assert!(ba$0r());
1206 }
1207 "#,
1208         expect![[r#"
1209                 *bar*
1210
1211                 ```rust
1212                 test
1213                 ```
1214
1215                 ```rust
1216                 fn bar() -> bool
1217                 ```
1218             "#]],
1219     );
1220 }
1221
1222 #[test]
1223 fn test_hover_multiple_actions() {
1224     check_actions(
1225         r#"
1226 struct Bar;
1227 struct Foo { bar: Bar }
1228
1229 fn foo(Foo { b$0ar }: &Foo) {}
1230         "#,
1231         expect![[r#"
1232             [
1233                 GoToType(
1234                     [
1235                         HoverGotoTypeData {
1236                             mod_path: "test::Bar",
1237                             nav: NavigationTarget {
1238                                 file_id: FileId(
1239                                     0,
1240                                 ),
1241                                 full_range: 0..11,
1242                                 focus_range: 7..10,
1243                                 name: "Bar",
1244                                 kind: Struct,
1245                                 description: "struct Bar",
1246                             },
1247                         },
1248                     ],
1249                 ),
1250             ]
1251         "#]],
1252     )
1253 }
1254
1255 #[test]
1256 fn test_hover_through_literal_string_in_builtin_macro() {
1257     check_hover_no_result(
1258         r#"
1259             #[rustc_builtin_macro]
1260             macro_rules! format {}
1261
1262             fn foo() {
1263                 format!("hel$0lo {}", 0);
1264             }
1265 "#,
1266     );
1267 }
1268
1269 #[test]
1270 fn test_hover_non_ascii_space_doc() {
1271     check(
1272         "
1273 /// <- `\u{3000}` here
1274 fn foo() { }
1275
1276 fn bar() { fo$0o(); }
1277 ",
1278         expect![[r#"
1279                 *foo*
1280
1281                 ```rust
1282                 test
1283                 ```
1284
1285                 ```rust
1286                 fn foo()
1287                 ```
1288
1289                 ---
1290
1291                 \<- ` ` here
1292             "#]],
1293     );
1294 }
1295
1296 #[test]
1297 fn test_hover_function_show_qualifiers() {
1298     check(
1299         r#"async fn foo$0() {}"#,
1300         expect![[r#"
1301                 *foo*
1302
1303                 ```rust
1304                 test
1305                 ```
1306
1307                 ```rust
1308                 async fn foo()
1309                 ```
1310             "#]],
1311     );
1312     check(
1313         r#"pub const unsafe fn foo$0() {}"#,
1314         expect![[r#"
1315                 *foo*
1316
1317                 ```rust
1318                 test
1319                 ```
1320
1321                 ```rust
1322                 pub const unsafe fn foo()
1323                 ```
1324             "#]],
1325     );
1326     // Top level `pub(crate)` will be displayed as no visibility.
1327     check(
1328         r#"mod m { pub(crate) async unsafe extern "C" fn foo$0() {} }"#,
1329         expect![[r#"
1330                 *foo*
1331
1332                 ```rust
1333                 test::m
1334                 ```
1335
1336                 ```rust
1337                 pub(crate) async unsafe extern "C" fn foo()
1338                 ```
1339             "#]],
1340     );
1341 }
1342
1343 #[test]
1344 fn test_hover_function_show_types() {
1345     check(
1346         r#"fn foo$0(a: i32, b:i32) -> i32 { 0 }"#,
1347         expect![[r#"
1348                 *foo*
1349
1350                 ```rust
1351                 test
1352                 ```
1353
1354                 ```rust
1355                 fn foo(a: i32, b: i32) -> i32
1356                 ```
1357             "#]],
1358     );
1359 }
1360
1361 #[test]
1362 fn test_hover_function_pointer_show_identifiers() {
1363     check(
1364         r#"type foo$0 = fn(a: i32, b: i32) -> i32;"#,
1365         expect![[r#"
1366                 *foo*
1367
1368                 ```rust
1369                 test
1370                 ```
1371
1372                 ```rust
1373                 type foo = fn(a: i32, b: i32) -> i32
1374                 ```
1375             "#]],
1376     );
1377 }
1378
1379 #[test]
1380 fn test_hover_function_pointer_no_identifier() {
1381     check(
1382         r#"type foo$0 = fn(i32, _: i32) -> i32;"#,
1383         expect![[r#"
1384                 *foo*
1385
1386                 ```rust
1387                 test
1388                 ```
1389
1390                 ```rust
1391                 type foo = fn(i32, i32) -> i32
1392                 ```
1393             "#]],
1394     );
1395 }
1396
1397 #[test]
1398 fn test_hover_trait_show_qualifiers() {
1399     check_actions(
1400         r"unsafe trait foo$0() {}",
1401         expect![[r#"
1402                 [
1403                     Implementation(
1404                         FilePosition {
1405                             file_id: FileId(
1406                                 0,
1407                             ),
1408                             offset: 13,
1409                         },
1410                     ),
1411                 ]
1412             "#]],
1413     );
1414 }
1415
1416 #[test]
1417 fn test_hover_extern_crate() {
1418     check(
1419         r#"
1420 //- /main.rs crate:main deps:std
1421 extern crate st$0d;
1422 //- /std/lib.rs crate:std
1423 //! Standard library for this test
1424 //!
1425 //! Printed?
1426 //! abc123
1427 "#,
1428         expect![[r#"
1429                 *std*
1430
1431                 ```rust
1432                 extern crate std
1433                 ```
1434
1435                 ---
1436
1437                 Standard library for this test
1438
1439                 Printed?
1440                 abc123
1441             "#]],
1442     );
1443     check(
1444         r#"
1445 //- /main.rs crate:main deps:std
1446 extern crate std as ab$0c;
1447 //- /std/lib.rs crate:std
1448 //! Standard library for this test
1449 //!
1450 //! Printed?
1451 //! abc123
1452 "#,
1453         expect![[r#"
1454                 *abc*
1455
1456                 ```rust
1457                 extern crate std
1458                 ```
1459
1460                 ---
1461
1462                 Standard library for this test
1463
1464                 Printed?
1465                 abc123
1466             "#]],
1467     );
1468 }
1469
1470 #[test]
1471 fn test_hover_mod_with_same_name_as_function() {
1472     check(
1473         r#"
1474 use self::m$0y::Bar;
1475 mod my { pub struct Bar; }
1476
1477 fn my() {}
1478 "#,
1479         expect![[r#"
1480                 *my*
1481
1482                 ```rust
1483                 test
1484                 ```
1485
1486                 ```rust
1487                 mod my
1488                 ```
1489             "#]],
1490     );
1491 }
1492
1493 #[test]
1494 fn test_hover_struct_doc_comment() {
1495     check(
1496         r#"
1497 /// This is an example
1498 /// multiline doc
1499 ///
1500 /// # Example
1501 ///
1502 /// ```
1503 /// let five = 5;
1504 ///
1505 /// assert_eq!(6, my_crate::add_one(5));
1506 /// ```
1507 struct Bar;
1508
1509 fn foo() { let bar = Ba$0r; }
1510 "#,
1511         expect![[r##"
1512                 *Bar*
1513
1514                 ```rust
1515                 test
1516                 ```
1517
1518                 ```rust
1519                 struct Bar
1520                 ```
1521
1522                 ---
1523
1524                 This is an example
1525                 multiline doc
1526
1527                 # Example
1528
1529                 ```
1530                 let five = 5;
1531
1532                 assert_eq!(6, my_crate::add_one(5));
1533                 ```
1534             "##]],
1535     );
1536 }
1537
1538 #[test]
1539 fn test_hover_struct_doc_attr() {
1540     check(
1541         r#"
1542 #[doc = "bar docs"]
1543 struct Bar;
1544
1545 fn foo() { let bar = Ba$0r; }
1546 "#,
1547         expect![[r#"
1548                 *Bar*
1549
1550                 ```rust
1551                 test
1552                 ```
1553
1554                 ```rust
1555                 struct Bar
1556                 ```
1557
1558                 ---
1559
1560                 bar docs
1561             "#]],
1562     );
1563 }
1564
1565 #[test]
1566 fn test_hover_struct_doc_attr_multiple_and_mixed() {
1567     check(
1568         r#"
1569 /// bar docs 0
1570 #[doc = "bar docs 1"]
1571 #[doc = "bar docs 2"]
1572 struct Bar;
1573
1574 fn foo() { let bar = Ba$0r; }
1575 "#,
1576         expect![[r#"
1577                 *Bar*
1578
1579                 ```rust
1580                 test
1581                 ```
1582
1583                 ```rust
1584                 struct Bar
1585                 ```
1586
1587                 ---
1588
1589                 bar docs 0
1590                 bar docs 1
1591                 bar docs 2
1592             "#]],
1593     );
1594 }
1595
1596 #[test]
1597 fn test_hover_external_url() {
1598     check(
1599         r#"
1600 pub struct Foo;
1601 /// [external](https://www.google.com)
1602 pub struct B$0ar
1603 "#,
1604         expect![[r#"
1605                 *Bar*
1606
1607                 ```rust
1608                 test
1609                 ```
1610
1611                 ```rust
1612                 pub struct Bar
1613                 ```
1614
1615                 ---
1616
1617                 [external](https://www.google.com)
1618             "#]],
1619     );
1620 }
1621
1622 // Check that we don't rewrite links which we can't identify
1623 #[test]
1624 fn test_hover_unknown_target() {
1625     check(
1626         r#"
1627 pub struct Foo;
1628 /// [baz](Baz)
1629 pub struct B$0ar
1630 "#,
1631         expect![[r#"
1632                 *Bar*
1633
1634                 ```rust
1635                 test
1636                 ```
1637
1638                 ```rust
1639                 pub struct Bar
1640                 ```
1641
1642                 ---
1643
1644                 [baz](Baz)
1645             "#]],
1646     );
1647 }
1648
1649 #[test]
1650 fn test_hover_no_links() {
1651     check_hover_no_links(
1652         r#"
1653 /// Test cases:
1654 /// case 1.  bare URL: https://www.example.com/
1655 /// case 2.  inline URL with title: [example](https://www.example.com/)
1656 /// case 3.  code reference: [`Result`]
1657 /// case 4.  code reference but miss footnote: [`String`]
1658 /// case 5.  autolink: <http://www.example.com/>
1659 /// case 6.  email address: <test@example.com>
1660 /// case 7.  reference: [example][example]
1661 /// case 8.  collapsed link: [example][]
1662 /// case 9.  shortcut link: [example]
1663 /// case 10. inline without URL: [example]()
1664 /// case 11. reference: [foo][foo]
1665 /// case 12. reference: [foo][bar]
1666 /// case 13. collapsed link: [foo][]
1667 /// case 14. shortcut link: [foo]
1668 /// case 15. inline without URL: [foo]()
1669 /// case 16. just escaped text: \[foo]
1670 /// case 17. inline link: [Foo](foo::Foo)
1671 ///
1672 /// [`Result`]: ../../std/result/enum.Result.html
1673 /// [^example]: https://www.example.com/
1674 pub fn fo$0o() {}
1675 "#,
1676         expect![[r#"
1677                 *foo*
1678
1679                 ```rust
1680                 test
1681                 ```
1682
1683                 ```rust
1684                 pub fn foo()
1685                 ```
1686
1687                 ---
1688
1689                 Test cases:
1690                 case 1.  bare URL: https://www.example.com/
1691                 case 2.  inline URL with title: [example](https://www.example.com/)
1692                 case 3.  code reference: `Result`
1693                 case 4.  code reference but miss footnote: `String`
1694                 case 5.  autolink: http://www.example.com/
1695                 case 6.  email address: test@example.com
1696                 case 7.  reference: example
1697                 case 8.  collapsed link: example
1698                 case 9.  shortcut link: example
1699                 case 10. inline without URL: example
1700                 case 11. reference: foo
1701                 case 12. reference: foo
1702                 case 13. collapsed link: foo
1703                 case 14. shortcut link: foo
1704                 case 15. inline without URL: foo
1705                 case 16. just escaped text: \[foo\]
1706                 case 17. inline link: Foo
1707
1708                 [^example]: https://www.example.com/
1709             "#]],
1710     );
1711 }
1712
1713 #[test]
1714 fn test_hover_macro_generated_struct_fn_doc_comment() {
1715     cov_mark::check!(hover_macro_generated_struct_fn_doc_comment);
1716
1717     check(
1718         r#"
1719 macro_rules! bar {
1720     () => {
1721         struct Bar;
1722         impl Bar {
1723             /// Do the foo
1724             fn foo(&self) {}
1725         }
1726     }
1727 }
1728
1729 bar!();
1730
1731 fn foo() { let bar = Bar; bar.fo$0o(); }
1732 "#,
1733         expect![[r#"
1734                 *foo*
1735
1736                 ```rust
1737                 test::Bar
1738                 ```
1739
1740                 ```rust
1741                 fn foo(&self)
1742                 ```
1743
1744                 ---
1745
1746                 Do the foo
1747             "#]],
1748     );
1749 }
1750
1751 #[test]
1752 fn test_hover_macro_generated_struct_fn_doc_attr() {
1753     cov_mark::check!(hover_macro_generated_struct_fn_doc_attr);
1754
1755     check(
1756         r#"
1757 macro_rules! bar {
1758     () => {
1759         struct Bar;
1760         impl Bar {
1761             #[doc = "Do the foo"]
1762             fn foo(&self) {}
1763         }
1764     }
1765 }
1766
1767 bar!();
1768
1769 fn foo() { let bar = Bar; bar.fo$0o(); }
1770 "#,
1771         expect![[r#"
1772                 *foo*
1773
1774                 ```rust
1775                 test::Bar
1776                 ```
1777
1778                 ```rust
1779                 fn foo(&self)
1780                 ```
1781
1782                 ---
1783
1784                 Do the foo
1785             "#]],
1786     );
1787 }
1788
1789 #[test]
1790 fn test_hover_variadic_function() {
1791     check(
1792         r#"
1793 extern "C" {
1794     pub fn foo(bar: i32, ...) -> i32;
1795 }
1796
1797 fn main() { let foo_test = unsafe { fo$0o(1, 2, 3); } }
1798 "#,
1799         expect![[r#"
1800             *foo*
1801
1802             ```rust
1803             test
1804             ```
1805
1806             ```rust
1807             pub unsafe fn foo(bar: i32, ...) -> i32
1808             ```
1809         "#]],
1810     );
1811 }
1812
1813 #[test]
1814 fn test_hover_trait_has_impl_action() {
1815     check_actions(
1816         r#"trait foo$0() {}"#,
1817         expect![[r#"
1818                 [
1819                     Implementation(
1820                         FilePosition {
1821                             file_id: FileId(
1822                                 0,
1823                             ),
1824                             offset: 6,
1825                         },
1826                     ),
1827                 ]
1828             "#]],
1829     );
1830 }
1831
1832 #[test]
1833 fn test_hover_struct_has_impl_action() {
1834     check_actions(
1835         r"struct foo$0() {}",
1836         expect![[r#"
1837                 [
1838                     Implementation(
1839                         FilePosition {
1840                             file_id: FileId(
1841                                 0,
1842                             ),
1843                             offset: 7,
1844                         },
1845                     ),
1846                 ]
1847             "#]],
1848     );
1849 }
1850
1851 #[test]
1852 fn test_hover_union_has_impl_action() {
1853     check_actions(
1854         r#"union foo$0() {}"#,
1855         expect![[r#"
1856                 [
1857                     Implementation(
1858                         FilePosition {
1859                             file_id: FileId(
1860                                 0,
1861                             ),
1862                             offset: 6,
1863                         },
1864                     ),
1865                 ]
1866             "#]],
1867     );
1868 }
1869
1870 #[test]
1871 fn test_hover_enum_has_impl_action() {
1872     check_actions(
1873         r"enum foo$0() { A, B }",
1874         expect![[r#"
1875                 [
1876                     Implementation(
1877                         FilePosition {
1878                             file_id: FileId(
1879                                 0,
1880                             ),
1881                             offset: 5,
1882                         },
1883                     ),
1884                 ]
1885             "#]],
1886     );
1887 }
1888
1889 #[test]
1890 fn test_hover_self_has_impl_action() {
1891     check_actions(
1892         r#"struct foo where Self$0:;"#,
1893         expect![[r#"
1894                 [
1895                     Implementation(
1896                         FilePosition {
1897                             file_id: FileId(
1898                                 0,
1899                             ),
1900                             offset: 7,
1901                         },
1902                     ),
1903                 ]
1904             "#]],
1905     );
1906 }
1907
1908 #[test]
1909 fn test_hover_test_has_action() {
1910     check_actions(
1911         r#"
1912 #[test]
1913 fn foo_$0test() {}
1914 "#,
1915         expect![[r#"
1916             [
1917                 Reference(
1918                     FilePosition {
1919                         file_id: FileId(
1920                             0,
1921                         ),
1922                         offset: 11,
1923                     },
1924                 ),
1925                 Runnable(
1926                     Runnable {
1927                         use_name_in_title: false,
1928                         nav: NavigationTarget {
1929                             file_id: FileId(
1930                                 0,
1931                             ),
1932                             full_range: 0..24,
1933                             focus_range: 11..19,
1934                             name: "foo_test",
1935                             kind: Function,
1936                         },
1937                         kind: Test {
1938                             test_id: Path(
1939                                 "foo_test",
1940                             ),
1941                             attr: TestAttr {
1942                                 ignore: false,
1943                             },
1944                         },
1945                         cfg: None,
1946                     },
1947                 ),
1948             ]
1949         "#]],
1950     );
1951 }
1952
1953 #[test]
1954 fn test_hover_test_mod_has_action() {
1955     check_actions(
1956         r#"
1957 mod tests$0 {
1958     #[test]
1959     fn foo_test() {}
1960 }
1961 "#,
1962         expect![[r#"
1963                 [
1964                     Runnable(
1965                         Runnable {
1966                             use_name_in_title: false,
1967                             nav: NavigationTarget {
1968                                 file_id: FileId(
1969                                     0,
1970                                 ),
1971                                 full_range: 0..46,
1972                                 focus_range: 4..9,
1973                                 name: "tests",
1974                                 kind: Module,
1975                                 description: "mod tests",
1976                             },
1977                             kind: TestMod {
1978                                 path: "tests",
1979                             },
1980                             cfg: None,
1981                         },
1982                     ),
1983                 ]
1984             "#]],
1985     );
1986 }
1987
1988 #[test]
1989 fn test_hover_struct_has_goto_type_action() {
1990     check_actions(
1991         r#"
1992 struct S{ f1: u32 }
1993
1994 fn main() { let s$0t = S{ f1:0 }; }
1995 "#,
1996         expect![[r#"
1997                 [
1998                     GoToType(
1999                         [
2000                             HoverGotoTypeData {
2001                                 mod_path: "test::S",
2002                                 nav: NavigationTarget {
2003                                     file_id: FileId(
2004                                         0,
2005                                     ),
2006                                     full_range: 0..19,
2007                                     focus_range: 7..8,
2008                                     name: "S",
2009                                     kind: Struct,
2010                                     description: "struct S",
2011                                 },
2012                             },
2013                         ],
2014                     ),
2015                 ]
2016             "#]],
2017     );
2018 }
2019
2020 #[test]
2021 fn test_hover_generic_struct_has_goto_type_actions() {
2022     check_actions(
2023         r#"
2024 struct Arg(u32);
2025 struct S<T>{ f1: T }
2026
2027 fn main() { let s$0t = S{ f1:Arg(0) }; }
2028 "#,
2029         expect![[r#"
2030                 [
2031                     GoToType(
2032                         [
2033                             HoverGotoTypeData {
2034                                 mod_path: "test::S",
2035                                 nav: NavigationTarget {
2036                                     file_id: FileId(
2037                                         0,
2038                                     ),
2039                                     full_range: 17..37,
2040                                     focus_range: 24..25,
2041                                     name: "S",
2042                                     kind: Struct,
2043                                     description: "struct S<T>",
2044                                 },
2045                             },
2046                             HoverGotoTypeData {
2047                                 mod_path: "test::Arg",
2048                                 nav: NavigationTarget {
2049                                     file_id: FileId(
2050                                         0,
2051                                     ),
2052                                     full_range: 0..16,
2053                                     focus_range: 7..10,
2054                                     name: "Arg",
2055                                     kind: Struct,
2056                                     description: "struct Arg",
2057                                 },
2058                             },
2059                         ],
2060                     ),
2061                 ]
2062             "#]],
2063     );
2064 }
2065
2066 #[test]
2067 fn test_hover_generic_struct_has_flattened_goto_type_actions() {
2068     check_actions(
2069         r#"
2070 struct Arg(u32);
2071 struct S<T>{ f1: T }
2072
2073 fn main() { let s$0t = S{ f1: S{ f1: Arg(0) } }; }
2074 "#,
2075         expect![[r#"
2076                 [
2077                     GoToType(
2078                         [
2079                             HoverGotoTypeData {
2080                                 mod_path: "test::S",
2081                                 nav: NavigationTarget {
2082                                     file_id: FileId(
2083                                         0,
2084                                     ),
2085                                     full_range: 17..37,
2086                                     focus_range: 24..25,
2087                                     name: "S",
2088                                     kind: Struct,
2089                                     description: "struct S<T>",
2090                                 },
2091                             },
2092                             HoverGotoTypeData {
2093                                 mod_path: "test::Arg",
2094                                 nav: NavigationTarget {
2095                                     file_id: FileId(
2096                                         0,
2097                                     ),
2098                                     full_range: 0..16,
2099                                     focus_range: 7..10,
2100                                     name: "Arg",
2101                                     kind: Struct,
2102                                     description: "struct Arg",
2103                                 },
2104                             },
2105                         ],
2106                     ),
2107                 ]
2108             "#]],
2109     );
2110 }
2111
2112 #[test]
2113 fn test_hover_tuple_has_goto_type_actions() {
2114     check_actions(
2115         r#"
2116 struct A(u32);
2117 struct B(u32);
2118 mod M {
2119     pub struct C(u32);
2120 }
2121
2122 fn main() { let s$0t = (A(1), B(2), M::C(3) ); }
2123 "#,
2124         expect![[r#"
2125                 [
2126                     GoToType(
2127                         [
2128                             HoverGotoTypeData {
2129                                 mod_path: "test::A",
2130                                 nav: NavigationTarget {
2131                                     file_id: FileId(
2132                                         0,
2133                                     ),
2134                                     full_range: 0..14,
2135                                     focus_range: 7..8,
2136                                     name: "A",
2137                                     kind: Struct,
2138                                     description: "struct A",
2139                                 },
2140                             },
2141                             HoverGotoTypeData {
2142                                 mod_path: "test::B",
2143                                 nav: NavigationTarget {
2144                                     file_id: FileId(
2145                                         0,
2146                                     ),
2147                                     full_range: 15..29,
2148                                     focus_range: 22..23,
2149                                     name: "B",
2150                                     kind: Struct,
2151                                     description: "struct B",
2152                                 },
2153                             },
2154                             HoverGotoTypeData {
2155                                 mod_path: "test::M::C",
2156                                 nav: NavigationTarget {
2157                                     file_id: FileId(
2158                                         0,
2159                                     ),
2160                                     full_range: 42..60,
2161                                     focus_range: 53..54,
2162                                     name: "C",
2163                                     kind: Struct,
2164                                     description: "pub struct C",
2165                                 },
2166                             },
2167                         ],
2168                     ),
2169                 ]
2170             "#]],
2171     );
2172 }
2173
2174 #[test]
2175 fn test_hover_return_impl_trait_has_goto_type_action() {
2176     check_actions(
2177         r#"
2178 trait Foo {}
2179 fn foo() -> impl Foo {}
2180
2181 fn main() { let s$0t = foo(); }
2182 "#,
2183         expect![[r#"
2184                 [
2185                     GoToType(
2186                         [
2187                             HoverGotoTypeData {
2188                                 mod_path: "test::Foo",
2189                                 nav: NavigationTarget {
2190                                     file_id: FileId(
2191                                         0,
2192                                     ),
2193                                     full_range: 0..12,
2194                                     focus_range: 6..9,
2195                                     name: "Foo",
2196                                     kind: Trait,
2197                                     description: "trait Foo",
2198                                 },
2199                             },
2200                         ],
2201                     ),
2202                 ]
2203             "#]],
2204     );
2205 }
2206
2207 #[test]
2208 fn test_hover_generic_return_impl_trait_has_goto_type_action() {
2209     check_actions(
2210         r#"
2211 trait Foo<T> {}
2212 struct S;
2213 fn foo() -> impl Foo<S> {}
2214
2215 fn main() { let s$0t = foo(); }
2216 "#,
2217         expect![[r#"
2218                 [
2219                     GoToType(
2220                         [
2221                             HoverGotoTypeData {
2222                                 mod_path: "test::Foo",
2223                                 nav: NavigationTarget {
2224                                     file_id: FileId(
2225                                         0,
2226                                     ),
2227                                     full_range: 0..15,
2228                                     focus_range: 6..9,
2229                                     name: "Foo",
2230                                     kind: Trait,
2231                                     description: "trait Foo<T>",
2232                                 },
2233                             },
2234                             HoverGotoTypeData {
2235                                 mod_path: "test::S",
2236                                 nav: NavigationTarget {
2237                                     file_id: FileId(
2238                                         0,
2239                                     ),
2240                                     full_range: 16..25,
2241                                     focus_range: 23..24,
2242                                     name: "S",
2243                                     kind: Struct,
2244                                     description: "struct S",
2245                                 },
2246                             },
2247                         ],
2248                     ),
2249                 ]
2250             "#]],
2251     );
2252 }
2253
2254 #[test]
2255 fn test_hover_return_impl_traits_has_goto_type_action() {
2256     check_actions(
2257         r#"
2258 trait Foo {}
2259 trait Bar {}
2260 fn foo() -> impl Foo + Bar {}
2261
2262 fn main() { let s$0t = foo(); }
2263 "#,
2264         expect![[r#"
2265                 [
2266                     GoToType(
2267                         [
2268                             HoverGotoTypeData {
2269                                 mod_path: "test::Foo",
2270                                 nav: NavigationTarget {
2271                                     file_id: FileId(
2272                                         0,
2273                                     ),
2274                                     full_range: 0..12,
2275                                     focus_range: 6..9,
2276                                     name: "Foo",
2277                                     kind: Trait,
2278                                     description: "trait Foo",
2279                                 },
2280                             },
2281                             HoverGotoTypeData {
2282                                 mod_path: "test::Bar",
2283                                 nav: NavigationTarget {
2284                                     file_id: FileId(
2285                                         0,
2286                                     ),
2287                                     full_range: 13..25,
2288                                     focus_range: 19..22,
2289                                     name: "Bar",
2290                                     kind: Trait,
2291                                     description: "trait Bar",
2292                                 },
2293                             },
2294                         ],
2295                     ),
2296                 ]
2297             "#]],
2298     );
2299 }
2300
2301 #[test]
2302 fn test_hover_generic_return_impl_traits_has_goto_type_action() {
2303     check_actions(
2304         r#"
2305 trait Foo<T> {}
2306 trait Bar<T> {}
2307 struct S1 {}
2308 struct S2 {}
2309
2310 fn foo() -> impl Foo<S1> + Bar<S2> {}
2311
2312 fn main() { let s$0t = foo(); }
2313 "#,
2314         expect![[r#"
2315                 [
2316                     GoToType(
2317                         [
2318                             HoverGotoTypeData {
2319                                 mod_path: "test::Foo",
2320                                 nav: NavigationTarget {
2321                                     file_id: FileId(
2322                                         0,
2323                                     ),
2324                                     full_range: 0..15,
2325                                     focus_range: 6..9,
2326                                     name: "Foo",
2327                                     kind: Trait,
2328                                     description: "trait Foo<T>",
2329                                 },
2330                             },
2331                             HoverGotoTypeData {
2332                                 mod_path: "test::Bar",
2333                                 nav: NavigationTarget {
2334                                     file_id: FileId(
2335                                         0,
2336                                     ),
2337                                     full_range: 16..31,
2338                                     focus_range: 22..25,
2339                                     name: "Bar",
2340                                     kind: Trait,
2341                                     description: "trait Bar<T>",
2342                                 },
2343                             },
2344                             HoverGotoTypeData {
2345                                 mod_path: "test::S1",
2346                                 nav: NavigationTarget {
2347                                     file_id: FileId(
2348                                         0,
2349                                     ),
2350                                     full_range: 32..44,
2351                                     focus_range: 39..41,
2352                                     name: "S1",
2353                                     kind: Struct,
2354                                     description: "struct S1",
2355                                 },
2356                             },
2357                             HoverGotoTypeData {
2358                                 mod_path: "test::S2",
2359                                 nav: NavigationTarget {
2360                                     file_id: FileId(
2361                                         0,
2362                                     ),
2363                                     full_range: 45..57,
2364                                     focus_range: 52..54,
2365                                     name: "S2",
2366                                     kind: Struct,
2367                                     description: "struct S2",
2368                                 },
2369                             },
2370                         ],
2371                     ),
2372                 ]
2373             "#]],
2374     );
2375 }
2376
2377 #[test]
2378 fn test_hover_arg_impl_trait_has_goto_type_action() {
2379     check_actions(
2380         r#"
2381 trait Foo {}
2382 fn foo(ar$0g: &impl Foo) {}
2383 "#,
2384         expect![[r#"
2385                 [
2386                     GoToType(
2387                         [
2388                             HoverGotoTypeData {
2389                                 mod_path: "test::Foo",
2390                                 nav: NavigationTarget {
2391                                     file_id: FileId(
2392                                         0,
2393                                     ),
2394                                     full_range: 0..12,
2395                                     focus_range: 6..9,
2396                                     name: "Foo",
2397                                     kind: Trait,
2398                                     description: "trait Foo",
2399                                 },
2400                             },
2401                         ],
2402                     ),
2403                 ]
2404             "#]],
2405     );
2406 }
2407
2408 #[test]
2409 fn test_hover_arg_impl_traits_has_goto_type_action() {
2410     check_actions(
2411         r#"
2412 trait Foo {}
2413 trait Bar<T> {}
2414 struct S{}
2415
2416 fn foo(ar$0g: &impl Foo + Bar<S>) {}
2417 "#,
2418         expect![[r#"
2419                 [
2420                     GoToType(
2421                         [
2422                             HoverGotoTypeData {
2423                                 mod_path: "test::Foo",
2424                                 nav: NavigationTarget {
2425                                     file_id: FileId(
2426                                         0,
2427                                     ),
2428                                     full_range: 0..12,
2429                                     focus_range: 6..9,
2430                                     name: "Foo",
2431                                     kind: Trait,
2432                                     description: "trait Foo",
2433                                 },
2434                             },
2435                             HoverGotoTypeData {
2436                                 mod_path: "test::Bar",
2437                                 nav: NavigationTarget {
2438                                     file_id: FileId(
2439                                         0,
2440                                     ),
2441                                     full_range: 13..28,
2442                                     focus_range: 19..22,
2443                                     name: "Bar",
2444                                     kind: Trait,
2445                                     description: "trait Bar<T>",
2446                                 },
2447                             },
2448                             HoverGotoTypeData {
2449                                 mod_path: "test::S",
2450                                 nav: NavigationTarget {
2451                                     file_id: FileId(
2452                                         0,
2453                                     ),
2454                                     full_range: 29..39,
2455                                     focus_range: 36..37,
2456                                     name: "S",
2457                                     kind: Struct,
2458                                     description: "struct S",
2459                                 },
2460                             },
2461                         ],
2462                     ),
2463                 ]
2464             "#]],
2465     );
2466 }
2467
2468 #[test]
2469 fn test_hover_async_block_impl_trait_has_goto_type_action() {
2470     check_actions(
2471         r#"
2472 //- /main.rs crate:main deps:core
2473 // we don't use minicore here so that this test doesn't randomly fail
2474 // when someone edits minicore
2475 struct S;
2476 fn foo() {
2477     let fo$0o = async { S };
2478 }
2479 //- /core.rs crate:core
2480 pub mod future {
2481     #[lang = "future_trait"]
2482     pub trait Future {}
2483 }
2484 "#,
2485         expect![[r#"
2486             [
2487                 GoToType(
2488                     [
2489                         HoverGotoTypeData {
2490                             mod_path: "core::future::Future",
2491                             nav: NavigationTarget {
2492                                 file_id: FileId(
2493                                     1,
2494                                 ),
2495                                 full_range: 21..69,
2496                                 focus_range: 60..66,
2497                                 name: "Future",
2498                                 kind: Trait,
2499                                 description: "pub trait Future",
2500                             },
2501                         },
2502                         HoverGotoTypeData {
2503                             mod_path: "main::S",
2504                             nav: NavigationTarget {
2505                                 file_id: FileId(
2506                                     0,
2507                                 ),
2508                                 full_range: 0..110,
2509                                 focus_range: 108..109,
2510                                 name: "S",
2511                                 kind: Struct,
2512                                 description: "struct S",
2513                             },
2514                         },
2515                     ],
2516                 ),
2517             ]
2518         "#]],
2519     );
2520 }
2521
2522 #[test]
2523 fn test_hover_arg_generic_impl_trait_has_goto_type_action() {
2524     check_actions(
2525         r#"
2526 trait Foo<T> {}
2527 struct S {}
2528 fn foo(ar$0g: &impl Foo<S>) {}
2529 "#,
2530         expect![[r#"
2531                 [
2532                     GoToType(
2533                         [
2534                             HoverGotoTypeData {
2535                                 mod_path: "test::Foo",
2536                                 nav: NavigationTarget {
2537                                     file_id: FileId(
2538                                         0,
2539                                     ),
2540                                     full_range: 0..15,
2541                                     focus_range: 6..9,
2542                                     name: "Foo",
2543                                     kind: Trait,
2544                                     description: "trait Foo<T>",
2545                                 },
2546                             },
2547                             HoverGotoTypeData {
2548                                 mod_path: "test::S",
2549                                 nav: NavigationTarget {
2550                                     file_id: FileId(
2551                                         0,
2552                                     ),
2553                                     full_range: 16..27,
2554                                     focus_range: 23..24,
2555                                     name: "S",
2556                                     kind: Struct,
2557                                     description: "struct S",
2558                                 },
2559                             },
2560                         ],
2561                     ),
2562                 ]
2563             "#]],
2564     );
2565 }
2566
2567 #[test]
2568 fn test_hover_dyn_return_has_goto_type_action() {
2569     check_actions(
2570         r#"
2571 trait Foo {}
2572 struct S;
2573 impl Foo for S {}
2574
2575 struct B<T>{}
2576 fn foo() -> B<dyn Foo> {}
2577
2578 fn main() { let s$0t = foo(); }
2579 "#,
2580         expect![[r#"
2581                 [
2582                     GoToType(
2583                         [
2584                             HoverGotoTypeData {
2585                                 mod_path: "test::B",
2586                                 nav: NavigationTarget {
2587                                     file_id: FileId(
2588                                         0,
2589                                     ),
2590                                     full_range: 42..55,
2591                                     focus_range: 49..50,
2592                                     name: "B",
2593                                     kind: Struct,
2594                                     description: "struct B<T>",
2595                                 },
2596                             },
2597                             HoverGotoTypeData {
2598                                 mod_path: "test::Foo",
2599                                 nav: NavigationTarget {
2600                                     file_id: FileId(
2601                                         0,
2602                                     ),
2603                                     full_range: 0..12,
2604                                     focus_range: 6..9,
2605                                     name: "Foo",
2606                                     kind: Trait,
2607                                     description: "trait Foo",
2608                                 },
2609                             },
2610                         ],
2611                     ),
2612                 ]
2613             "#]],
2614     );
2615 }
2616
2617 #[test]
2618 fn test_hover_dyn_arg_has_goto_type_action() {
2619     check_actions(
2620         r#"
2621 trait Foo {}
2622 fn foo(ar$0g: &dyn Foo) {}
2623 "#,
2624         expect![[r#"
2625                 [
2626                     GoToType(
2627                         [
2628                             HoverGotoTypeData {
2629                                 mod_path: "test::Foo",
2630                                 nav: NavigationTarget {
2631                                     file_id: FileId(
2632                                         0,
2633                                     ),
2634                                     full_range: 0..12,
2635                                     focus_range: 6..9,
2636                                     name: "Foo",
2637                                     kind: Trait,
2638                                     description: "trait Foo",
2639                                 },
2640                             },
2641                         ],
2642                     ),
2643                 ]
2644             "#]],
2645     );
2646 }
2647
2648 #[test]
2649 fn test_hover_generic_dyn_arg_has_goto_type_action() {
2650     check_actions(
2651         r#"
2652 trait Foo<T> {}
2653 struct S {}
2654 fn foo(ar$0g: &dyn Foo<S>) {}
2655 "#,
2656         expect![[r#"
2657                 [
2658                     GoToType(
2659                         [
2660                             HoverGotoTypeData {
2661                                 mod_path: "test::Foo",
2662                                 nav: NavigationTarget {
2663                                     file_id: FileId(
2664                                         0,
2665                                     ),
2666                                     full_range: 0..15,
2667                                     focus_range: 6..9,
2668                                     name: "Foo",
2669                                     kind: Trait,
2670                                     description: "trait Foo<T>",
2671                                 },
2672                             },
2673                             HoverGotoTypeData {
2674                                 mod_path: "test::S",
2675                                 nav: NavigationTarget {
2676                                     file_id: FileId(
2677                                         0,
2678                                     ),
2679                                     full_range: 16..27,
2680                                     focus_range: 23..24,
2681                                     name: "S",
2682                                     kind: Struct,
2683                                     description: "struct S",
2684                                 },
2685                             },
2686                         ],
2687                     ),
2688                 ]
2689             "#]],
2690     );
2691 }
2692
2693 #[test]
2694 fn test_hover_goto_type_action_links_order() {
2695     check_actions(
2696         r#"
2697 trait ImplTrait<T> {}
2698 trait DynTrait<T> {}
2699 struct B<T> {}
2700 struct S {}
2701
2702 fn foo(a$0rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
2703 "#,
2704         expect![[r#"
2705                 [
2706                     GoToType(
2707                         [
2708                             HoverGotoTypeData {
2709                                 mod_path: "test::ImplTrait",
2710                                 nav: NavigationTarget {
2711                                     file_id: FileId(
2712                                         0,
2713                                     ),
2714                                     full_range: 0..21,
2715                                     focus_range: 6..15,
2716                                     name: "ImplTrait",
2717                                     kind: Trait,
2718                                     description: "trait ImplTrait<T>",
2719                                 },
2720                             },
2721                             HoverGotoTypeData {
2722                                 mod_path: "test::B",
2723                                 nav: NavigationTarget {
2724                                     file_id: FileId(
2725                                         0,
2726                                     ),
2727                                     full_range: 43..57,
2728                                     focus_range: 50..51,
2729                                     name: "B",
2730                                     kind: Struct,
2731                                     description: "struct B<T>",
2732                                 },
2733                             },
2734                             HoverGotoTypeData {
2735                                 mod_path: "test::DynTrait",
2736                                 nav: NavigationTarget {
2737                                     file_id: FileId(
2738                                         0,
2739                                     ),
2740                                     full_range: 22..42,
2741                                     focus_range: 28..36,
2742                                     name: "DynTrait",
2743                                     kind: Trait,
2744                                     description: "trait DynTrait<T>",
2745                                 },
2746                             },
2747                             HoverGotoTypeData {
2748                                 mod_path: "test::S",
2749                                 nav: NavigationTarget {
2750                                     file_id: FileId(
2751                                         0,
2752                                     ),
2753                                     full_range: 58..69,
2754                                     focus_range: 65..66,
2755                                     name: "S",
2756                                     kind: Struct,
2757                                     description: "struct S",
2758                                 },
2759                             },
2760                         ],
2761                     ),
2762                 ]
2763             "#]],
2764     );
2765 }
2766
2767 #[test]
2768 fn test_hover_associated_type_has_goto_type_action() {
2769     check_actions(
2770         r#"
2771 trait Foo {
2772     type Item;
2773     fn get(self) -> Self::Item {}
2774 }
2775
2776 struct Bar{}
2777 struct S{}
2778
2779 impl Foo for S { type Item = Bar; }
2780
2781 fn test() -> impl Foo { S {} }
2782
2783 fn main() { let s$0t = test().get(); }
2784 "#,
2785         expect![[r#"
2786                 [
2787                     GoToType(
2788                         [
2789                             HoverGotoTypeData {
2790                                 mod_path: "test::Foo",
2791                                 nav: NavigationTarget {
2792                                     file_id: FileId(
2793                                         0,
2794                                     ),
2795                                     full_range: 0..62,
2796                                     focus_range: 6..9,
2797                                     name: "Foo",
2798                                     kind: Trait,
2799                                     description: "trait Foo",
2800                                 },
2801                             },
2802                         ],
2803                     ),
2804                 ]
2805             "#]],
2806     );
2807 }
2808
2809 #[test]
2810 fn test_hover_const_param_has_goto_type_action() {
2811     check_actions(
2812         r#"
2813 struct Bar;
2814 struct Foo<const BAR: Bar>;
2815
2816 impl<const BAR: Bar> Foo<BAR$0> {}
2817 "#,
2818         expect![[r#"
2819                 [
2820                     GoToType(
2821                         [
2822                             HoverGotoTypeData {
2823                                 mod_path: "test::Bar",
2824                                 nav: NavigationTarget {
2825                                     file_id: FileId(
2826                                         0,
2827                                     ),
2828                                     full_range: 0..11,
2829                                     focus_range: 7..10,
2830                                     name: "Bar",
2831                                     kind: Struct,
2832                                     description: "struct Bar",
2833                                 },
2834                             },
2835                         ],
2836                     ),
2837                 ]
2838             "#]],
2839     );
2840 }
2841
2842 #[test]
2843 fn test_hover_type_param_has_goto_type_action() {
2844     check_actions(
2845         r#"
2846 trait Foo {}
2847
2848 fn foo<T: Foo>(t: T$0){}
2849 "#,
2850         expect![[r#"
2851                 [
2852                     GoToType(
2853                         [
2854                             HoverGotoTypeData {
2855                                 mod_path: "test::Foo",
2856                                 nav: NavigationTarget {
2857                                     file_id: FileId(
2858                                         0,
2859                                     ),
2860                                     full_range: 0..12,
2861                                     focus_range: 6..9,
2862                                     name: "Foo",
2863                                     kind: Trait,
2864                                     description: "trait Foo",
2865                                 },
2866                             },
2867                         ],
2868                     ),
2869                 ]
2870             "#]],
2871     );
2872 }
2873
2874 #[test]
2875 fn test_hover_self_has_go_to_type() {
2876     check_actions(
2877         r#"
2878 struct Foo;
2879 impl Foo {
2880     fn foo(&self$0) {}
2881 }
2882 "#,
2883         expect![[r#"
2884                 [
2885                     GoToType(
2886                         [
2887                             HoverGotoTypeData {
2888                                 mod_path: "test::Foo",
2889                                 nav: NavigationTarget {
2890                                     file_id: FileId(
2891                                         0,
2892                                     ),
2893                                     full_range: 0..11,
2894                                     focus_range: 7..10,
2895                                     name: "Foo",
2896                                     kind: Struct,
2897                                     description: "struct Foo",
2898                                 },
2899                             },
2900                         ],
2901                     ),
2902                 ]
2903             "#]],
2904     );
2905 }
2906
2907 #[test]
2908 fn hover_displays_normalized_crate_names() {
2909     check(
2910         r#"
2911 //- /lib.rs crate:name-with-dashes
2912 pub mod wrapper {
2913     pub struct Thing { x: u32 }
2914
2915     impl Thing {
2916         pub fn new() -> Thing { Thing { x: 0 } }
2917     }
2918 }
2919
2920 //- /main.rs crate:main deps:name-with-dashes
2921 fn main() { let foo_test = name_with_dashes::wrapper::Thing::new$0(); }
2922 "#,
2923         expect![[r#"
2924             *new*
2925
2926             ```rust
2927             name_with_dashes::wrapper::Thing
2928             ```
2929
2930             ```rust
2931             pub fn new() -> Thing
2932             ```
2933             "#]],
2934     )
2935 }
2936
2937 #[test]
2938 fn hover_field_pat_shorthand_ref_match_ergonomics() {
2939     check(
2940         r#"
2941 struct S {
2942     f: i32,
2943 }
2944
2945 fn main() {
2946     let s = S { f: 0 };
2947     let S { f$0 } = &s;
2948 }
2949 "#,
2950         expect![[r#"
2951             *f*
2952
2953             ```rust
2954             f: &i32
2955             ```
2956             ---
2957
2958             ```rust
2959             test::S
2960             ```
2961
2962             ```rust
2963             f: i32
2964             ```
2965         "#]],
2966     );
2967 }
2968
2969 #[test]
2970 fn const_generic_order() {
2971     check(
2972         r#"
2973 struct Foo;
2974 struct S$0T<const C: usize = 1, T = Foo>(T);
2975 "#,
2976         expect![[r#"
2977             *ST*
2978
2979             ```rust
2980             test
2981             ```
2982
2983             ```rust
2984             struct ST<const C: usize, T = Foo>
2985             ```
2986         "#]],
2987     );
2988 }
2989
2990 #[test]
2991 fn const_generic_positive_i8_literal() {
2992     check(
2993         r#"
2994 struct Const<const N: i8>;
2995
2996 fn main() {
2997     let v$0alue = Const::<1>;
2998 }
2999 "#,
3000         expect![[r#"
3001             *value*
3002
3003             ```rust
3004             let value: Const<1>
3005             ```
3006         "#]],
3007     );
3008 }
3009
3010 #[test]
3011 fn const_generic_zero_i8_literal() {
3012     check(
3013         r#"
3014 struct Const<const N: i8>;
3015
3016 fn main() {
3017     let v$0alue = Const::<0>;
3018 }
3019 "#,
3020         expect![[r#"
3021             *value*
3022
3023             ```rust
3024             let value: Const<0>
3025             ```
3026         "#]],
3027     );
3028 }
3029
3030 #[test]
3031 fn const_generic_negative_i8_literal() {
3032     check(
3033         r#"
3034 struct Const<const N: i8>;
3035
3036 fn main() {
3037     let v$0alue = Const::<-1>;
3038 }
3039 "#,
3040         expect![[r#"
3041             *value*
3042
3043             ```rust
3044             let value: Const<-1>
3045             ```
3046         "#]],
3047     );
3048 }
3049
3050 #[test]
3051 fn const_generic_bool_literal() {
3052     check(
3053         r#"
3054 struct Const<const F: bool>;
3055
3056 fn main() {
3057     let v$0alue = Const::<true>;
3058 }
3059 "#,
3060         expect![[r#"
3061             *value*
3062
3063             ```rust
3064             let value: Const<true>
3065             ```
3066         "#]],
3067     );
3068 }
3069
3070 #[test]
3071 fn const_generic_char_literal() {
3072     check(
3073         r#"
3074 struct Const<const C: char>;
3075
3076 fn main() {
3077     let v$0alue = Const::<'🦀'>;
3078 }
3079 "#,
3080         expect![[r#"
3081             *value*
3082
3083             ```rust
3084             let value: Const<'🦀'>
3085             ```
3086         "#]],
3087     );
3088 }
3089
3090 #[test]
3091 fn hover_self_param_shows_type() {
3092     check(
3093         r#"
3094 struct Foo {}
3095 impl Foo {
3096     fn bar(&sel$0f) {}
3097 }
3098 "#,
3099         expect![[r#"
3100                 *self*
3101
3102                 ```rust
3103                 self: &Foo
3104                 ```
3105             "#]],
3106     );
3107 }
3108
3109 #[test]
3110 fn hover_self_param_shows_type_for_arbitrary_self_type() {
3111     check(
3112         r#"
3113 struct Arc<T>(T);
3114 struct Foo {}
3115 impl Foo {
3116     fn bar(sel$0f: Arc<Foo>) {}
3117 }
3118 "#,
3119         expect![[r#"
3120                 *self*
3121
3122                 ```rust
3123                 self: Arc<Foo>
3124                 ```
3125             "#]],
3126     );
3127 }
3128
3129 #[test]
3130 fn hover_doc_outer_inner() {
3131     check(
3132         r#"
3133 /// Be quick;
3134 mod Foo$0 {
3135     //! time is mana
3136
3137     /// This comment belongs to the function
3138     fn foo() {}
3139 }
3140 "#,
3141         expect![[r#"
3142                 *Foo*
3143
3144                 ```rust
3145                 test
3146                 ```
3147
3148                 ```rust
3149                 mod Foo
3150                 ```
3151
3152                 ---
3153
3154                 Be quick;
3155                 time is mana
3156             "#]],
3157     );
3158 }
3159
3160 #[test]
3161 fn hover_doc_outer_inner_attribue() {
3162     check(
3163         r#"
3164 #[doc = "Be quick;"]
3165 mod Foo$0 {
3166     #![doc = "time is mana"]
3167
3168     #[doc = "This comment belongs to the function"]
3169     fn foo() {}
3170 }
3171 "#,
3172         expect![[r#"
3173                 *Foo*
3174
3175                 ```rust
3176                 test
3177                 ```
3178
3179                 ```rust
3180                 mod Foo
3181                 ```
3182
3183                 ---
3184
3185                 Be quick;
3186                 time is mana
3187             "#]],
3188     );
3189 }
3190
3191 #[test]
3192 fn hover_doc_block_style_indentend() {
3193     check(
3194         r#"
3195 /**
3196     foo
3197     ```rust
3198     let x = 3;
3199     ```
3200 */
3201 fn foo$0() {}
3202 "#,
3203         expect![[r#"
3204                 *foo*
3205
3206                 ```rust
3207                 test
3208                 ```
3209
3210                 ```rust
3211                 fn foo()
3212                 ```
3213
3214                 ---
3215
3216                 foo
3217
3218                 ```rust
3219                 let x = 3;
3220                 ```
3221             "#]],
3222     );
3223 }
3224
3225 #[test]
3226 fn hover_comments_dont_highlight_parent() {
3227     cov_mark::check!(no_highlight_on_comment_hover);
3228     check_hover_no_result(
3229         r#"
3230 fn no_hover() {
3231     // no$0hover
3232 }
3233 "#,
3234     );
3235 }
3236
3237 #[test]
3238 fn hover_label() {
3239     check(
3240         r#"
3241 fn foo() {
3242     'label$0: loop {}
3243 }
3244 "#,
3245         expect![[r#"
3246             *'label*
3247
3248             ```rust
3249             'label
3250             ```
3251             "#]],
3252     );
3253 }
3254
3255 #[test]
3256 fn hover_lifetime() {
3257     check(
3258         r#"fn foo<'lifetime>(_: &'lifetime$0 ()) {}"#,
3259         expect![[r#"
3260             *'lifetime*
3261
3262             ```rust
3263             'lifetime
3264             ```
3265             "#]],
3266     );
3267 }
3268
3269 #[test]
3270 fn hover_type_param() {
3271     check(
3272         r#"
3273 //- minicore: sized
3274 struct Foo<T>(T);
3275 trait TraitA {}
3276 trait TraitB {}
3277 impl<T: TraitA + TraitB> Foo<T$0> where T: Sized {}
3278 "#,
3279         expect![[r#"
3280                 *T*
3281
3282                 ```rust
3283                 T: TraitA + TraitB
3284                 ```
3285             "#]],
3286     );
3287     check(
3288         r#"
3289 //- minicore: sized
3290 struct Foo<T>(T);
3291 impl<T> Foo<T$0> {}
3292 "#,
3293         expect![[r#"
3294                 *T*
3295
3296                 ```rust
3297                 T
3298                 ```
3299                 "#]],
3300     );
3301     // lifetimes bounds arent being tracked yet
3302     check(
3303         r#"
3304 //- minicore: sized
3305 struct Foo<T>(T);
3306 impl<T: 'static> Foo<T$0> {}
3307 "#,
3308         expect![[r#"
3309                 *T*
3310
3311                 ```rust
3312                 T
3313                 ```
3314                 "#]],
3315     );
3316 }
3317
3318 #[test]
3319 fn hover_type_param_sized_bounds() {
3320     // implicit `: Sized` bound
3321     check(
3322         r#"
3323 //- minicore: sized
3324 trait Trait {}
3325 struct Foo<T>(T);
3326 impl<T: Trait> Foo<T$0> {}
3327 "#,
3328         expect![[r#"
3329                 *T*
3330
3331                 ```rust
3332                 T: Trait
3333                 ```
3334             "#]],
3335     );
3336     check(
3337         r#"
3338 //- minicore: sized
3339 trait Trait {}
3340 struct Foo<T>(T);
3341 impl<T: Trait + ?Sized> Foo<T$0> {}
3342 "#,
3343         expect![[r#"
3344                 *T*
3345
3346                 ```rust
3347                 T: Trait + ?Sized
3348                 ```
3349             "#]],
3350     );
3351 }
3352
3353 mod type_param_sized_bounds {
3354     use super::*;
3355
3356     #[test]
3357     fn single_implicit() {
3358         check(
3359             r#"
3360 //- minicore: sized
3361 fn foo<T$0>() {}
3362 "#,
3363             expect![[r#"
3364                     *T*
3365
3366                     ```rust
3367                     T
3368                     ```
3369                 "#]],
3370         );
3371     }
3372
3373     #[test]
3374     fn single_explicit() {
3375         check(
3376             r#"
3377 //- minicore: sized
3378 fn foo<T$0: Sized>() {}
3379 "#,
3380             expect![[r#"
3381                     *T*
3382
3383                     ```rust
3384                     T
3385                     ```
3386                 "#]],
3387         );
3388     }
3389
3390     #[test]
3391     fn single_relaxed() {
3392         check(
3393             r#"
3394 //- minicore: sized
3395 fn foo<T$0: ?Sized>() {}
3396 "#,
3397             expect![[r#"
3398                     *T*
3399
3400                     ```rust
3401                     T: ?Sized
3402                     ```
3403                 "#]],
3404         );
3405     }
3406
3407     #[test]
3408     fn multiple_implicit() {
3409         check(
3410             r#"
3411 //- minicore: sized
3412 trait Trait {}
3413 fn foo<T$0: Trait>() {}
3414 "#,
3415             expect![[r#"
3416                     *T*
3417
3418                     ```rust
3419                     T: Trait
3420                     ```
3421                 "#]],
3422         );
3423     }
3424
3425     #[test]
3426     fn multiple_explicit() {
3427         check(
3428             r#"
3429 //- minicore: sized
3430 trait Trait {}
3431 fn foo<T$0: Trait + Sized>() {}
3432 "#,
3433             expect![[r#"
3434                     *T*
3435
3436                     ```rust
3437                     T: Trait
3438                     ```
3439                 "#]],
3440         );
3441     }
3442
3443     #[test]
3444     fn multiple_relaxed() {
3445         check(
3446             r#"
3447 //- minicore: sized
3448 trait Trait {}
3449 fn foo<T$0: Trait + ?Sized>() {}
3450 "#,
3451             expect![[r#"
3452                     *T*
3453
3454                     ```rust
3455                     T: Trait + ?Sized
3456                     ```
3457                 "#]],
3458         );
3459     }
3460
3461     #[test]
3462     fn mixed() {
3463         check(
3464             r#"
3465 //- minicore: sized
3466 fn foo<T$0: ?Sized + Sized + Sized>() {}
3467 "#,
3468             expect![[r#"
3469                     *T*
3470
3471                     ```rust
3472                     T
3473                     ```
3474                 "#]],
3475         );
3476         check(
3477             r#"
3478 //- minicore: sized
3479 trait Trait {}
3480 fn foo<T$0: Sized + ?Sized + Sized + Trait>() {}
3481 "#,
3482             expect![[r#"
3483                     *T*
3484
3485                     ```rust
3486                     T: Trait
3487                     ```
3488                 "#]],
3489         );
3490     }
3491 }
3492
3493 #[test]
3494 fn hover_const_generic_type_alias() {
3495     check(
3496         r#"
3497 struct Foo<const LEN: usize>;
3498 type Fo$0o2 = Foo<2>;
3499 "#,
3500         expect![[r#"
3501                 *Foo2*
3502
3503                 ```rust
3504                 test
3505                 ```
3506
3507                 ```rust
3508                 type Foo2 = Foo<2>
3509                 ```
3510             "#]],
3511     );
3512 }
3513
3514 #[test]
3515 fn hover_const_param() {
3516     check(
3517         r#"
3518 struct Foo<const LEN: usize>;
3519 impl<const LEN: usize> Foo<LEN$0> {}
3520 "#,
3521         expect![[r#"
3522                 *LEN*
3523
3524                 ```rust
3525                 const LEN: usize
3526                 ```
3527             "#]],
3528     );
3529 }
3530
3531 #[test]
3532 fn hover_const_eval_variant() {
3533     // show hex for <10
3534     check(
3535         r#"
3536 #[repr(u8)]
3537 enum E {
3538     /// This is a doc
3539     A$0 = 1 << 3,
3540 }
3541 "#,
3542         expect![[r#"
3543             *A*
3544
3545             ```rust
3546             test::E
3547             ```
3548
3549             ```rust
3550             A = 8
3551             ```
3552
3553             ---
3554
3555             This is a doc
3556         "#]],
3557     );
3558     // show hex for >10
3559     check(
3560         r#"
3561 #[repr(u8)]
3562 enum E {
3563     /// This is a doc
3564     A$0 = (1 << 3) + (1 << 2),
3565 }
3566 "#,
3567         expect![[r#"
3568             *A*
3569
3570             ```rust
3571             test::E
3572             ```
3573
3574             ```rust
3575             A = 12 (0xC)
3576             ```
3577
3578             ---
3579
3580             This is a doc
3581         "#]],
3582     );
3583     // enums in const eval
3584     check(
3585         r#"
3586 #[repr(u8)]
3587 enum E {
3588     A = 1,
3589     /// This is a doc
3590     B$0 = E::A as u8 + 1,
3591 }
3592 "#,
3593         expect![[r#"
3594             *B*
3595
3596             ```rust
3597             test::E
3598             ```
3599
3600             ```rust
3601             B = 2
3602             ```
3603
3604             ---
3605
3606             This is a doc
3607         "#]],
3608     );
3609     // unspecified variant should increment by one
3610     check(
3611         r#"
3612 #[repr(u8)]
3613 enum E {
3614     A = 4,
3615     /// This is a doc
3616     B$0,
3617 }
3618 "#,
3619         expect![[r#"
3620             *B*
3621
3622             ```rust
3623             test::E
3624             ```
3625
3626             ```rust
3627             B = 5
3628             ```
3629
3630             ---
3631
3632             This is a doc
3633         "#]],
3634     );
3635 }
3636
3637 #[test]
3638 fn hover_const_eval() {
3639     // show hex for <10
3640     check(
3641         r#"
3642 /// This is a doc
3643 const FOO$0: usize = 1 << 3;
3644 "#,
3645         expect![[r#"
3646             *FOO*
3647
3648             ```rust
3649             test
3650             ```
3651
3652             ```rust
3653             const FOO: usize = 8
3654             ```
3655
3656             ---
3657
3658             This is a doc
3659         "#]],
3660     );
3661     // show hex for >10
3662     check(
3663         r#"
3664 /// This is a doc
3665 const FOO$0: usize = (1 << 3) + (1 << 2);
3666 "#,
3667         expect![[r#"
3668             *FOO*
3669
3670             ```rust
3671             test
3672             ```
3673
3674             ```rust
3675             const FOO: usize = 12 (0xC)
3676             ```
3677
3678             ---
3679
3680             This is a doc
3681         "#]],
3682     );
3683     // show original body when const eval fails
3684     check(
3685         r#"
3686 /// This is a doc
3687 const FOO$0: usize = 2 - 3;
3688 "#,
3689         expect![[r#"
3690             *FOO*
3691
3692             ```rust
3693             test
3694             ```
3695
3696             ```rust
3697             const FOO: usize = 2 - 3
3698             ```
3699
3700             ---
3701
3702             This is a doc
3703         "#]],
3704     );
3705     // don't show hex for negatives
3706     check(
3707         r#"
3708 /// This is a doc
3709 const FOO$0: i32 = 2 - 3;
3710 "#,
3711         expect![[r#"
3712             *FOO*
3713
3714             ```rust
3715             test
3716             ```
3717
3718             ```rust
3719             const FOO: i32 = -1
3720             ```
3721
3722             ---
3723
3724             This is a doc
3725         "#]],
3726     );
3727     check(
3728         r#"
3729 /// This is a doc
3730 const FOO$0: &str = "bar";
3731 "#,
3732         expect![[r#"
3733             *FOO*
3734
3735             ```rust
3736             test
3737             ```
3738
3739             ```rust
3740             const FOO: &str = "bar"
3741             ```
3742
3743             ---
3744
3745             This is a doc
3746         "#]],
3747     );
3748     // show char literal
3749     check(
3750         r#"
3751 /// This is a doc
3752 const FOO$0: char = 'a';
3753 "#,
3754         expect![[r#"
3755             *FOO*
3756
3757             ```rust
3758             test
3759             ```
3760
3761             ```rust
3762             const FOO: char = 'a'
3763             ```
3764
3765             ---
3766
3767             This is a doc
3768         "#]],
3769     );
3770     // show escaped char literal
3771     check(
3772         r#"
3773 /// This is a doc
3774 const FOO$0: char = '\x61';
3775 "#,
3776         expect![[r#"
3777             *FOO*
3778
3779             ```rust
3780             test
3781             ```
3782
3783             ```rust
3784             const FOO: char = 'a'
3785             ```
3786
3787             ---
3788
3789             This is a doc
3790         "#]],
3791     );
3792     // show byte literal
3793     check(
3794         r#"
3795 /// This is a doc
3796 const FOO$0: u8 = b'a';
3797 "#,
3798         expect![[r#"
3799             *FOO*
3800
3801             ```rust
3802             test
3803             ```
3804
3805             ```rust
3806             const FOO: u8 = 97 (0x61)
3807             ```
3808
3809             ---
3810
3811             This is a doc
3812         "#]],
3813     );
3814     // show escaped byte literal
3815     check(
3816         r#"
3817 /// This is a doc
3818 const FOO$0: u8 = b'\x61';
3819 "#,
3820         expect![[r#"
3821             *FOO*
3822
3823             ```rust
3824             test
3825             ```
3826
3827             ```rust
3828             const FOO: u8 = 97 (0x61)
3829             ```
3830
3831             ---
3832
3833             This is a doc
3834         "#]],
3835     );
3836     // show float literal
3837     check(
3838         r#"
3839     /// This is a doc
3840     const FOO$0: f64 = 1.0234;
3841     "#,
3842         expect![[r#"
3843             *FOO*
3844
3845             ```rust
3846             test
3847             ```
3848
3849             ```rust
3850             const FOO: f64 = 1.0234
3851             ```
3852
3853             ---
3854
3855             This is a doc
3856         "#]],
3857     );
3858     //show float typecasted from int
3859     check(
3860         r#"
3861 /// This is a doc
3862 const FOO$0: f32 = 1f32;
3863 "#,
3864         expect![[r#"
3865             *FOO*
3866
3867             ```rust
3868             test
3869             ```
3870
3871             ```rust
3872             const FOO: f32 = 1.0
3873             ```
3874
3875             ---
3876
3877             This is a doc
3878         "#]],
3879     );
3880     //show f64 typecasted from float
3881     check(
3882         r#"
3883 /// This is a doc
3884 const FOO$0: f64 = 1.0f64;
3885 "#,
3886         expect![[r#"
3887             *FOO*
3888
3889             ```rust
3890             test
3891             ```
3892
3893             ```rust
3894             const FOO: f64 = 1.0
3895             ```
3896
3897             ---
3898
3899             This is a doc
3900         "#]],
3901     );
3902 }
3903
3904 #[test]
3905 fn hover_const_pat() {
3906     check(
3907         r#"
3908 /// This is a doc
3909 const FOO: usize = 3;
3910 fn foo() {
3911     match 5 {
3912         FOO$0 => (),
3913         _ => ()
3914     }
3915 }
3916 "#,
3917         expect![[r#"
3918             *FOO*
3919
3920             ```rust
3921             test
3922             ```
3923
3924             ```rust
3925             const FOO: usize = 3
3926             ```
3927
3928             ---
3929
3930             This is a doc
3931         "#]],
3932     );
3933     check(
3934         r#"
3935 enum E {
3936     /// This is a doc
3937     A = 3,
3938 }
3939 fn foo(e: E) {
3940     match e {
3941         E::A$0 => (),
3942         _ => ()
3943     }
3944 }
3945 "#,
3946         expect![[r#"
3947             *A*
3948
3949             ```rust
3950             test::E
3951             ```
3952
3953             ```rust
3954             A = 3
3955             ```
3956
3957             ---
3958
3959             This is a doc
3960         "#]],
3961     );
3962 }
3963
3964 #[test]
3965 fn array_repeat_exp() {
3966     check(
3967         r#"
3968 fn main() {
3969     let til$0e4 = [0_u32; (4 * 8 * 8) / 32];
3970 }
3971         "#,
3972         expect![[r#"
3973             *tile4*
3974
3975             ```rust
3976             let tile4: [u32; 8]
3977             ```
3978             "#]],
3979     );
3980 }
3981
3982 #[test]
3983 fn hover_mod_def() {
3984     check(
3985         r#"
3986 //- /main.rs
3987 mod foo$0;
3988 //- /foo.rs
3989 //! For the horde!
3990 "#,
3991         expect![[r#"
3992                 *foo*
3993
3994                 ```rust
3995                 test
3996                 ```
3997
3998                 ```rust
3999                 mod foo
4000                 ```
4001
4002                 ---
4003
4004                 For the horde!
4005             "#]],
4006     );
4007 }
4008
4009 #[test]
4010 fn hover_self_in_use() {
4011     check(
4012         r#"
4013 //! This should not appear
4014 mod foo {
4015     /// But this should appear
4016     pub mod bar {}
4017 }
4018 use foo::bar::{self$0};
4019 "#,
4020         expect![[r#"
4021                 *self*
4022
4023                 ```rust
4024                 test::foo
4025                 ```
4026
4027                 ```rust
4028                 mod bar
4029                 ```
4030
4031                 ---
4032
4033                 But this should appear
4034             "#]],
4035     )
4036 }
4037
4038 #[test]
4039 fn hover_keyword() {
4040     check(
4041         r#"
4042 //- /main.rs crate:main deps:std
4043 fn f() { retur$0n; }
4044 //- /libstd.rs crate:std
4045 /// Docs for return_keyword
4046 mod return_keyword {}
4047 "#,
4048         expect![[r#"
4049                 *return*
4050
4051                 ```rust
4052                 return
4053                 ```
4054
4055                 ---
4056
4057                 Docs for return_keyword
4058             "#]],
4059     );
4060 }
4061
4062 #[test]
4063 fn hover_keyword_doc() {
4064     check(
4065         r#"
4066 //- /main.rs crate:main deps:std
4067 fn foo() {
4068     let bar = mov$0e || {};
4069 }
4070 //- /libstd.rs crate:std
4071 #[doc(keyword = "move")]
4072 /// [closure]
4073 /// [closures][closure]
4074 /// [threads]
4075 /// <https://doc.rust-lang.org/nightly/book/ch13-01-closures.html>
4076 ///
4077 /// [closure]: ../book/ch13-01-closures.html
4078 /// [threads]: ../book/ch16-01-threads.html#using-move-closures-with-threads
4079 mod move_keyword {}
4080 "#,
4081         expect![[r##"
4082             *move*
4083
4084             ```rust
4085             move
4086             ```
4087
4088             ---
4089
4090             [closure](https://doc.rust-lang.org/nightly/book/ch13-01-closures.html)
4091             [closures](https://doc.rust-lang.org/nightly/book/ch13-01-closures.html)
4092             [threads](https://doc.rust-lang.org/nightly/book/ch16-01-threads.html#using-move-closures-with-threads)
4093             <https://doc.rust-lang.org/nightly/book/ch13-01-closures.html>
4094         "##]],
4095     );
4096 }
4097
4098 #[test]
4099 fn hover_keyword_as_primitive() {
4100     check(
4101         r#"
4102 //- /main.rs crate:main deps:std
4103 type F = f$0n(i32) -> i32;
4104 //- /libstd.rs crate:std
4105 /// Docs for prim_fn
4106 mod prim_fn {}
4107 "#,
4108         expect![[r#"
4109                 *fn*
4110
4111                 ```rust
4112                 fn
4113                 ```
4114
4115                 ---
4116
4117                 Docs for prim_fn
4118             "#]],
4119     );
4120 }
4121
4122 #[test]
4123 fn hover_builtin() {
4124     check(
4125         r#"
4126 //- /main.rs crate:main deps:std
4127 cosnt _: &str$0 = ""; }
4128
4129 //- /libstd.rs crate:std
4130 /// Docs for prim_str
4131 /// [`foo`](../std/keyword.foo.html)
4132 mod prim_str {}
4133 "#,
4134         expect![[r#"
4135                 *str*
4136
4137                 ```rust
4138                 str
4139                 ```
4140
4141                 ---
4142
4143                 Docs for prim_str
4144                 [`foo`](https://doc.rust-lang.org/nightly/std/keyword.foo.html)
4145             "#]],
4146     );
4147 }
4148
4149 #[test]
4150 fn hover_macro_expanded_function() {
4151     check(
4152         r#"
4153 struct S<'a, T>(&'a T);
4154 trait Clone {}
4155 macro_rules! foo {
4156     () => {
4157         fn bar<'t, T: Clone + 't>(s: &mut S<'t, T>, t: u32) -> *mut u32 where
4158             't: 't + 't,
4159             for<'a> T: Clone + 'a
4160         { 0 as _ }
4161     };
4162 }
4163
4164 foo!();
4165
4166 fn main() {
4167     bar$0;
4168 }
4169 "#,
4170         expect![[r#"
4171                 *bar*
4172
4173                 ```rust
4174                 test
4175                 ```
4176
4177                 ```rust
4178                 fn bar<'t, T>(s: &mut S<'t, T>, t: u32) -> *mut u32
4179                 where
4180                     T: Clone + 't,
4181                     't: 't + 't,
4182                     for<'a> T: Clone + 'a,
4183                 ```
4184             "#]],
4185     )
4186 }
4187
4188 #[test]
4189 fn hover_intra_doc_links() {
4190     check(
4191         r#"
4192
4193 pub mod theitem {
4194     /// This is the item. Cool!
4195     pub struct TheItem;
4196 }
4197
4198 /// Gives you a [`TheItem$0`].
4199 ///
4200 /// [`TheItem`]: theitem::TheItem
4201 pub fn gimme() -> theitem::TheItem {
4202     theitem::TheItem
4203 }
4204 "#,
4205         expect![[r#"
4206                 *[`TheItem`]*
4207
4208                 ```rust
4209                 test::theitem
4210                 ```
4211
4212                 ```rust
4213                 pub struct TheItem
4214                 ```
4215
4216                 ---
4217
4218                 This is the item. Cool!
4219             "#]],
4220     );
4221 }
4222
4223 #[test]
4224 fn test_hover_trait_assoc_typealias() {
4225     check(
4226         r#"
4227         fn main() {}
4228
4229 trait T1 {
4230     type Bar;
4231     type Baz;
4232 }
4233
4234 struct Foo;
4235
4236 mod t2 {
4237     pub trait T2 {
4238         type Bar;
4239     }
4240 }
4241
4242 use t2::T2;
4243
4244 impl T2 for Foo {
4245     type Bar = String;
4246 }
4247
4248 impl T1 for Foo {
4249     type Bar = <Foo as t2::T2>::Ba$0r;
4250     //                          ^^^ unresolvedReference
4251 }
4252         "#,
4253         expect![[r#"
4254 *Bar*
4255
4256 ```rust
4257 test::t2
4258 ```
4259
4260 ```rust
4261 pub type Bar
4262 ```
4263 "#]],
4264     );
4265 }
4266 #[test]
4267 fn hover_generic_assoc() {
4268     check(
4269         r#"
4270 fn foo<T: A>() where T::Assoc$0: {}
4271
4272 trait A {
4273     type Assoc;
4274 }"#,
4275         expect![[r#"
4276                 *Assoc*
4277
4278                 ```rust
4279                 test
4280                 ```
4281
4282                 ```rust
4283                 type Assoc
4284                 ```
4285             "#]],
4286     );
4287     check(
4288         r#"
4289 fn foo<T: A>() {
4290     let _: <T>::Assoc$0;
4291 }
4292
4293 trait A {
4294     type Assoc;
4295 }"#,
4296         expect![[r#"
4297                 *Assoc*
4298
4299                 ```rust
4300                 test
4301                 ```
4302
4303                 ```rust
4304                 type Assoc
4305                 ```
4306             "#]],
4307     );
4308     check(
4309         r#"
4310 trait A where
4311     Self::Assoc$0: ,
4312 {
4313     type Assoc;
4314 }"#,
4315         expect![[r#"
4316                 *Assoc*
4317
4318                 ```rust
4319                 test
4320                 ```
4321
4322                 ```rust
4323                 type Assoc
4324                 ```
4325             "#]],
4326     );
4327 }
4328
4329 #[test]
4330 fn string_shadowed_with_inner_items() {
4331     check(
4332         r#"
4333 //- /main.rs crate:main deps:alloc
4334
4335 /// Custom `String` type.
4336 struct String;
4337
4338 fn f() {
4339     let _: String$0;
4340
4341     fn inner() {}
4342 }
4343
4344 //- /alloc.rs crate:alloc
4345 #[prelude_import]
4346 pub use string::*;
4347
4348 mod string {
4349     /// This is `alloc::String`.
4350     pub struct String;
4351 }
4352 "#,
4353         expect![[r#"
4354                 *String*
4355
4356                 ```rust
4357                 main
4358                 ```
4359
4360                 ```rust
4361                 struct String
4362                 ```
4363
4364                 ---
4365
4366                 Custom `String` type.
4367             "#]],
4368     )
4369 }
4370
4371 #[test]
4372 fn function_doesnt_shadow_crate_in_use_tree() {
4373     check(
4374         r#"
4375 //- /main.rs crate:main deps:foo
4376 use foo$0::{foo};
4377
4378 //- /foo.rs crate:foo
4379 pub fn foo() {}
4380 "#,
4381         expect![[r#"
4382                 *foo*
4383
4384                 ```rust
4385                 extern crate foo
4386                 ```
4387             "#]],
4388     )
4389 }
4390
4391 #[test]
4392 fn hover_feature() {
4393     check(
4394         r#"#![feature(box_syntax$0)]"#,
4395         expect![[r##"
4396                 *box_syntax*
4397                 ```
4398                 box_syntax
4399                 ```
4400                 ___
4401
4402                 # `box_syntax`
4403
4404                 The tracking issue for this feature is: [#49733]
4405
4406                 [#49733]: https://github.com/rust-lang/rust/issues/49733
4407
4408                 See also [`box_patterns`](box-patterns.md)
4409
4410                 ------------------------
4411
4412                 Currently the only stable way to create a `Box` is via the `Box::new` method.
4413                 Also it is not possible in stable Rust to destructure a `Box` in a match
4414                 pattern. The unstable `box` keyword can be used to create a `Box`. An example
4415                 usage would be:
4416
4417                 ```rust
4418                 #![feature(box_syntax)]
4419
4420                 fn main() {
4421                     let b = box 5;
4422                 }
4423                 ```
4424
4425             "##]],
4426     )
4427 }
4428
4429 #[test]
4430 fn hover_lint() {
4431     check(
4432         r#"#![allow(arithmetic_overflow$0)]"#,
4433         expect![[r#"
4434                 *arithmetic_overflow*
4435                 ```
4436                 arithmetic_overflow
4437                 ```
4438                 ___
4439
4440                 arithmetic operation overflows
4441             "#]],
4442     )
4443 }
4444
4445 #[test]
4446 fn hover_clippy_lint() {
4447     check(
4448         r#"#![allow(clippy::almost_swapped$0)]"#,
4449         expect![[r#"
4450                 *almost_swapped*
4451                 ```
4452                 clippy::almost_swapped
4453                 ```
4454                 ___
4455
4456                 Checks for `foo = bar; bar = foo` sequences.
4457             "#]],
4458     )
4459 }
4460
4461 #[test]
4462 fn hover_attr_path_qualifier() {
4463     check(
4464         r#"
4465 //- /foo.rs crate:foo
4466
4467 //- /lib.rs crate:main.rs deps:foo
4468 #[fo$0o::bar()]
4469 struct Foo;
4470 "#,
4471         expect![[r#"
4472                 *foo*
4473
4474                 ```rust
4475                 extern crate foo
4476                 ```
4477             "#]],
4478     )
4479 }
4480
4481 #[test]
4482 fn hover_rename() {
4483     check(
4484         r#"
4485 use self as foo$0;
4486 "#,
4487         expect![[r#"
4488                 *foo*
4489
4490                 ```rust
4491                 extern crate test
4492                 ```
4493             "#]],
4494     );
4495     check(
4496         r#"
4497 mod bar {}
4498 use bar::{self as foo$0};
4499 "#,
4500         expect![[r#"
4501                 *foo*
4502
4503                 ```rust
4504                 test
4505                 ```
4506
4507                 ```rust
4508                 mod bar
4509                 ```
4510             "#]],
4511     );
4512     check(
4513         r#"
4514 mod bar {
4515     use super as foo$0;
4516 }
4517 "#,
4518         expect![[r#"
4519                 *foo*
4520
4521                 ```rust
4522                 extern crate test
4523                 ```
4524             "#]],
4525     );
4526     check(
4527         r#"
4528 use crate as foo$0;
4529 "#,
4530         expect![[r#"
4531                 *foo*
4532
4533                 ```rust
4534                 extern crate test
4535                 ```
4536             "#]],
4537     );
4538 }
4539
4540 #[test]
4541 fn hover_attribute_in_macro() {
4542     check(
4543         r#"
4544 //- minicore:derive
4545 macro_rules! identity {
4546     ($struct:item) => {
4547         $struct
4548     };
4549 }
4550 #[rustc_builtin_macro]
4551 pub macro Copy {}
4552 identity!{
4553     #[derive(Copy$0)]
4554     struct Foo;
4555 }
4556 "#,
4557         expect![[r#"
4558             *Copy*
4559
4560             ```rust
4561             test
4562             ```
4563
4564             ```rust
4565             macro Copy
4566             ```
4567         "#]],
4568     );
4569 }
4570
4571 #[test]
4572 fn hover_derive_input() {
4573     check(
4574         r#"
4575 //- minicore:derive
4576 #[rustc_builtin_macro]
4577 pub macro Copy {}
4578 #[derive(Copy$0)]
4579 struct Foo;
4580 "#,
4581         expect![[r#"
4582             *Copy*
4583
4584             ```rust
4585             test
4586             ```
4587
4588             ```rust
4589             macro Copy
4590             ```
4591         "#]],
4592     );
4593     check(
4594         r#"
4595 //- minicore:derive
4596 mod foo {
4597     #[rustc_builtin_macro]
4598     pub macro Copy {}
4599 }
4600 #[derive(foo::Copy$0)]
4601 struct Foo;
4602 "#,
4603         expect![[r#"
4604             *Copy*
4605
4606             ```rust
4607             test::foo
4608             ```
4609
4610             ```rust
4611             macro Copy
4612             ```
4613         "#]],
4614     );
4615 }
4616
4617 #[test]
4618 fn hover_range_math() {
4619     check_hover_range(
4620         r#"
4621 fn f() { let expr = $01 + 2 * 3$0 }
4622 "#,
4623         expect![[r#"
4624             ```rust
4625             i32
4626             ```"#]],
4627     );
4628
4629     check_hover_range(
4630         r#"
4631 fn f() { let expr = 1 $0+ 2 * $03 }
4632 "#,
4633         expect![[r#"
4634             ```rust
4635             i32
4636             ```"#]],
4637     );
4638
4639     check_hover_range(
4640         r#"
4641 fn f() { let expr = 1 + $02 * 3$0 }
4642 "#,
4643         expect![[r#"
4644             ```rust
4645             i32
4646             ```"#]],
4647     );
4648 }
4649
4650 #[test]
4651 fn hover_range_arrays() {
4652     check_hover_range(
4653         r#"
4654 fn f() { let expr = $0[1, 2, 3, 4]$0 }
4655 "#,
4656         expect![[r#"
4657             ```rust
4658             [i32; 4]
4659             ```"#]],
4660     );
4661
4662     check_hover_range(
4663         r#"
4664 fn f() { let expr = [1, 2, $03, 4]$0 }
4665 "#,
4666         expect![[r#"
4667             ```rust
4668             [i32; 4]
4669             ```"#]],
4670     );
4671
4672     check_hover_range(
4673         r#"
4674 fn f() { let expr = [1, 2, $03$0, 4] }
4675 "#,
4676         expect![[r#"
4677             ```rust
4678             i32
4679             ```"#]],
4680     );
4681 }
4682
4683 #[test]
4684 fn hover_range_functions() {
4685     check_hover_range(
4686         r#"
4687 fn f<T>(a: &[T]) { }
4688 fn b() { $0f$0(&[1, 2, 3, 4, 5]); }
4689 "#,
4690         expect![[r#"
4691             ```rust
4692             fn f<i32>(&[i32])
4693             ```"#]],
4694     );
4695
4696     check_hover_range(
4697         r#"
4698 fn f<T>(a: &[T]) { }
4699 fn b() { f($0&[1, 2, 3, 4, 5]$0); }
4700 "#,
4701         expect![[r#"
4702             ```rust
4703             &[i32; 5]
4704             ```"#]],
4705     );
4706 }
4707
4708 #[test]
4709 fn hover_range_shows_nothing_when_invalid() {
4710     check_hover_range_no_results(
4711         r#"
4712 fn f<T>(a: &[T]) { }
4713 fn b()$0 { f(&[1, 2, 3, 4, 5]); }$0
4714 "#,
4715     );
4716
4717     check_hover_range_no_results(
4718         r#"
4719 fn f<T>$0(a: &[T]) { }
4720 fn b() { f(&[1, 2, 3,$0 4, 5]); }
4721 "#,
4722     );
4723
4724     check_hover_range_no_results(
4725         r#"
4726 fn $0f() { let expr = [1, 2, 3, 4]$0 }
4727 "#,
4728     );
4729 }
4730
4731 #[test]
4732 fn hover_range_shows_unit_for_statements() {
4733     check_hover_range(
4734         r#"
4735 fn f<T>(a: &[T]) { }
4736 fn b() { $0f(&[1, 2, 3, 4, 5]); }$0
4737 "#,
4738         expect![[r#"
4739             ```rust
4740             ()
4741             ```"#]],
4742     );
4743
4744     check_hover_range(
4745         r#"
4746 fn f() { let expr$0 = $0[1, 2, 3, 4] }
4747 "#,
4748         expect![[r#"
4749             ```rust
4750             ()
4751             ```"#]],
4752     );
4753 }
4754
4755 #[test]
4756 fn hover_range_for_pat() {
4757     check_hover_range(
4758         r#"
4759 fn foo() {
4760     let $0x$0 = 0;
4761 }
4762 "#,
4763         expect![[r#"
4764                 ```rust
4765                 i32
4766                 ```"#]],
4767     );
4768
4769     check_hover_range(
4770         r#"
4771 fn foo() {
4772     let $0x$0 = "";
4773 }
4774 "#,
4775         expect![[r#"
4776                 ```rust
4777                 &str
4778                 ```"#]],
4779     );
4780 }
4781
4782 #[test]
4783 fn hover_range_shows_coercions_if_applicable_expr() {
4784     check_hover_range(
4785         r#"
4786 fn foo() {
4787     let x: &u32 = $0&&&&&0$0;
4788 }
4789 "#,
4790         expect![[r#"
4791                 ```text
4792                 Type:       &&&&&u32
4793                 Coerced to:     &u32
4794                 ```
4795             "#]],
4796     );
4797     check_hover_range(
4798         r#"
4799 fn foo() {
4800     let x: *const u32 = $0&0$0;
4801 }
4802 "#,
4803         expect![[r#"
4804                 ```text
4805                 Type:             &u32
4806                 Coerced to: *const u32
4807                 ```
4808             "#]],
4809     );
4810 }
4811
4812 #[test]
4813 fn hover_range_shows_type_actions() {
4814     check_actions(
4815         r#"
4816 struct Foo;
4817 fn foo() {
4818     let x: &Foo = $0&&&&&Foo$0;
4819 }
4820 "#,
4821         expect![[r#"
4822                 [
4823                     GoToType(
4824                         [
4825                             HoverGotoTypeData {
4826                                 mod_path: "test::Foo",
4827                                 nav: NavigationTarget {
4828                                     file_id: FileId(
4829                                         0,
4830                                     ),
4831                                     full_range: 0..11,
4832                                     focus_range: 7..10,
4833                                     name: "Foo",
4834                                     kind: Struct,
4835                                     description: "struct Foo",
4836                                 },
4837                             },
4838                         ],
4839                     ),
4840                 ]
4841             "#]],
4842     );
4843 }
4844
4845 #[test]
4846 fn hover_try_expr_res() {
4847     check_hover_range(
4848         r#"
4849 //- minicore:result
4850 struct FooError;
4851
4852 fn foo() -> Result<(), FooError> {
4853     Ok($0Result::<(), FooError>::Ok(())?$0)
4854 }
4855 "#,
4856         expect![[r#"
4857                 ```rust
4858                 ()
4859                 ```"#]],
4860     );
4861     check_hover_range(
4862         r#"
4863 //- minicore:result
4864 struct FooError;
4865 struct BarError;
4866
4867 fn foo() -> Result<(), FooError> {
4868     Ok($0Result::<(), BarError>::Ok(())?$0)
4869 }
4870 "#,
4871         expect![[r#"
4872                 ```text
4873                 Try Error Type: BarError
4874                 Propagated as:  FooError
4875                 ```
4876             "#]],
4877     );
4878 }
4879
4880 #[test]
4881 fn hover_try_expr() {
4882     check_hover_range(
4883         r#"
4884 struct NotResult<T, U>(T, U);
4885 struct Short;
4886 struct Looooong;
4887
4888 fn foo() -> NotResult<(), Looooong> {
4889     $0NotResult((), Short)?$0;
4890 }
4891 "#,
4892         expect![[r#"
4893                 ```text
4894                 Try Target Type:    NotResult<(), Short>
4895                 Propagated as:   NotResult<(), Looooong>
4896                 ```
4897             "#]],
4898     );
4899     check_hover_range(
4900         r#"
4901 struct NotResult<T, U>(T, U);
4902 struct Short;
4903 struct Looooong;
4904
4905 fn foo() -> NotResult<(), Short> {
4906     $0NotResult((), Looooong)?$0;
4907 }
4908 "#,
4909         expect![[r#"
4910                 ```text
4911                 Try Target Type: NotResult<(), Looooong>
4912                 Propagated as:      NotResult<(), Short>
4913                 ```
4914             "#]],
4915     );
4916     check_hover_range(
4917         r#"
4918 //- minicore: try
4919 use core::ops::ControlFlow;
4920 fn foo() -> ControlFlow<()> {
4921     $0ControlFlow::Break(())?$0;
4922     ControlFlow::Continue(())
4923 }
4924 "#,
4925         expect![[r#"
4926             ```text
4927             Try Target Type: ControlFlow<(), {unknown}>
4928             Propagated as:          ControlFlow<(), ()>
4929             ```
4930         "#]],
4931     );
4932 }
4933
4934 #[test]
4935 fn hover_try_expr_option() {
4936     cov_mark::check!(hover_try_expr_opt_opt);
4937     check_hover_range(
4938         r#"
4939 //- minicore: option, try
4940
4941 fn foo() -> Option<()> {
4942     $0Some(0)?$0;
4943     None
4944 }
4945 "#,
4946         expect![[r#"
4947             ```rust
4948             i32
4949             ```"#]],
4950     );
4951 }
4952
4953 #[test]
4954 fn hover_deref_expr() {
4955     check_hover_range(
4956         r#"
4957 //- minicore: deref
4958 use core::ops::Deref;
4959
4960 struct DerefExample<T> {
4961     value: T
4962 }
4963
4964 impl<T> Deref for DerefExample<T> {
4965     type Target = T;
4966
4967     fn deref(&self) -> &Self::Target {
4968         &self.value
4969     }
4970 }
4971
4972 fn foo() {
4973     let x = DerefExample { value: 0 };
4974     let y: i32 = $0*x$0;
4975 }
4976 "#,
4977         expect![[r#"
4978                 ```text
4979                 Dereferenced from: DerefExample<i32>
4980                 To type:                         i32
4981                 ```
4982             "#]],
4983     );
4984 }
4985
4986 #[test]
4987 fn hover_deref_expr_with_coercion() {
4988     check_hover_range(
4989         r#"
4990 //- minicore: deref
4991 use core::ops::Deref;
4992
4993 struct DerefExample<T> {
4994     value: T
4995 }
4996
4997 impl<T> Deref for DerefExample<T> {
4998     type Target = T;
4999
5000     fn deref(&self) -> &Self::Target {
5001         &self.value
5002     }
5003 }
5004
5005 fn foo() {
5006     let x = DerefExample { value: &&&&&0 };
5007     let y: &i32 = $0*x$0;
5008 }
5009 "#,
5010         expect![[r#"
5011                 ```text
5012                 Dereferenced from: DerefExample<&&&&&i32>
5013                 To type:                         &&&&&i32
5014                 Coerced to:                          &i32
5015                 ```
5016             "#]],
5017     );
5018 }
5019
5020 #[test]
5021 fn hover_intra_in_macro() {
5022     check(
5023         r#"
5024 macro_rules! foo_macro {
5025     ($(#[$attr:meta])* $name:ident) => {
5026         $(#[$attr])*
5027         pub struct $name;
5028     }
5029 }
5030
5031 foo_macro!(
5032     /// Doc comment for [`Foo$0`]
5033     Foo
5034 );
5035 "#,
5036         expect![[r#"
5037             *[`Foo`]*
5038
5039             ```rust
5040             test
5041             ```
5042
5043             ```rust
5044             pub struct Foo
5045             ```
5046
5047             ---
5048
5049             Doc comment for [`Foo`](https://docs.rs/test/*/test/struct.Foo.html)
5050         "#]],
5051     );
5052 }
5053
5054 #[test]
5055 fn hover_intra_in_attr() {
5056     check(
5057         r#"
5058 #[doc = "Doc comment for [`Foo$0`]"]
5059 pub struct Foo;
5060 "#,
5061         expect![[r#"
5062             *[`Foo`]*
5063
5064             ```rust
5065             test
5066             ```
5067
5068             ```rust
5069             pub struct Foo
5070             ```
5071
5072             ---
5073
5074             Doc comment for [`Foo`](https://docs.rs/test/*/test/struct.Foo.html)
5075         "#]],
5076     );
5077 }
5078
5079 #[test]
5080 fn hover_inert_attr() {
5081     check(
5082         r#"
5083 #[doc$0 = ""]
5084 pub struct Foo;
5085 "#,
5086         expect![[r##"
5087             *doc*
5088
5089             ```rust
5090             #[doc]
5091             ```
5092
5093             ---
5094
5095             Valid forms are:
5096
5097             * \#\[doc(hidden|inline|...)\]
5098             * \#\[doc = string\]
5099         "##]],
5100     );
5101     check(
5102         r#"
5103 #[allow$0()]
5104 pub struct Foo;
5105 "#,
5106         expect![[r##"
5107             *allow*
5108
5109             ```rust
5110             #[allow]
5111             ```
5112
5113             ---
5114
5115             Valid forms are:
5116
5117             * \#\[allow(lint1, lint2, ..., /\*opt\*/ reason = "...")\]
5118         "##]],
5119     );
5120 }
5121
5122 #[test]
5123 fn hover_dollar_crate() {
5124     // $crate should be resolved to the right crate name.
5125
5126     check(
5127         r#"
5128 //- /main.rs crate:main deps:dep
5129 dep::m!(KONST$0);
5130 //- /dep.rs crate:dep
5131 #[macro_export]
5132 macro_rules! m {
5133     ( $name:ident ) => { const $name: $crate::Type = $crate::Type; };
5134 }
5135
5136 pub struct Type;
5137 "#,
5138         expect![[r#"
5139             *KONST*
5140
5141             ```rust
5142             main
5143             ```
5144
5145             ```rust
5146             const KONST: dep::Type = $crate::Type
5147             ```
5148         "#]],
5149     );
5150 }
5151
5152 #[test]
5153 fn hover_record_variant() {
5154     check(
5155         r#"
5156 enum Enum {
5157     RecordV$0 { field: u32 }
5158 }
5159 "#,
5160         expect![[r#"
5161             *RecordV*
5162
5163             ```rust
5164             test::Enum
5165             ```
5166
5167             ```rust
5168             RecordV { field: u32 }
5169             ```
5170         "#]],
5171     );
5172 }
5173
5174 #[test]
5175 fn hover_trait_impl_assoc_item_def_doc_forwarding() {
5176     check(
5177         r#"
5178 trait T {
5179     /// Trait docs
5180     fn func() {}
5181 }
5182 impl T for () {
5183     fn func$0() {}
5184 }
5185 "#,
5186         expect![[r#"
5187             *func*
5188
5189             ```rust
5190             test
5191             ```
5192
5193             ```rust
5194             fn func()
5195             ```
5196
5197             ---
5198
5199             Trait docs
5200         "#]],
5201     );
5202 }
5203
5204 #[test]
5205 fn hover_ranged_macro_call() {
5206     check_hover_range(
5207         r#"
5208 macro_rules! __rust_force_expr {
5209     ($e:expr) => {
5210         $e
5211     };
5212 }
5213 macro_rules! vec {
5214     ($elem:expr) => {
5215         __rust_force_expr!($elem)
5216     };
5217 }
5218
5219 struct Struct;
5220 impl Struct {
5221     fn foo(self) {}
5222 }
5223
5224 fn f() {
5225     $0vec![Struct]$0;
5226 }
5227 "#,
5228         expect![[r#"
5229             ```rust
5230             Struct
5231             ```"#]],
5232     );
5233 }
5234
5235 #[test]
5236 fn hover_deref() {
5237     check(
5238         r#"
5239 //- minicore: deref
5240
5241 struct Struct(usize);
5242
5243 impl core::ops::Deref for Struct {
5244     type Target = usize;
5245
5246     fn deref(&self) -> &Self::Target {
5247         &self.0
5248     }
5249 }
5250
5251 fn f() {
5252     $0*Struct(0);
5253 }
5254 "#,
5255         expect![[r#"
5256             ***
5257
5258             ```rust
5259             test::Struct
5260             ```
5261
5262             ```rust
5263             fn deref(&self) -> &Self::Target
5264             ```
5265         "#]],
5266     );
5267 }
5268
5269 #[test]
5270 fn static_const_macro_expanded_body() {
5271     check(
5272         r#"
5273 macro_rules! m {
5274     () => {
5275         pub const V: i8 = {
5276             let e = 123;
5277             f(e) // Prevent const eval from evaluating this constant, we want to print the body's code.
5278         };
5279     };
5280 }
5281 m!();
5282 fn main() { $0V; }
5283 "#,
5284         expect![[r#"
5285             *V*
5286
5287             ```rust
5288             test
5289             ```
5290
5291             ```rust
5292             pub const V: i8 = {
5293               let e = 123;
5294               f(e)
5295             }
5296             ```
5297         "#]],
5298     );
5299     check(
5300         r#"
5301 macro_rules! m {
5302     () => {
5303         pub static V: i8 = {
5304             let e = 123;
5305         };
5306     };
5307 }
5308 m!();
5309 fn main() { $0V; }
5310 "#,
5311         expect![[r#"
5312             *V*
5313
5314             ```rust
5315             test
5316             ```
5317
5318             ```rust
5319             pub static V: i8 = {
5320               let e = 123;
5321             }
5322             ```
5323         "#]],
5324     );
5325 }