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