]> git.lizzy.rs Git - rust.git/blob - crates/ide/src/hover.rs
Merge #7149
[rust.git] / crates / ide / src / hover.rs
1 use hir::{
2     Adt, AsAssocItem, AssocItemContainer, FieldSource, HasAttrs, HasSource, HirDisplay, Module,
3     ModuleDef, ModuleSource, Semantics,
4 };
5 use ide_db::base_db::SourceDatabase;
6 use ide_db::{
7     defs::{Definition, NameClass, NameRefClass},
8     RootDatabase,
9 };
10 use itertools::Itertools;
11 use stdx::format_to;
12 use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset, T};
13 use test_utils::mark;
14
15 use crate::{
16     display::{macro_label, ShortLabel, TryToNav},
17     doc_links::{remove_links, rewrite_links},
18     markdown_remove::remove_markdown,
19     markup::Markup,
20     runnables::runnable,
21     FileId, FilePosition, NavigationTarget, RangeInfo, Runnable,
22 };
23
24 #[derive(Clone, Debug, PartialEq, Eq)]
25 pub struct HoverConfig {
26     pub implementations: bool,
27     pub run: bool,
28     pub debug: bool,
29     pub goto_type_def: bool,
30     pub links_in_hover: bool,
31     pub markdown: bool,
32 }
33
34 impl Default for HoverConfig {
35     fn default() -> Self {
36         Self {
37             implementations: true,
38             run: true,
39             debug: true,
40             goto_type_def: true,
41             links_in_hover: true,
42             markdown: true,
43         }
44     }
45 }
46
47 impl HoverConfig {
48     pub const NO_ACTIONS: Self = Self {
49         implementations: false,
50         run: false,
51         debug: false,
52         goto_type_def: false,
53         links_in_hover: true,
54         markdown: true,
55     };
56
57     pub fn any(&self) -> bool {
58         self.implementations || self.runnable() || self.goto_type_def
59     }
60
61     pub fn none(&self) -> bool {
62         !self.any()
63     }
64
65     pub fn runnable(&self) -> bool {
66         self.run || self.debug
67     }
68 }
69
70 #[derive(Debug, Clone)]
71 pub enum HoverAction {
72     Runnable(Runnable),
73     Implementaion(FilePosition),
74     GoToType(Vec<HoverGotoTypeData>),
75 }
76
77 #[derive(Debug, Clone, Eq, PartialEq)]
78 pub struct HoverGotoTypeData {
79     pub mod_path: String,
80     pub nav: NavigationTarget,
81 }
82
83 /// Contains the results when hovering over an item
84 #[derive(Debug, Default)]
85 pub struct HoverResult {
86     pub markup: Markup,
87     pub actions: Vec<HoverAction>,
88 }
89
90 // Feature: Hover
91 //
92 // Shows additional information, like type of an expression or documentation for definition when "focusing" code.
93 // Focusing is usually hovering with a mouse, but can also be triggered with a shortcut.
94 pub(crate) fn hover(
95     db: &RootDatabase,
96     position: FilePosition,
97     links_in_hover: bool,
98     markdown: bool,
99 ) -> Option<RangeInfo<HoverResult>> {
100     let sema = Semantics::new(db);
101     let file = sema.parse(position.file_id).syntax().clone();
102     let token = pick_best(file.token_at_offset(position.offset))?;
103     let token = sema.descend_into_macros(token);
104
105     let mut res = HoverResult::default();
106
107     let node = token.parent();
108     let definition = match_ast! {
109         match node {
110             ast::Name(name) => NameClass::classify(&sema, &name).and_then(|d| d.defined(sema.db)),
111             ast::NameRef(name_ref) => NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced(sema.db)),
112             ast::Lifetime(lifetime) => NameClass::classify_lifetime(&sema, &lifetime)
113                 .map_or_else(|| NameRefClass::classify_lifetime(&sema, &lifetime).map(|d| d.referenced(sema.db)), |d| d.defined(sema.db)),
114             _ => None,
115         }
116     };
117     if let Some(definition) = definition {
118         if let Some(markup) = hover_for_definition(db, definition) {
119             let markup = if !markdown {
120                 remove_markdown(&markup.as_str())
121             } else if links_in_hover {
122                 rewrite_links(db, &markup.as_str(), &definition)
123             } else {
124                 remove_links(&markup.as_str())
125             };
126             res.markup = Markup::from(markup);
127             if let Some(action) = show_implementations_action(db, definition) {
128                 res.actions.push(action);
129             }
130
131             if let Some(action) = runnable_action(&sema, definition, position.file_id) {
132                 res.actions.push(action);
133             }
134
135             if let Some(action) = goto_type_action(db, definition) {
136                 res.actions.push(action);
137             }
138
139             let range = sema.original_range(&node).range;
140             return Some(RangeInfo::new(range, res));
141         }
142     }
143
144     if token.kind() == syntax::SyntaxKind::COMMENT {
145         // don't highlight the entire parent node on comment hover
146         return None;
147     }
148
149     let node = token.ancestors().find(|n| {
150         ast::Expr::can_cast(n.kind())
151             || ast::Pat::can_cast(n.kind())
152             || ast::SelfParam::can_cast(n.kind())
153     })?;
154
155     let ty = match_ast! {
156         match node {
157             ast::Expr(it) => sema.type_of_expr(&it)?,
158             ast::Pat(it) => sema.type_of_pat(&it)?,
159             ast::SelfParam(self_param) => sema.type_of_self(&self_param)?,
160             // If this node is a MACRO_CALL, it means that `descend_into_macros` failed to resolve.
161             // (e.g expanding a builtin macro). So we give up here.
162             ast::MacroCall(_it) => return None,
163             _ => return None,
164         }
165     };
166
167     res.markup = if markdown {
168         Markup::fenced_block(&ty.display(db))
169     } else {
170         ty.display(db).to_string().into()
171     };
172     let range = sema.original_range(&node).range;
173     Some(RangeInfo::new(range, res))
174 }
175
176 fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> {
177     fn to_action(nav_target: NavigationTarget) -> HoverAction {
178         HoverAction::Implementaion(FilePosition {
179             file_id: nav_target.file_id,
180             offset: nav_target.focus_or_full_range().start(),
181         })
182     }
183
184     match def {
185         Definition::ModuleDef(it) => match it {
186             ModuleDef::Adt(Adt::Struct(it)) => Some(to_action(it.try_to_nav(db)?)),
187             ModuleDef::Adt(Adt::Union(it)) => Some(to_action(it.try_to_nav(db)?)),
188             ModuleDef::Adt(Adt::Enum(it)) => Some(to_action(it.try_to_nav(db)?)),
189             ModuleDef::Trait(it) => Some(to_action(it.try_to_nav(db)?)),
190             _ => None,
191         },
192         _ => None,
193     }
194 }
195
196 fn runnable_action(
197     sema: &Semantics<RootDatabase>,
198     def: Definition,
199     file_id: FileId,
200 ) -> Option<HoverAction> {
201     match def {
202         Definition::ModuleDef(it) => match it {
203             ModuleDef::Module(it) => match it.definition_source(sema.db).value {
204                 ModuleSource::Module(it) => runnable(&sema, it.syntax().clone(), file_id)
205                     .map(|it| HoverAction::Runnable(it)),
206                 _ => None,
207             },
208             ModuleDef::Function(it) => {
209                 #[allow(deprecated)]
210                 let src = it.source(sema.db)?;
211                 if src.file_id != file_id.into() {
212                     mark::hit!(hover_macro_generated_struct_fn_doc_comment);
213                     mark::hit!(hover_macro_generated_struct_fn_doc_attr);
214
215                     return None;
216                 }
217
218                 runnable(&sema, src.value.syntax().clone(), file_id)
219                     .map(|it| HoverAction::Runnable(it))
220             }
221             _ => None,
222         },
223         _ => None,
224     }
225 }
226
227 fn goto_type_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> {
228     match def {
229         Definition::Local(it) => {
230             let mut targets: Vec<ModuleDef> = Vec::new();
231             let mut push_new_def = |item: ModuleDef| {
232                 if !targets.contains(&item) {
233                     targets.push(item);
234                 }
235             };
236
237             it.ty(db).walk(db, |t| {
238                 if let Some(adt) = t.as_adt() {
239                     push_new_def(adt.into());
240                 } else if let Some(trait_) = t.as_dyn_trait() {
241                     push_new_def(trait_.into());
242                 } else if let Some(traits) = t.as_impl_traits(db) {
243                     traits.into_iter().for_each(|it| push_new_def(it.into()));
244                 } else if let Some(trait_) = t.as_associated_type_parent_trait(db) {
245                     push_new_def(trait_.into());
246                 }
247             });
248
249             let targets = targets
250                 .into_iter()
251                 .filter_map(|it| {
252                     Some(HoverGotoTypeData {
253                         mod_path: render_path(
254                             db,
255                             it.module(db)?,
256                             it.name(db).map(|name| name.to_string()),
257                         ),
258                         nav: it.try_to_nav(db)?,
259                     })
260                 })
261                 .collect();
262
263             Some(HoverAction::GoToType(targets))
264         }
265         _ => None,
266     }
267 }
268
269 fn hover_markup(
270     docs: Option<String>,
271     desc: Option<String>,
272     mod_path: Option<String>,
273 ) -> Option<Markup> {
274     match desc {
275         Some(desc) => {
276             let mut buf = String::new();
277
278             if let Some(mod_path) = mod_path {
279                 if !mod_path.is_empty() {
280                     format_to!(buf, "```rust\n{}\n```\n\n", mod_path);
281                 }
282             }
283             format_to!(buf, "```rust\n{}\n```", desc);
284
285             if let Some(doc) = docs {
286                 format_to!(buf, "\n___\n\n{}", doc);
287             }
288             Some(buf.into())
289         }
290         None => docs.map(Markup::from),
291     }
292 }
293
294 fn definition_owner_name(db: &RootDatabase, def: &Definition) -> Option<String> {
295     match def {
296         Definition::Field(f) => Some(f.parent_def(db).name(db)),
297         Definition::Local(l) => l.parent(db).name(db),
298         Definition::ModuleDef(md) => match md {
299             ModuleDef::Function(f) => match f.as_assoc_item(db)?.container(db) {
300                 AssocItemContainer::Trait(t) => Some(t.name(db)),
301                 AssocItemContainer::Impl(i) => i.target_ty(db).as_adt().map(|adt| adt.name(db)),
302             },
303             ModuleDef::Variant(e) => Some(e.parent_enum(db).name(db)),
304             _ => None,
305         },
306         _ => None,
307     }
308     .map(|name| name.to_string())
309 }
310
311 fn render_path(db: &RootDatabase, module: Module, item_name: Option<String>) -> String {
312     let crate_name =
313         db.crate_graph()[module.krate().into()].display_name.as_ref().map(|it| it.to_string());
314     let module_path = module
315         .path_to_root(db)
316         .into_iter()
317         .rev()
318         .flat_map(|it| it.name(db).map(|name| name.to_string()));
319     crate_name.into_iter().chain(module_path).chain(item_name).join("::")
320 }
321
322 fn definition_mod_path(db: &RootDatabase, def: &Definition) -> Option<String> {
323     def.module(db).map(|module| render_path(db, module, definition_owner_name(db, def)))
324 }
325
326 fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> {
327     let mod_path = definition_mod_path(db, &def);
328     return match def {
329         Definition::Macro(it) => {
330             let label = macro_label(&it.source(db)?.value);
331             from_def_source_labeled(db, it, Some(label), mod_path)
332         }
333         Definition::Field(def) => {
334             #[allow(deprecated)]
335             let src = def.source(db)?.value;
336             if let FieldSource::Named(it) = src {
337                 from_def_source_labeled(db, def, it.short_label(), mod_path)
338             } else {
339                 None
340             }
341         }
342         Definition::ModuleDef(it) => match it {
343             ModuleDef::Module(it) => from_def_source_labeled(
344                 db,
345                 it,
346                 match it.definition_source(db).value {
347                     ModuleSource::Module(it) => it.short_label(),
348                     ModuleSource::SourceFile(it) => it.short_label(),
349                 },
350                 mod_path,
351             ),
352             ModuleDef::Function(it) => from_def_source(db, it, mod_path),
353             ModuleDef::Adt(Adt::Struct(it)) => from_def_source(db, it, mod_path),
354             ModuleDef::Adt(Adt::Union(it)) => from_def_source(db, it, mod_path),
355             ModuleDef::Adt(Adt::Enum(it)) => from_def_source(db, it, mod_path),
356             ModuleDef::Variant(it) => from_def_source(db, it, mod_path),
357             ModuleDef::Const(it) => from_def_source(db, it, mod_path),
358             ModuleDef::Static(it) => from_def_source(db, it, mod_path),
359             ModuleDef::Trait(it) => from_def_source(db, it, mod_path),
360             ModuleDef::TypeAlias(it) => from_def_source(db, it, mod_path),
361             ModuleDef::BuiltinType(it) => Some(Markup::fenced_block(&it)),
362         },
363         Definition::Local(it) => Some(Markup::fenced_block(&it.ty(db).display(db))),
364         Definition::SelfType(impl_def) => {
365             impl_def.target_ty(db).as_adt().and_then(|adt| match adt {
366                 Adt::Struct(it) => from_def_source(db, it, mod_path),
367                 Adt::Union(it) => from_def_source(db, it, mod_path),
368                 Adt::Enum(it) => from_def_source(db, it, mod_path),
369             })
370         }
371         Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))),
372         Definition::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))),
373         Definition::TypeParam(type_param) => Some(Markup::fenced_block(&type_param.display(db))),
374         Definition::ConstParam(_) => {
375             // FIXME: Hover for generic const param
376             None
377         }
378     };
379
380     fn from_def_source<A, D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<Markup>
381     where
382         D: HasSource<Ast = A> + HasAttrs + Copy,
383         A: ShortLabel,
384     {
385         #[allow(deprecated)]
386         let short_label = def.source(db)?.value.short_label();
387         from_def_source_labeled(db, def, short_label, mod_path)
388     }
389
390     fn from_def_source_labeled<D>(
391         db: &RootDatabase,
392         def: D,
393         short_label: Option<String>,
394         mod_path: Option<String>,
395     ) -> Option<Markup>
396     where
397         D: HasAttrs,
398     {
399         let docs = def.attrs(db).docs().map(Into::into);
400         hover_markup(docs, short_label, mod_path)
401     }
402 }
403
404 fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
405     return tokens.max_by_key(priority);
406     fn priority(n: &SyntaxToken) -> usize {
407         match n.kind() {
408             IDENT | INT_NUMBER | LIFETIME_IDENT => 3,
409             T!['('] | T![')'] => 2,
410             kind if kind.is_trivia() => 0,
411             _ => 1,
412         }
413     }
414 }
415
416 #[cfg(test)]
417 mod tests {
418     use expect_test::{expect, Expect};
419     use ide_db::base_db::FileLoader;
420
421     use crate::fixture;
422
423     use super::*;
424
425     fn check_hover_no_result(ra_fixture: &str) {
426         let (analysis, position) = fixture::position(ra_fixture);
427         assert!(analysis.hover(position, true, true).unwrap().is_none());
428     }
429
430     fn check(ra_fixture: &str, expect: Expect) {
431         let (analysis, position) = fixture::position(ra_fixture);
432         let hover = analysis.hover(position, true, true).unwrap().unwrap();
433
434         let content = analysis.db.file_text(position.file_id);
435         let hovered_element = &content[hover.range];
436
437         let actual = format!("*{}*\n{}\n", hovered_element, hover.info.markup);
438         expect.assert_eq(&actual)
439     }
440
441     fn check_hover_no_links(ra_fixture: &str, expect: Expect) {
442         let (analysis, position) = fixture::position(ra_fixture);
443         let hover = analysis.hover(position, false, true).unwrap().unwrap();
444
445         let content = analysis.db.file_text(position.file_id);
446         let hovered_element = &content[hover.range];
447
448         let actual = format!("*{}*\n{}\n", hovered_element, hover.info.markup);
449         expect.assert_eq(&actual)
450     }
451
452     fn check_hover_no_markdown(ra_fixture: &str, expect: Expect) {
453         let (analysis, position) = fixture::position(ra_fixture);
454         let hover = analysis.hover(position, true, false).unwrap().unwrap();
455
456         let content = analysis.db.file_text(position.file_id);
457         let hovered_element = &content[hover.range];
458
459         let actual = format!("*{}*\n{}\n", hovered_element, hover.info.markup);
460         expect.assert_eq(&actual)
461     }
462
463     fn check_actions(ra_fixture: &str, expect: Expect) {
464         let (analysis, position) = fixture::position(ra_fixture);
465         let hover = analysis.hover(position, true, true).unwrap().unwrap();
466         expect.assert_debug_eq(&hover.info.actions)
467     }
468
469     #[test]
470     fn hover_shows_type_of_an_expression() {
471         check(
472             r#"
473 pub fn foo() -> u32 { 1 }
474
475 fn main() {
476     let foo_test = foo()<|>;
477 }
478 "#,
479             expect![[r#"
480                 *foo()*
481                 ```rust
482                 u32
483                 ```
484             "#]],
485         );
486     }
487
488     #[test]
489     fn hover_remove_markdown_if_configured() {
490         check_hover_no_markdown(
491             r#"
492 pub fn foo() -> u32 { 1 }
493
494 fn main() {
495     let foo_test = foo()<|>;
496 }
497 "#,
498             expect![[r#"
499                 *foo()*
500                 u32
501             "#]],
502         );
503     }
504
505     #[test]
506     fn hover_shows_long_type_of_an_expression() {
507         check(
508             r#"
509 struct Scan<A, B, C> { a: A, b: B, c: C }
510 struct Iter<I> { inner: I }
511 enum Option<T> { Some(T), None }
512
513 struct OtherStruct<T> { i: T }
514
515 fn scan<A, B, C>(a: A, b: B, c: C) -> Iter<Scan<OtherStruct<A>, B, C>> {
516     Iter { inner: Scan { a, b, c } }
517 }
518
519 fn main() {
520     let num: i32 = 55;
521     let closure = |memo: &mut u32, value: &u32, _another: &mut u32| -> Option<u32> {
522         Option::Some(*memo + value)
523     };
524     let number = 5u32;
525     let mut iter<|> = scan(OtherStruct { i: num }, closure, number);
526 }
527 "#,
528             expect![[r#"
529                 *iter*
530
531                 ```rust
532                 Iter<Scan<OtherStruct<OtherStruct<i32>>, |&mut u32, &u32, &mut u32| -> Option<u32>, u32>>
533                 ```
534             "#]],
535         );
536     }
537
538     #[test]
539     fn hover_shows_fn_signature() {
540         // Single file with result
541         check(
542             r#"
543 pub fn foo() -> u32 { 1 }
544
545 fn main() { let foo_test = fo<|>o(); }
546 "#,
547             expect![[r#"
548                 *foo*
549
550                 ```rust
551                 test
552                 ```
553
554                 ```rust
555                 pub fn foo() -> u32
556                 ```
557             "#]],
558         );
559
560         // Multiple candidates but results are ambiguous.
561         check(
562             r#"
563 //- /a.rs
564 pub fn foo() -> u32 { 1 }
565
566 //- /b.rs
567 pub fn foo() -> &str { "" }
568
569 //- /c.rs
570 pub fn foo(a: u32, b: u32) {}
571
572 //- /main.rs
573 mod a;
574 mod b;
575 mod c;
576
577 fn main() { let foo_test = fo<|>o(); }
578         "#,
579             expect![[r#"
580                 *foo*
581                 ```rust
582                 {unknown}
583                 ```
584             "#]],
585         );
586     }
587
588     #[test]
589     fn hover_shows_fn_signature_with_type_params() {
590         check(
591             r#"
592 pub fn foo<'a, T: AsRef<str>>(b: &'a T) -> &'a str { }
593
594 fn main() { let foo_test = fo<|>o(); }
595         "#,
596             expect![[r#"
597                 *foo*
598
599                 ```rust
600                 test
601                 ```
602
603                 ```rust
604                 pub fn foo<'a, T: AsRef<str>>(b: &'a T) -> &'a str
605                 ```
606             "#]],
607         );
608     }
609
610     #[test]
611     fn hover_shows_fn_signature_on_fn_name() {
612         check(
613             r#"
614 pub fn foo<|>(a: u32, b: u32) -> u32 {}
615
616 fn main() { }
617 "#,
618             expect![[r#"
619                 *foo*
620
621                 ```rust
622                 test
623                 ```
624
625                 ```rust
626                 pub fn foo(a: u32, b: u32) -> u32
627                 ```
628             "#]],
629         );
630     }
631
632     #[test]
633     fn hover_shows_fn_doc() {
634         check(
635             r#"
636 /// # Example
637 /// ```
638 /// # use std::path::Path;
639 /// #
640 /// foo(Path::new("hello, world!"))
641 /// ```
642 pub fn foo<|>(_: &Path) {}
643
644 fn main() { }
645 "#,
646             expect![[r##"
647                 *foo*
648
649                 ```rust
650                 test
651                 ```
652
653                 ```rust
654                 pub fn foo(_: &Path)
655                 ```
656
657                 ---
658
659                 # Example
660
661                 ```
662                 # use std::path::Path;
663                 #
664                 foo(Path::new("hello, world!"))
665                 ```
666             "##]],
667         );
668     }
669
670     #[test]
671     fn hover_shows_fn_doc_attr_raw_string() {
672         check(
673             r##"
674 #[doc = r#"Raw string doc attr"#]
675 pub fn foo<|>(_: &Path) {}
676
677 fn main() { }
678 "##,
679             expect![[r##"
680                 *foo*
681
682                 ```rust
683                 test
684                 ```
685
686                 ```rust
687                 pub fn foo(_: &Path)
688                 ```
689
690                 ---
691
692                 Raw string doc attr
693             "##]],
694         );
695     }
696
697     #[test]
698     fn hover_shows_struct_field_info() {
699         // Hovering over the field when instantiating
700         check(
701             r#"
702 struct Foo { field_a: u32 }
703
704 fn main() {
705     let foo = Foo { field_a<|>: 0, };
706 }
707 "#,
708             expect![[r#"
709                 *field_a*
710
711                 ```rust
712                 test::Foo
713                 ```
714
715                 ```rust
716                 field_a: u32
717                 ```
718             "#]],
719         );
720
721         // Hovering over the field in the definition
722         check(
723             r#"
724 struct Foo { field_a<|>: u32 }
725
726 fn main() {
727     let foo = Foo { field_a: 0 };
728 }
729 "#,
730             expect![[r#"
731                 *field_a*
732
733                 ```rust
734                 test::Foo
735                 ```
736
737                 ```rust
738                 field_a: u32
739                 ```
740             "#]],
741         );
742     }
743
744     #[test]
745     fn hover_const_static() {
746         check(
747             r#"const foo<|>: u32 = 123;"#,
748             expect![[r#"
749                 *foo*
750
751                 ```rust
752                 test
753                 ```
754
755                 ```rust
756                 const foo: u32 = 123
757                 ```
758             "#]],
759         );
760         check(
761             r#"static foo<|>: u32 = 456;"#,
762             expect![[r#"
763                 *foo*
764
765                 ```rust
766                 test
767                 ```
768
769                 ```rust
770                 static foo: u32
771                 ```
772             "#]],
773         );
774     }
775
776     #[test]
777     fn hover_default_generic_types() {
778         check(
779             r#"
780 struct Test<K, T = u8> { k: K, t: T }
781
782 fn main() {
783     let zz<|> = Test { t: 23u8, k: 33 };
784 }"#,
785             expect![[r#"
786                 *zz*
787
788                 ```rust
789                 Test<i32, u8>
790                 ```
791             "#]],
792         );
793     }
794
795     #[test]
796     fn hover_some() {
797         check(
798             r#"
799 enum Option<T> { Some(T) }
800 use Option::Some;
801
802 fn main() { So<|>me(12); }
803 "#,
804             expect![[r#"
805                 *Some*
806
807                 ```rust
808                 test::Option
809                 ```
810
811                 ```rust
812                 Some
813                 ```
814             "#]],
815         );
816
817         check(
818             r#"
819 enum Option<T> { Some(T) }
820 use Option::Some;
821
822 fn main() { let b<|>ar = Some(12); }
823 "#,
824             expect![[r#"
825                 *bar*
826
827                 ```rust
828                 Option<i32>
829                 ```
830             "#]],
831         );
832     }
833
834     #[test]
835     fn hover_enum_variant() {
836         check(
837             r#"
838 enum Option<T> {
839     /// The None variant
840     Non<|>e
841 }
842 "#,
843             expect![[r#"
844                 *None*
845
846                 ```rust
847                 test::Option
848                 ```
849
850                 ```rust
851                 None
852                 ```
853
854                 ---
855
856                 The None variant
857             "#]],
858         );
859
860         check(
861             r#"
862 enum Option<T> {
863     /// The Some variant
864     Some(T)
865 }
866 fn main() {
867     let s = Option::Som<|>e(12);
868 }
869 "#,
870             expect![[r#"
871                 *Some*
872
873                 ```rust
874                 test::Option
875                 ```
876
877                 ```rust
878                 Some
879                 ```
880
881                 ---
882
883                 The Some variant
884             "#]],
885         );
886     }
887
888     #[test]
889     fn hover_for_local_variable() {
890         check(
891             r#"fn func(foo: i32) { fo<|>o; }"#,
892             expect![[r#"
893                 *foo*
894
895                 ```rust
896                 i32
897                 ```
898             "#]],
899         )
900     }
901
902     #[test]
903     fn hover_for_local_variable_pat() {
904         check(
905             r#"fn func(fo<|>o: i32) {}"#,
906             expect![[r#"
907                 *foo*
908
909                 ```rust
910                 i32
911                 ```
912             "#]],
913         )
914     }
915
916     #[test]
917     fn hover_local_var_edge() {
918         check(
919             r#"fn func(foo: i32) { if true { <|>foo; }; }"#,
920             expect![[r#"
921                 *foo*
922
923                 ```rust
924                 i32
925                 ```
926             "#]],
927         )
928     }
929
930     #[test]
931     fn hover_for_param_edge() {
932         check(
933             r#"fn func(<|>foo: i32) {}"#,
934             expect![[r#"
935                 *foo*
936
937                 ```rust
938                 i32
939                 ```
940             "#]],
941         )
942     }
943
944     #[test]
945     fn hover_for_param_with_multiple_traits() {
946         check(
947             r#"trait Deref {
948                 type Target: ?Sized;
949             }
950             trait DerefMut {
951                 type Target: ?Sized;
952             }
953             fn f(_x<|>: impl Deref<Target=u8> + DerefMut<Target=u8>) {}"#,
954             expect![[r#"
955                 *_x*
956
957                 ```rust
958                 impl Deref<Target = u8> + DerefMut<Target = u8>
959                 ```
960             "#]],
961         )
962     }
963
964     #[test]
965     fn test_hover_infer_associated_method_result() {
966         check(
967             r#"
968 struct Thing { x: u32 }
969
970 impl Thing {
971     fn new() -> Thing { Thing { x: 0 } }
972 }
973
974 fn main() { let foo_<|>test = Thing::new(); }
975             "#,
976             expect![[r#"
977                 *foo_test*
978
979                 ```rust
980                 Thing
981                 ```
982             "#]],
983         )
984     }
985
986     #[test]
987     fn test_hover_infer_associated_method_exact() {
988         check(
989             r#"
990 mod wrapper {
991     struct Thing { x: u32 }
992
993     impl Thing {
994         fn new() -> Thing { Thing { x: 0 } }
995     }
996 }
997
998 fn main() { let foo_test = wrapper::Thing::new<|>(); }
999 "#,
1000             expect![[r#"
1001                 *new*
1002
1003                 ```rust
1004                 test::wrapper::Thing
1005                 ```
1006
1007                 ```rust
1008                 fn new() -> Thing
1009                 ```
1010             "#]],
1011         )
1012     }
1013
1014     #[test]
1015     fn test_hover_infer_associated_const_in_pattern() {
1016         check(
1017             r#"
1018 struct X;
1019 impl X {
1020     const C: u32 = 1;
1021 }
1022
1023 fn main() {
1024     match 1 {
1025         X::C<|> => {},
1026         2 => {},
1027         _ => {}
1028     };
1029 }
1030 "#,
1031             expect![[r#"
1032                 *C*
1033
1034                 ```rust
1035                 test
1036                 ```
1037
1038                 ```rust
1039                 const C: u32 = 1
1040                 ```
1041             "#]],
1042         )
1043     }
1044
1045     #[test]
1046     fn test_hover_self() {
1047         check(
1048             r#"
1049 struct Thing { x: u32 }
1050 impl Thing {
1051     fn new() -> Self { Self<|> { x: 0 } }
1052 }
1053 "#,
1054             expect![[r#"
1055                 *Self*
1056
1057                 ```rust
1058                 test
1059                 ```
1060
1061                 ```rust
1062                 struct Thing
1063                 ```
1064             "#]],
1065         );
1066         check(
1067             r#"
1068 struct Thing { x: u32 }
1069 impl Thing {
1070     fn new() -> Self<|> { Self { x: 0 } }
1071 }
1072 "#,
1073             expect![[r#"
1074                 *Self*
1075
1076                 ```rust
1077                 test
1078                 ```
1079
1080                 ```rust
1081                 struct Thing
1082                 ```
1083             "#]],
1084         );
1085         check(
1086             r#"
1087 enum Thing { A }
1088 impl Thing {
1089     pub fn new() -> Self<|> { Thing::A }
1090 }
1091 "#,
1092             expect![[r#"
1093                 *Self*
1094
1095                 ```rust
1096                 test
1097                 ```
1098
1099                 ```rust
1100                 enum Thing
1101                 ```
1102             "#]],
1103         );
1104         check(
1105             r#"
1106         enum Thing { A }
1107         impl Thing {
1108             pub fn thing(a: Self<|>) {}
1109         }
1110         "#,
1111             expect![[r#"
1112                 *Self*
1113
1114                 ```rust
1115                 test
1116                 ```
1117
1118                 ```rust
1119                 enum Thing
1120                 ```
1121             "#]],
1122         );
1123     }
1124
1125     #[test]
1126     fn test_hover_shadowing_pat() {
1127         check(
1128             r#"
1129 fn x() {}
1130
1131 fn y() {
1132     let x = 0i32;
1133     x<|>;
1134 }
1135 "#,
1136             expect![[r#"
1137                 *x*
1138
1139                 ```rust
1140                 i32
1141                 ```
1142             "#]],
1143         )
1144     }
1145
1146     #[test]
1147     fn test_hover_macro_invocation() {
1148         check(
1149             r#"
1150 macro_rules! foo { () => {} }
1151
1152 fn f() { fo<|>o!(); }
1153 "#,
1154             expect![[r#"
1155                 *foo*
1156
1157                 ```rust
1158                 test
1159                 ```
1160
1161                 ```rust
1162                 macro_rules! foo
1163                 ```
1164             "#]],
1165         )
1166     }
1167
1168     #[test]
1169     fn test_hover_tuple_field() {
1170         check(
1171             r#"struct TS(String, i32<|>);"#,
1172             expect![[r#"
1173                 *i32*
1174
1175                 ```rust
1176                 i32
1177                 ```
1178             "#]],
1179         )
1180     }
1181
1182     #[test]
1183     fn test_hover_through_macro() {
1184         check(
1185             r#"
1186 macro_rules! id { ($($tt:tt)*) => { $($tt)* } }
1187 fn foo() {}
1188 id! {
1189     fn bar() { fo<|>o(); }
1190 }
1191 "#,
1192             expect![[r#"
1193                 *foo*
1194
1195                 ```rust
1196                 test
1197                 ```
1198
1199                 ```rust
1200                 fn foo()
1201                 ```
1202             "#]],
1203         );
1204     }
1205
1206     #[test]
1207     fn test_hover_through_expr_in_macro() {
1208         check(
1209             r#"
1210 macro_rules! id { ($($tt:tt)*) => { $($tt)* } }
1211 fn foo(bar:u32) { let a = id!(ba<|>r); }
1212 "#,
1213             expect![[r#"
1214                 *bar*
1215
1216                 ```rust
1217                 u32
1218                 ```
1219             "#]],
1220         );
1221     }
1222
1223     #[test]
1224     fn test_hover_through_expr_in_macro_recursive() {
1225         check(
1226             r#"
1227 macro_rules! id_deep { ($($tt:tt)*) => { $($tt)* } }
1228 macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } }
1229 fn foo(bar:u32) { let a = id!(ba<|>r); }
1230 "#,
1231             expect![[r#"
1232                 *bar*
1233
1234                 ```rust
1235                 u32
1236                 ```
1237             "#]],
1238         );
1239     }
1240
1241     #[test]
1242     fn test_hover_through_func_in_macro_recursive() {
1243         check(
1244             r#"
1245 macro_rules! id_deep { ($($tt:tt)*) => { $($tt)* } }
1246 macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } }
1247 fn bar() -> u32 { 0 }
1248 fn foo() { let a = id!([0u32, bar(<|>)] ); }
1249 "#,
1250             expect![[r#"
1251                 *bar()*
1252                 ```rust
1253                 u32
1254                 ```
1255             "#]],
1256         );
1257     }
1258
1259     #[test]
1260     fn test_hover_through_literal_string_in_macro() {
1261         check(
1262             r#"
1263 macro_rules! arr { ($($tt:tt)*) => { [$($tt)*)] } }
1264 fn foo() {
1265     let mastered_for_itunes = "";
1266     let _ = arr!("Tr<|>acks", &mastered_for_itunes);
1267 }
1268 "#,
1269             expect![[r#"
1270                 *"Tracks"*
1271                 ```rust
1272                 &str
1273                 ```
1274             "#]],
1275         );
1276     }
1277
1278     #[test]
1279     fn test_hover_through_assert_macro() {
1280         check(
1281             r#"
1282 #[rustc_builtin_macro]
1283 macro_rules! assert {}
1284
1285 fn bar() -> bool { true }
1286 fn foo() {
1287     assert!(ba<|>r());
1288 }
1289 "#,
1290             expect![[r#"
1291                 *bar*
1292
1293                 ```rust
1294                 test
1295                 ```
1296
1297                 ```rust
1298                 fn bar() -> bool
1299                 ```
1300             "#]],
1301         );
1302     }
1303
1304     #[test]
1305     fn test_hover_through_literal_string_in_builtin_macro() {
1306         check_hover_no_result(
1307             r#"
1308             #[rustc_builtin_macro]
1309             macro_rules! format {}
1310
1311             fn foo() {
1312                 format!("hel<|>lo {}", 0);
1313             }
1314             "#,
1315         );
1316     }
1317
1318     #[test]
1319     fn test_hover_non_ascii_space_doc() {
1320         check(
1321             "
1322 /// <- `\u{3000}` here
1323 fn foo() { }
1324
1325 fn bar() { fo<|>o(); }
1326 ",
1327             expect![[r#"
1328                 *foo*
1329
1330                 ```rust
1331                 test
1332                 ```
1333
1334                 ```rust
1335                 fn foo()
1336                 ```
1337
1338                 ---
1339
1340                 \<- ` ` here
1341             "#]],
1342         );
1343     }
1344
1345     #[test]
1346     fn test_hover_function_show_qualifiers() {
1347         check(
1348             r#"async fn foo<|>() {}"#,
1349             expect![[r#"
1350                 *foo*
1351
1352                 ```rust
1353                 test
1354                 ```
1355
1356                 ```rust
1357                 async fn foo()
1358                 ```
1359             "#]],
1360         );
1361         check(
1362             r#"pub const unsafe fn foo<|>() {}"#,
1363             expect![[r#"
1364                 *foo*
1365
1366                 ```rust
1367                 test
1368                 ```
1369
1370                 ```rust
1371                 pub const unsafe fn foo()
1372                 ```
1373             "#]],
1374         );
1375         check(
1376             r#"pub(crate) async unsafe extern "C" fn foo<|>() {}"#,
1377             expect![[r#"
1378                 *foo*
1379
1380                 ```rust
1381                 test
1382                 ```
1383
1384                 ```rust
1385                 pub(crate) async unsafe extern "C" fn foo()
1386                 ```
1387             "#]],
1388         );
1389     }
1390
1391     #[test]
1392     fn test_hover_trait_show_qualifiers() {
1393         check_actions(
1394             r"unsafe trait foo<|>() {}",
1395             expect![[r#"
1396                 [
1397                     Implementaion(
1398                         FilePosition {
1399                             file_id: FileId(
1400                                 0,
1401                             ),
1402                             offset: 13,
1403                         },
1404                     ),
1405                 ]
1406             "#]],
1407         );
1408     }
1409
1410     #[test]
1411     fn test_hover_extern_crate() {
1412         check(
1413             r#"
1414 //- /main.rs crate:main deps:std
1415 extern crate st<|>d;
1416 //- /std/lib.rs crate:std
1417 //! Standard library for this test
1418 //!
1419 //! Printed?
1420 //! abc123
1421             "#,
1422             expect![[r#"
1423             *std*
1424             Standard library for this test
1425
1426             Printed?
1427             abc123
1428             "#]],
1429         );
1430         check(
1431             r#"
1432 //- /main.rs crate:main deps:std
1433 extern crate std as ab<|>c;
1434 //- /std/lib.rs crate:std
1435 //! Standard library for this test
1436 //!
1437 //! Printed?
1438 //! abc123
1439             "#,
1440             expect![[r#"
1441             *abc*
1442             Standard library for this test
1443
1444             Printed?
1445             abc123
1446             "#]],
1447         );
1448     }
1449
1450     #[test]
1451     fn test_hover_mod_with_same_name_as_function() {
1452         check(
1453             r#"
1454 use self::m<|>y::Bar;
1455 mod my { pub struct Bar; }
1456
1457 fn my() {}
1458 "#,
1459             expect![[r#"
1460                 *my*
1461
1462                 ```rust
1463                 test
1464                 ```
1465
1466                 ```rust
1467                 mod my
1468                 ```
1469             "#]],
1470         );
1471     }
1472
1473     #[test]
1474     fn test_hover_struct_doc_comment() {
1475         check(
1476             r#"
1477 /// bar docs
1478 struct Bar;
1479
1480 fn foo() { let bar = Ba<|>r; }
1481 "#,
1482             expect![[r#"
1483                 *Bar*
1484
1485                 ```rust
1486                 test
1487                 ```
1488
1489                 ```rust
1490                 struct Bar
1491                 ```
1492
1493                 ---
1494
1495                 bar docs
1496             "#]],
1497         );
1498     }
1499
1500     #[test]
1501     fn test_hover_struct_doc_attr() {
1502         check(
1503             r#"
1504 #[doc = "bar docs"]
1505 struct Bar;
1506
1507 fn foo() { let bar = Ba<|>r; }
1508 "#,
1509             expect![[r#"
1510                 *Bar*
1511
1512                 ```rust
1513                 test
1514                 ```
1515
1516                 ```rust
1517                 struct Bar
1518                 ```
1519
1520                 ---
1521
1522                 bar docs
1523             "#]],
1524         );
1525     }
1526
1527     #[test]
1528     fn test_hover_struct_doc_attr_multiple_and_mixed() {
1529         check(
1530             r#"
1531 /// bar docs 0
1532 #[doc = "bar docs 1"]
1533 #[doc = "bar docs 2"]
1534 struct Bar;
1535
1536 fn foo() { let bar = Ba<|>r; }
1537 "#,
1538             expect![[r#"
1539                 *Bar*
1540
1541                 ```rust
1542                 test
1543                 ```
1544
1545                 ```rust
1546                 struct Bar
1547                 ```
1548
1549                 ---
1550
1551                 bar docs 0
1552                 bar docs 1
1553                 bar docs 2
1554             "#]],
1555         );
1556     }
1557
1558     #[test]
1559     fn test_hover_path_link() {
1560         check(
1561             r#"
1562 pub struct Foo;
1563 /// [Foo](struct.Foo.html)
1564 pub struct B<|>ar
1565 "#,
1566             expect![[r#"
1567                 *Bar*
1568
1569                 ```rust
1570                 test
1571                 ```
1572
1573                 ```rust
1574                 pub struct Bar
1575                 ```
1576
1577                 ---
1578
1579                 [Foo](https://docs.rs/test/*/test/struct.Foo.html)
1580             "#]],
1581         );
1582     }
1583
1584     #[test]
1585     fn test_hover_path_link_no_strip() {
1586         check(
1587             r#"
1588 pub struct Foo;
1589 /// [struct Foo](struct.Foo.html)
1590 pub struct B<|>ar
1591 "#,
1592             expect![[r#"
1593                 *Bar*
1594
1595                 ```rust
1596                 test
1597                 ```
1598
1599                 ```rust
1600                 pub struct Bar
1601                 ```
1602
1603                 ---
1604
1605                 [struct Foo](https://docs.rs/test/*/test/struct.Foo.html)
1606             "#]],
1607         );
1608     }
1609
1610     #[ignore = "path based links currently only support documentation on ModuleDef items"]
1611     #[test]
1612     fn test_hover_path_link_field() {
1613         check(
1614             r#"
1615 pub struct Foo;
1616 pub struct Bar {
1617     /// [Foo](struct.Foo.html)
1618     fie<|>ld: ()
1619 }
1620 "#,
1621             expect![[r#"
1622                 *field*
1623
1624                 ```rust
1625                 test::Bar
1626                 ```
1627
1628                 ```rust
1629                 field: ()
1630                 ```
1631
1632                 ---
1633
1634                 [Foo](https://docs.rs/test/*/test/struct.Foo.html)
1635             "#]],
1636         );
1637     }
1638
1639     #[test]
1640     fn test_hover_intra_link() {
1641         check(
1642             r#"
1643 pub mod foo {
1644     pub struct Foo;
1645 }
1646 /// [Foo](foo::Foo)
1647 pub struct B<|>ar
1648 "#,
1649             expect![[r#"
1650                 *Bar*
1651
1652                 ```rust
1653                 test
1654                 ```
1655
1656                 ```rust
1657                 pub struct Bar
1658                 ```
1659
1660                 ---
1661
1662                 [Foo](https://docs.rs/test/*/test/foo/struct.Foo.html)
1663             "#]],
1664         );
1665     }
1666
1667     #[test]
1668     fn test_hover_intra_link_html_root_url() {
1669         check(
1670             r#"
1671 #![doc(arbitrary_attribute = "test", html_root_url = "https:/example.com", arbitrary_attribute2)]
1672
1673 pub mod foo {
1674     pub struct Foo;
1675 }
1676 /// [Foo](foo::Foo)
1677 pub struct B<|>ar
1678 "#,
1679             expect![[r#"
1680                 *Bar*
1681
1682                 ```rust
1683                 test
1684                 ```
1685
1686                 ```rust
1687                 pub struct Bar
1688                 ```
1689
1690                 ---
1691
1692                 [Foo](https://example.com/test/foo/struct.Foo.html)
1693             "#]],
1694         );
1695     }
1696
1697     #[test]
1698     fn test_hover_intra_link_shortlink() {
1699         check(
1700             r#"
1701 pub struct Foo;
1702 /// [Foo]
1703 pub struct B<|>ar
1704 "#,
1705             expect![[r#"
1706                 *Bar*
1707
1708                 ```rust
1709                 test
1710                 ```
1711
1712                 ```rust
1713                 pub struct Bar
1714                 ```
1715
1716                 ---
1717
1718                 [Foo](https://docs.rs/test/*/test/struct.Foo.html)
1719             "#]],
1720         );
1721     }
1722
1723     #[test]
1724     fn test_hover_intra_link_shortlink_code() {
1725         check(
1726             r#"
1727 pub struct Foo;
1728 /// [`Foo`]
1729 pub struct B<|>ar
1730 "#,
1731             expect![[r#"
1732                 *Bar*
1733
1734                 ```rust
1735                 test
1736                 ```
1737
1738                 ```rust
1739                 pub struct Bar
1740                 ```
1741
1742                 ---
1743
1744                 [`Foo`](https://docs.rs/test/*/test/struct.Foo.html)
1745             "#]],
1746         );
1747     }
1748
1749     #[test]
1750     fn test_hover_intra_link_namespaced() {
1751         check(
1752             r#"
1753 pub struct Foo;
1754 fn Foo() {}
1755 /// [Foo()]
1756 pub struct B<|>ar
1757 "#,
1758             expect![[r#"
1759                 *Bar*
1760
1761                 ```rust
1762                 test
1763                 ```
1764
1765                 ```rust
1766                 pub struct Bar
1767                 ```
1768
1769                 ---
1770
1771                 [Foo](https://docs.rs/test/*/test/struct.Foo.html)
1772             "#]],
1773         );
1774     }
1775
1776     #[test]
1777     fn test_hover_intra_link_shortlink_namspaced_code() {
1778         check(
1779             r#"
1780 pub struct Foo;
1781 /// [`struct Foo`]
1782 pub struct B<|>ar
1783 "#,
1784             expect![[r#"
1785                 *Bar*
1786
1787                 ```rust
1788                 test
1789                 ```
1790
1791                 ```rust
1792                 pub struct Bar
1793                 ```
1794
1795                 ---
1796
1797                 [`Foo`](https://docs.rs/test/*/test/struct.Foo.html)
1798             "#]],
1799         );
1800     }
1801
1802     #[test]
1803     fn test_hover_intra_link_shortlink_namspaced_code_with_at() {
1804         check(
1805             r#"
1806 pub struct Foo;
1807 /// [`struct@Foo`]
1808 pub struct B<|>ar
1809 "#,
1810             expect![[r#"
1811                 *Bar*
1812
1813                 ```rust
1814                 test
1815                 ```
1816
1817                 ```rust
1818                 pub struct Bar
1819                 ```
1820
1821                 ---
1822
1823                 [`Foo`](https://docs.rs/test/*/test/struct.Foo.html)
1824             "#]],
1825         );
1826     }
1827
1828     #[test]
1829     fn test_hover_intra_link_reference() {
1830         check(
1831             r#"
1832 pub struct Foo;
1833 /// [my Foo][foo]
1834 ///
1835 /// [foo]: Foo
1836 pub struct B<|>ar
1837 "#,
1838             expect![[r#"
1839                 *Bar*
1840
1841                 ```rust
1842                 test
1843                 ```
1844
1845                 ```rust
1846                 pub struct Bar
1847                 ```
1848
1849                 ---
1850
1851                 [my Foo](https://docs.rs/test/*/test/struct.Foo.html)
1852             "#]],
1853         );
1854     }
1855
1856     #[test]
1857     fn test_hover_external_url() {
1858         check(
1859             r#"
1860 pub struct Foo;
1861 /// [external](https://www.google.com)
1862 pub struct B<|>ar
1863 "#,
1864             expect![[r#"
1865                 *Bar*
1866
1867                 ```rust
1868                 test
1869                 ```
1870
1871                 ```rust
1872                 pub struct Bar
1873                 ```
1874
1875                 ---
1876
1877                 [external](https://www.google.com)
1878             "#]],
1879         );
1880     }
1881
1882     // Check that we don't rewrite links which we can't identify
1883     #[test]
1884     fn test_hover_unknown_target() {
1885         check(
1886             r#"
1887 pub struct Foo;
1888 /// [baz](Baz)
1889 pub struct B<|>ar
1890 "#,
1891             expect![[r#"
1892                 *Bar*
1893
1894                 ```rust
1895                 test
1896                 ```
1897
1898                 ```rust
1899                 pub struct Bar
1900                 ```
1901
1902                 ---
1903
1904                 [baz](Baz)
1905             "#]],
1906         );
1907     }
1908
1909     #[test]
1910     fn test_doc_links_enum_variant() {
1911         check(
1912             r#"
1913 enum E {
1914     /// [E]
1915     V<|> { field: i32 }
1916 }
1917 "#,
1918             expect![[r#"
1919                 *V*
1920
1921                 ```rust
1922                 test::E
1923                 ```
1924
1925                 ```rust
1926                 V
1927                 ```
1928
1929                 ---
1930
1931                 [E](https://docs.rs/test/*/test/enum.E.html)
1932             "#]],
1933         );
1934     }
1935
1936     #[test]
1937     fn test_doc_links_field() {
1938         check(
1939             r#"
1940 struct S {
1941     /// [`S`]
1942     field<|>: i32
1943 }
1944 "#,
1945             expect![[r#"
1946                 *field*
1947
1948                 ```rust
1949                 test::S
1950                 ```
1951
1952                 ```rust
1953                 field: i32
1954                 ```
1955
1956                 ---
1957
1958                 [`S`](https://docs.rs/test/*/test/struct.S.html)
1959             "#]],
1960         );
1961     }
1962
1963     #[test]
1964     fn test_hover_no_links() {
1965         check_hover_no_links(
1966             r#"
1967 /// Test cases:
1968 /// case 1.  bare URL: https://www.example.com/
1969 /// case 2.  inline URL with title: [example](https://www.example.com/)
1970 /// case 3.  code refrence: [`Result`]
1971 /// case 4.  code refrence but miss footnote: [`String`]
1972 /// case 5.  autolink: <http://www.example.com/>
1973 /// case 6.  email address: <test@example.com>
1974 /// case 7.  refrence: [example][example]
1975 /// case 8.  collapsed link: [example][]
1976 /// case 9.  shortcut link: [example]
1977 /// case 10. inline without URL: [example]()
1978 /// case 11. refrence: [foo][foo]
1979 /// case 12. refrence: [foo][bar]
1980 /// case 13. collapsed link: [foo][]
1981 /// case 14. shortcut link: [foo]
1982 /// case 15. inline without URL: [foo]()
1983 /// case 16. just escaped text: \[foo]
1984 /// case 17. inline link: [Foo](foo::Foo)
1985 ///
1986 /// [`Result`]: ../../std/result/enum.Result.html
1987 /// [^example]: https://www.example.com/
1988 pub fn fo<|>o() {}
1989 "#,
1990             expect![[r#"
1991                 *foo*
1992
1993                 ```rust
1994                 test
1995                 ```
1996
1997                 ```rust
1998                 pub fn foo()
1999                 ```
2000
2001                 ---
2002
2003                 Test cases:
2004                 case 1.  bare URL: https://www.example.com/
2005                 case 2.  inline URL with title: [example](https://www.example.com/)
2006                 case 3.  code refrence: `Result`
2007                 case 4.  code refrence but miss footnote: `String`
2008                 case 5.  autolink: http://www.example.com/
2009                 case 6.  email address: test@example.com
2010                 case 7.  refrence: example
2011                 case 8.  collapsed link: example
2012                 case 9.  shortcut link: example
2013                 case 10. inline without URL: example
2014                 case 11. refrence: foo
2015                 case 12. refrence: foo
2016                 case 13. collapsed link: foo
2017                 case 14. shortcut link: foo
2018                 case 15. inline without URL: foo
2019                 case 16. just escaped text: \[foo]
2020                 case 17. inline link: Foo
2021
2022                 [^example]: https://www.example.com/
2023             "#]],
2024         );
2025     }
2026
2027     #[test]
2028     fn test_hover_macro_generated_struct_fn_doc_comment() {
2029         mark::check!(hover_macro_generated_struct_fn_doc_comment);
2030
2031         check(
2032             r#"
2033 macro_rules! bar {
2034     () => {
2035         struct Bar;
2036         impl Bar {
2037             /// Do the foo
2038             fn foo(&self) {}
2039         }
2040     }
2041 }
2042
2043 bar!();
2044
2045 fn foo() { let bar = Bar; bar.fo<|>o(); }
2046 "#,
2047             expect![[r#"
2048                 *foo*
2049
2050                 ```rust
2051                 test::Bar
2052                 ```
2053
2054                 ```rust
2055                 fn foo(&self)
2056                 ```
2057
2058                 ---
2059
2060                 Do the foo
2061             "#]],
2062         );
2063     }
2064
2065     #[test]
2066     fn test_hover_macro_generated_struct_fn_doc_attr() {
2067         mark::check!(hover_macro_generated_struct_fn_doc_attr);
2068
2069         check(
2070             r#"
2071 macro_rules! bar {
2072     () => {
2073         struct Bar;
2074         impl Bar {
2075             #[doc = "Do the foo"]
2076             fn foo(&self) {}
2077         }
2078     }
2079 }
2080
2081 bar!();
2082
2083 fn foo() { let bar = Bar; bar.fo<|>o(); }
2084 "#,
2085             expect![[r#"
2086                 *foo*
2087
2088                 ```rust
2089                 test::Bar
2090                 ```
2091
2092                 ```rust
2093                 fn foo(&self)
2094                 ```
2095
2096                 ---
2097
2098                 Do the foo
2099             "#]],
2100         );
2101     }
2102
2103     #[test]
2104     fn test_hover_trait_has_impl_action() {
2105         check_actions(
2106             r#"trait foo<|>() {}"#,
2107             expect![[r#"
2108                 [
2109                     Implementaion(
2110                         FilePosition {
2111                             file_id: FileId(
2112                                 0,
2113                             ),
2114                             offset: 6,
2115                         },
2116                     ),
2117                 ]
2118             "#]],
2119         );
2120     }
2121
2122     #[test]
2123     fn test_hover_struct_has_impl_action() {
2124         check_actions(
2125             r"struct foo<|>() {}",
2126             expect![[r#"
2127                 [
2128                     Implementaion(
2129                         FilePosition {
2130                             file_id: FileId(
2131                                 0,
2132                             ),
2133                             offset: 7,
2134                         },
2135                     ),
2136                 ]
2137             "#]],
2138         );
2139     }
2140
2141     #[test]
2142     fn test_hover_union_has_impl_action() {
2143         check_actions(
2144             r#"union foo<|>() {}"#,
2145             expect![[r#"
2146                 [
2147                     Implementaion(
2148                         FilePosition {
2149                             file_id: FileId(
2150                                 0,
2151                             ),
2152                             offset: 6,
2153                         },
2154                     ),
2155                 ]
2156             "#]],
2157         );
2158     }
2159
2160     #[test]
2161     fn test_hover_enum_has_impl_action() {
2162         check_actions(
2163             r"enum foo<|>() { A, B }",
2164             expect![[r#"
2165                 [
2166                     Implementaion(
2167                         FilePosition {
2168                             file_id: FileId(
2169                                 0,
2170                             ),
2171                             offset: 5,
2172                         },
2173                     ),
2174                 ]
2175             "#]],
2176         );
2177     }
2178
2179     #[test]
2180     fn test_hover_test_has_action() {
2181         check_actions(
2182             r#"
2183 #[test]
2184 fn foo_<|>test() {}
2185 "#,
2186             expect![[r#"
2187                 [
2188                     Runnable(
2189                         Runnable {
2190                             nav: NavigationTarget {
2191                                 file_id: FileId(
2192                                     0,
2193                                 ),
2194                                 full_range: 0..24,
2195                                 focus_range: 11..19,
2196                                 name: "foo_test",
2197                                 kind: Function,
2198                             },
2199                             kind: Test {
2200                                 test_id: Path(
2201                                     "foo_test",
2202                                 ),
2203                                 attr: TestAttr {
2204                                     ignore: false,
2205                                 },
2206                             },
2207                             cfg: None,
2208                         },
2209                     ),
2210                 ]
2211             "#]],
2212         );
2213     }
2214
2215     #[test]
2216     fn test_hover_test_mod_has_action() {
2217         check_actions(
2218             r#"
2219 mod tests<|> {
2220     #[test]
2221     fn foo_test() {}
2222 }
2223 "#,
2224             expect![[r#"
2225                 [
2226                     Runnable(
2227                         Runnable {
2228                             nav: NavigationTarget {
2229                                 file_id: FileId(
2230                                     0,
2231                                 ),
2232                                 full_range: 0..46,
2233                                 focus_range: 4..9,
2234                                 name: "tests",
2235                                 kind: Module,
2236                             },
2237                             kind: TestMod {
2238                                 path: "tests",
2239                             },
2240                             cfg: None,
2241                         },
2242                     ),
2243                 ]
2244             "#]],
2245         );
2246     }
2247
2248     #[test]
2249     fn test_hover_struct_has_goto_type_action() {
2250         check_actions(
2251             r#"
2252 struct S{ f1: u32 }
2253
2254 fn main() { let s<|>t = S{ f1:0 }; }
2255             "#,
2256             expect![[r#"
2257                 [
2258                     GoToType(
2259                         [
2260                             HoverGotoTypeData {
2261                                 mod_path: "test::S",
2262                                 nav: NavigationTarget {
2263                                     file_id: FileId(
2264                                         0,
2265                                     ),
2266                                     full_range: 0..19,
2267                                     focus_range: 7..8,
2268                                     name: "S",
2269                                     kind: Struct,
2270                                     description: "struct S",
2271                                 },
2272                             },
2273                         ],
2274                     ),
2275                 ]
2276             "#]],
2277         );
2278     }
2279
2280     #[test]
2281     fn test_hover_generic_struct_has_goto_type_actions() {
2282         check_actions(
2283             r#"
2284 struct Arg(u32);
2285 struct S<T>{ f1: T }
2286
2287 fn main() { let s<|>t = S{ f1:Arg(0) }; }
2288 "#,
2289             expect![[r#"
2290                 [
2291                     GoToType(
2292                         [
2293                             HoverGotoTypeData {
2294                                 mod_path: "test::S",
2295                                 nav: NavigationTarget {
2296                                     file_id: FileId(
2297                                         0,
2298                                     ),
2299                                     full_range: 17..37,
2300                                     focus_range: 24..25,
2301                                     name: "S",
2302                                     kind: Struct,
2303                                     description: "struct S",
2304                                 },
2305                             },
2306                             HoverGotoTypeData {
2307                                 mod_path: "test::Arg",
2308                                 nav: NavigationTarget {
2309                                     file_id: FileId(
2310                                         0,
2311                                     ),
2312                                     full_range: 0..16,
2313                                     focus_range: 7..10,
2314                                     name: "Arg",
2315                                     kind: Struct,
2316                                     description: "struct Arg",
2317                                 },
2318                             },
2319                         ],
2320                     ),
2321                 ]
2322             "#]],
2323         );
2324     }
2325
2326     #[test]
2327     fn test_hover_generic_struct_has_flattened_goto_type_actions() {
2328         check_actions(
2329             r#"
2330 struct Arg(u32);
2331 struct S<T>{ f1: T }
2332
2333 fn main() { let s<|>t = S{ f1: S{ f1: Arg(0) } }; }
2334             "#,
2335             expect![[r#"
2336                 [
2337                     GoToType(
2338                         [
2339                             HoverGotoTypeData {
2340                                 mod_path: "test::S",
2341                                 nav: NavigationTarget {
2342                                     file_id: FileId(
2343                                         0,
2344                                     ),
2345                                     full_range: 17..37,
2346                                     focus_range: 24..25,
2347                                     name: "S",
2348                                     kind: Struct,
2349                                     description: "struct S",
2350                                 },
2351                             },
2352                             HoverGotoTypeData {
2353                                 mod_path: "test::Arg",
2354                                 nav: NavigationTarget {
2355                                     file_id: FileId(
2356                                         0,
2357                                     ),
2358                                     full_range: 0..16,
2359                                     focus_range: 7..10,
2360                                     name: "Arg",
2361                                     kind: Struct,
2362                                     description: "struct Arg",
2363                                 },
2364                             },
2365                         ],
2366                     ),
2367                 ]
2368             "#]],
2369         );
2370     }
2371
2372     #[test]
2373     fn test_hover_tuple_has_goto_type_actions() {
2374         check_actions(
2375             r#"
2376 struct A(u32);
2377 struct B(u32);
2378 mod M {
2379     pub struct C(u32);
2380 }
2381
2382 fn main() { let s<|>t = (A(1), B(2), M::C(3) ); }
2383 "#,
2384             expect![[r#"
2385                 [
2386                     GoToType(
2387                         [
2388                             HoverGotoTypeData {
2389                                 mod_path: "test::A",
2390                                 nav: NavigationTarget {
2391                                     file_id: FileId(
2392                                         0,
2393                                     ),
2394                                     full_range: 0..14,
2395                                     focus_range: 7..8,
2396                                     name: "A",
2397                                     kind: Struct,
2398                                     description: "struct A",
2399                                 },
2400                             },
2401                             HoverGotoTypeData {
2402                                 mod_path: "test::B",
2403                                 nav: NavigationTarget {
2404                                     file_id: FileId(
2405                                         0,
2406                                     ),
2407                                     full_range: 15..29,
2408                                     focus_range: 22..23,
2409                                     name: "B",
2410                                     kind: Struct,
2411                                     description: "struct B",
2412                                 },
2413                             },
2414                             HoverGotoTypeData {
2415                                 mod_path: "test::M::C",
2416                                 nav: NavigationTarget {
2417                                     file_id: FileId(
2418                                         0,
2419                                     ),
2420                                     full_range: 42..60,
2421                                     focus_range: 53..54,
2422                                     name: "C",
2423                                     kind: Struct,
2424                                     description: "pub struct C",
2425                                 },
2426                             },
2427                         ],
2428                     ),
2429                 ]
2430             "#]],
2431         );
2432     }
2433
2434     #[test]
2435     fn test_hover_return_impl_trait_has_goto_type_action() {
2436         check_actions(
2437             r#"
2438 trait Foo {}
2439 fn foo() -> impl Foo {}
2440
2441 fn main() { let s<|>t = foo(); }
2442 "#,
2443             expect![[r#"
2444                 [
2445                     GoToType(
2446                         [
2447                             HoverGotoTypeData {
2448                                 mod_path: "test::Foo",
2449                                 nav: NavigationTarget {
2450                                     file_id: FileId(
2451                                         0,
2452                                     ),
2453                                     full_range: 0..12,
2454                                     focus_range: 6..9,
2455                                     name: "Foo",
2456                                     kind: Trait,
2457                                     description: "trait Foo",
2458                                 },
2459                             },
2460                         ],
2461                     ),
2462                 ]
2463             "#]],
2464         );
2465     }
2466
2467     #[test]
2468     fn test_hover_generic_return_impl_trait_has_goto_type_action() {
2469         check_actions(
2470             r#"
2471 trait Foo<T> {}
2472 struct S;
2473 fn foo() -> impl Foo<S> {}
2474
2475 fn main() { let s<|>t = foo(); }
2476 "#,
2477             expect![[r#"
2478                 [
2479                     GoToType(
2480                         [
2481                             HoverGotoTypeData {
2482                                 mod_path: "test::Foo",
2483                                 nav: NavigationTarget {
2484                                     file_id: FileId(
2485                                         0,
2486                                     ),
2487                                     full_range: 0..15,
2488                                     focus_range: 6..9,
2489                                     name: "Foo",
2490                                     kind: Trait,
2491                                     description: "trait Foo",
2492                                 },
2493                             },
2494                             HoverGotoTypeData {
2495                                 mod_path: "test::S",
2496                                 nav: NavigationTarget {
2497                                     file_id: FileId(
2498                                         0,
2499                                     ),
2500                                     full_range: 16..25,
2501                                     focus_range: 23..24,
2502                                     name: "S",
2503                                     kind: Struct,
2504                                     description: "struct S",
2505                                 },
2506                             },
2507                         ],
2508                     ),
2509                 ]
2510             "#]],
2511         );
2512     }
2513
2514     #[test]
2515     fn test_hover_return_impl_traits_has_goto_type_action() {
2516         check_actions(
2517             r#"
2518 trait Foo {}
2519 trait Bar {}
2520 fn foo() -> impl Foo + Bar {}
2521
2522 fn main() { let s<|>t = foo(); }
2523             "#,
2524             expect![[r#"
2525                 [
2526                     GoToType(
2527                         [
2528                             HoverGotoTypeData {
2529                                 mod_path: "test::Foo",
2530                                 nav: NavigationTarget {
2531                                     file_id: FileId(
2532                                         0,
2533                                     ),
2534                                     full_range: 0..12,
2535                                     focus_range: 6..9,
2536                                     name: "Foo",
2537                                     kind: Trait,
2538                                     description: "trait Foo",
2539                                 },
2540                             },
2541                             HoverGotoTypeData {
2542                                 mod_path: "test::Bar",
2543                                 nav: NavigationTarget {
2544                                     file_id: FileId(
2545                                         0,
2546                                     ),
2547                                     full_range: 13..25,
2548                                     focus_range: 19..22,
2549                                     name: "Bar",
2550                                     kind: Trait,
2551                                     description: "trait Bar",
2552                                 },
2553                             },
2554                         ],
2555                     ),
2556                 ]
2557             "#]],
2558         );
2559     }
2560
2561     #[test]
2562     fn test_hover_generic_return_impl_traits_has_goto_type_action() {
2563         check_actions(
2564             r#"
2565 trait Foo<T> {}
2566 trait Bar<T> {}
2567 struct S1 {}
2568 struct S2 {}
2569
2570 fn foo() -> impl Foo<S1> + Bar<S2> {}
2571
2572 fn main() { let s<|>t = foo(); }
2573 "#,
2574             expect![[r#"
2575                 [
2576                     GoToType(
2577                         [
2578                             HoverGotoTypeData {
2579                                 mod_path: "test::Foo",
2580                                 nav: NavigationTarget {
2581                                     file_id: FileId(
2582                                         0,
2583                                     ),
2584                                     full_range: 0..15,
2585                                     focus_range: 6..9,
2586                                     name: "Foo",
2587                                     kind: Trait,
2588                                     description: "trait Foo",
2589                                 },
2590                             },
2591                             HoverGotoTypeData {
2592                                 mod_path: "test::Bar",
2593                                 nav: NavigationTarget {
2594                                     file_id: FileId(
2595                                         0,
2596                                     ),
2597                                     full_range: 16..31,
2598                                     focus_range: 22..25,
2599                                     name: "Bar",
2600                                     kind: Trait,
2601                                     description: "trait Bar",
2602                                 },
2603                             },
2604                             HoverGotoTypeData {
2605                                 mod_path: "test::S1",
2606                                 nav: NavigationTarget {
2607                                     file_id: FileId(
2608                                         0,
2609                                     ),
2610                                     full_range: 32..44,
2611                                     focus_range: 39..41,
2612                                     name: "S1",
2613                                     kind: Struct,
2614                                     description: "struct S1",
2615                                 },
2616                             },
2617                             HoverGotoTypeData {
2618                                 mod_path: "test::S2",
2619                                 nav: NavigationTarget {
2620                                     file_id: FileId(
2621                                         0,
2622                                     ),
2623                                     full_range: 45..57,
2624                                     focus_range: 52..54,
2625                                     name: "S2",
2626                                     kind: Struct,
2627                                     description: "struct S2",
2628                                 },
2629                             },
2630                         ],
2631                     ),
2632                 ]
2633             "#]],
2634         );
2635     }
2636
2637     #[test]
2638     fn test_hover_arg_impl_trait_has_goto_type_action() {
2639         check_actions(
2640             r#"
2641 trait Foo {}
2642 fn foo(ar<|>g: &impl Foo) {}
2643 "#,
2644             expect![[r#"
2645                 [
2646                     GoToType(
2647                         [
2648                             HoverGotoTypeData {
2649                                 mod_path: "test::Foo",
2650                                 nav: NavigationTarget {
2651                                     file_id: FileId(
2652                                         0,
2653                                     ),
2654                                     full_range: 0..12,
2655                                     focus_range: 6..9,
2656                                     name: "Foo",
2657                                     kind: Trait,
2658                                     description: "trait Foo",
2659                                 },
2660                             },
2661                         ],
2662                     ),
2663                 ]
2664             "#]],
2665         );
2666     }
2667
2668     #[test]
2669     fn test_hover_arg_impl_traits_has_goto_type_action() {
2670         check_actions(
2671             r#"
2672 trait Foo {}
2673 trait Bar<T> {}
2674 struct S{}
2675
2676 fn foo(ar<|>g: &impl Foo + Bar<S>) {}
2677 "#,
2678             expect![[r#"
2679                 [
2680                     GoToType(
2681                         [
2682                             HoverGotoTypeData {
2683                                 mod_path: "test::Foo",
2684                                 nav: NavigationTarget {
2685                                     file_id: FileId(
2686                                         0,
2687                                     ),
2688                                     full_range: 0..12,
2689                                     focus_range: 6..9,
2690                                     name: "Foo",
2691                                     kind: Trait,
2692                                     description: "trait Foo",
2693                                 },
2694                             },
2695                             HoverGotoTypeData {
2696                                 mod_path: "test::Bar",
2697                                 nav: NavigationTarget {
2698                                     file_id: FileId(
2699                                         0,
2700                                     ),
2701                                     full_range: 13..28,
2702                                     focus_range: 19..22,
2703                                     name: "Bar",
2704                                     kind: Trait,
2705                                     description: "trait Bar",
2706                                 },
2707                             },
2708                             HoverGotoTypeData {
2709                                 mod_path: "test::S",
2710                                 nav: NavigationTarget {
2711                                     file_id: FileId(
2712                                         0,
2713                                     ),
2714                                     full_range: 29..39,
2715                                     focus_range: 36..37,
2716                                     name: "S",
2717                                     kind: Struct,
2718                                     description: "struct S",
2719                                 },
2720                             },
2721                         ],
2722                     ),
2723                 ]
2724             "#]],
2725         );
2726     }
2727
2728     #[test]
2729     fn test_hover_async_block_impl_trait_has_goto_type_action() {
2730         check_actions(
2731             r#"
2732 struct S;
2733 fn foo() {
2734     let fo<|>o = async { S };
2735 }
2736
2737 #[prelude_import] use future::*;
2738 mod future {
2739     #[lang = "future_trait"]
2740     pub trait Future { type Output; }
2741 }
2742 "#,
2743             expect![[r#"
2744                 [
2745                     GoToType(
2746                         [
2747                             HoverGotoTypeData {
2748                                 mod_path: "test::future::Future",
2749                                 nav: NavigationTarget {
2750                                     file_id: FileId(
2751                                         0,
2752                                     ),
2753                                     full_range: 101..163,
2754                                     focus_range: 140..146,
2755                                     name: "Future",
2756                                     kind: Trait,
2757                                     description: "pub trait Future",
2758                                 },
2759                             },
2760                             HoverGotoTypeData {
2761                                 mod_path: "test::S",
2762                                 nav: NavigationTarget {
2763                                     file_id: FileId(
2764                                         0,
2765                                     ),
2766                                     full_range: 0..9,
2767                                     focus_range: 7..8,
2768                                     name: "S",
2769                                     kind: Struct,
2770                                     description: "struct S",
2771                                 },
2772                             },
2773                         ],
2774                     ),
2775                 ]
2776             "#]],
2777         );
2778     }
2779
2780     #[test]
2781     fn test_hover_arg_generic_impl_trait_has_goto_type_action() {
2782         check_actions(
2783             r#"
2784 trait Foo<T> {}
2785 struct S {}
2786 fn foo(ar<|>g: &impl Foo<S>) {}
2787 "#,
2788             expect![[r#"
2789                 [
2790                     GoToType(
2791                         [
2792                             HoverGotoTypeData {
2793                                 mod_path: "test::Foo",
2794                                 nav: NavigationTarget {
2795                                     file_id: FileId(
2796                                         0,
2797                                     ),
2798                                     full_range: 0..15,
2799                                     focus_range: 6..9,
2800                                     name: "Foo",
2801                                     kind: Trait,
2802                                     description: "trait Foo",
2803                                 },
2804                             },
2805                             HoverGotoTypeData {
2806                                 mod_path: "test::S",
2807                                 nav: NavigationTarget {
2808                                     file_id: FileId(
2809                                         0,
2810                                     ),
2811                                     full_range: 16..27,
2812                                     focus_range: 23..24,
2813                                     name: "S",
2814                                     kind: Struct,
2815                                     description: "struct S",
2816                                 },
2817                             },
2818                         ],
2819                     ),
2820                 ]
2821             "#]],
2822         );
2823     }
2824
2825     #[test]
2826     fn test_hover_dyn_return_has_goto_type_action() {
2827         check_actions(
2828             r#"
2829 trait Foo {}
2830 struct S;
2831 impl Foo for S {}
2832
2833 struct B<T>{}
2834 fn foo() -> B<dyn Foo> {}
2835
2836 fn main() { let s<|>t = foo(); }
2837 "#,
2838             expect![[r#"
2839                 [
2840                     GoToType(
2841                         [
2842                             HoverGotoTypeData {
2843                                 mod_path: "test::B",
2844                                 nav: NavigationTarget {
2845                                     file_id: FileId(
2846                                         0,
2847                                     ),
2848                                     full_range: 42..55,
2849                                     focus_range: 49..50,
2850                                     name: "B",
2851                                     kind: Struct,
2852                                     description: "struct B",
2853                                 },
2854                             },
2855                             HoverGotoTypeData {
2856                                 mod_path: "test::Foo",
2857                                 nav: NavigationTarget {
2858                                     file_id: FileId(
2859                                         0,
2860                                     ),
2861                                     full_range: 0..12,
2862                                     focus_range: 6..9,
2863                                     name: "Foo",
2864                                     kind: Trait,
2865                                     description: "trait Foo",
2866                                 },
2867                             },
2868                         ],
2869                     ),
2870                 ]
2871             "#]],
2872         );
2873     }
2874
2875     #[test]
2876     fn test_hover_dyn_arg_has_goto_type_action() {
2877         check_actions(
2878             r#"
2879 trait Foo {}
2880 fn foo(ar<|>g: &dyn Foo) {}
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..12,
2893                                     focus_range: 6..9,
2894                                     name: "Foo",
2895                                     kind: Trait,
2896                                     description: "trait Foo",
2897                                 },
2898                             },
2899                         ],
2900                     ),
2901                 ]
2902             "#]],
2903         );
2904     }
2905
2906     #[test]
2907     fn test_hover_generic_dyn_arg_has_goto_type_action() {
2908         check_actions(
2909             r#"
2910 trait Foo<T> {}
2911 struct S {}
2912 fn foo(ar<|>g: &dyn Foo<S>) {}
2913 "#,
2914             expect![[r#"
2915                 [
2916                     GoToType(
2917                         [
2918                             HoverGotoTypeData {
2919                                 mod_path: "test::Foo",
2920                                 nav: NavigationTarget {
2921                                     file_id: FileId(
2922                                         0,
2923                                     ),
2924                                     full_range: 0..15,
2925                                     focus_range: 6..9,
2926                                     name: "Foo",
2927                                     kind: Trait,
2928                                     description: "trait Foo",
2929                                 },
2930                             },
2931                             HoverGotoTypeData {
2932                                 mod_path: "test::S",
2933                                 nav: NavigationTarget {
2934                                     file_id: FileId(
2935                                         0,
2936                                     ),
2937                                     full_range: 16..27,
2938                                     focus_range: 23..24,
2939                                     name: "S",
2940                                     kind: Struct,
2941                                     description: "struct S",
2942                                 },
2943                             },
2944                         ],
2945                     ),
2946                 ]
2947             "#]],
2948         );
2949     }
2950
2951     #[test]
2952     fn test_hover_goto_type_action_links_order() {
2953         check_actions(
2954             r#"
2955 trait ImplTrait<T> {}
2956 trait DynTrait<T> {}
2957 struct B<T> {}
2958 struct S {}
2959
2960 fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
2961             "#,
2962             expect![[r#"
2963                 [
2964                     GoToType(
2965                         [
2966                             HoverGotoTypeData {
2967                                 mod_path: "test::ImplTrait",
2968                                 nav: NavigationTarget {
2969                                     file_id: FileId(
2970                                         0,
2971                                     ),
2972                                     full_range: 0..21,
2973                                     focus_range: 6..15,
2974                                     name: "ImplTrait",
2975                                     kind: Trait,
2976                                     description: "trait ImplTrait",
2977                                 },
2978                             },
2979                             HoverGotoTypeData {
2980                                 mod_path: "test::B",
2981                                 nav: NavigationTarget {
2982                                     file_id: FileId(
2983                                         0,
2984                                     ),
2985                                     full_range: 43..57,
2986                                     focus_range: 50..51,
2987                                     name: "B",
2988                                     kind: Struct,
2989                                     description: "struct B",
2990                                 },
2991                             },
2992                             HoverGotoTypeData {
2993                                 mod_path: "test::DynTrait",
2994                                 nav: NavigationTarget {
2995                                     file_id: FileId(
2996                                         0,
2997                                     ),
2998                                     full_range: 22..42,
2999                                     focus_range: 28..36,
3000                                     name: "DynTrait",
3001                                     kind: Trait,
3002                                     description: "trait DynTrait",
3003                                 },
3004                             },
3005                             HoverGotoTypeData {
3006                                 mod_path: "test::S",
3007                                 nav: NavigationTarget {
3008                                     file_id: FileId(
3009                                         0,
3010                                     ),
3011                                     full_range: 58..69,
3012                                     focus_range: 65..66,
3013                                     name: "S",
3014                                     kind: Struct,
3015                                     description: "struct S",
3016                                 },
3017                             },
3018                         ],
3019                     ),
3020                 ]
3021             "#]],
3022         );
3023     }
3024
3025     #[test]
3026     fn test_hover_associated_type_has_goto_type_action() {
3027         check_actions(
3028             r#"
3029 trait Foo {
3030     type Item;
3031     fn get(self) -> Self::Item {}
3032 }
3033
3034 struct Bar{}
3035 struct S{}
3036
3037 impl Foo for S { type Item = Bar; }
3038
3039 fn test() -> impl Foo { S {} }
3040
3041 fn main() { let s<|>t = test().get(); }
3042 "#,
3043             expect![[r#"
3044                 [
3045                     GoToType(
3046                         [
3047                             HoverGotoTypeData {
3048                                 mod_path: "test::Foo",
3049                                 nav: NavigationTarget {
3050                                     file_id: FileId(
3051                                         0,
3052                                     ),
3053                                     full_range: 0..62,
3054                                     focus_range: 6..9,
3055                                     name: "Foo",
3056                                     kind: Trait,
3057                                     description: "trait Foo",
3058                                 },
3059                             },
3060                         ],
3061                     ),
3062                 ]
3063             "#]],
3064         );
3065     }
3066
3067     #[test]
3068     fn hover_displays_normalized_crate_names() {
3069         check(
3070             r#"
3071 //- /lib.rs crate:name-with-dashes
3072 pub mod wrapper {
3073     pub struct Thing { x: u32 }
3074
3075     impl Thing {
3076         pub fn new() -> Thing { Thing { x: 0 } }
3077     }
3078 }
3079
3080 //- /main.rs crate:main deps:name-with-dashes
3081 fn main() { let foo_test = name_with_dashes::wrapper::Thing::new<|>(); }
3082 "#,
3083             expect![[r#"
3084             *new*
3085
3086             ```rust
3087             name_with_dashes::wrapper::Thing
3088             ```
3089
3090             ```rust
3091             pub fn new() -> Thing
3092             ```
3093             "#]],
3094         )
3095     }
3096
3097     #[test]
3098     fn hover_field_pat_shorthand_ref_match_ergonomics() {
3099         check(
3100             r#"
3101 struct S {
3102     f: i32,
3103 }
3104
3105 fn main() {
3106     let s = S { f: 0 };
3107     let S { f<|> } = &s;
3108 }
3109 "#,
3110             expect![[r#"
3111                 *f*
3112
3113                 ```rust
3114                 &i32
3115                 ```
3116             "#]],
3117         );
3118     }
3119
3120     #[test]
3121     fn hover_self_param_shows_type() {
3122         check(
3123             r#"
3124 struct Foo {}
3125 impl Foo {
3126     fn bar(&sel<|>f) {}
3127 }
3128 "#,
3129             expect![[r#"
3130                 *&self*
3131                 ```rust
3132                 &Foo
3133                 ```
3134             "#]],
3135         );
3136     }
3137
3138     #[test]
3139     fn hover_self_param_shows_type_for_arbitrary_self_type() {
3140         check(
3141             r#"
3142 struct Arc<T>(T);
3143 struct Foo {}
3144 impl Foo {
3145     fn bar(sel<|>f: Arc<Foo>) {}
3146 }
3147 "#,
3148             expect![[r#"
3149                 *self: Arc<Foo>*
3150                 ```rust
3151                 Arc<Foo>
3152                 ```
3153             "#]],
3154         );
3155     }
3156
3157     #[test]
3158     fn hover_doc_outer_inner() {
3159         check(
3160             r#"
3161 /// Be quick;
3162 mod Foo<|> {
3163     //! time is mana
3164
3165     /// This comment belongs to the function
3166     fn foo() {}
3167 }
3168 "#,
3169             expect![[r#"
3170                 *Foo*
3171
3172                 ```rust
3173                 test
3174                 ```
3175
3176                 ```rust
3177                 mod Foo
3178                 ```
3179
3180                 ---
3181
3182                 Be quick;
3183                 time is mana
3184             "#]],
3185         );
3186     }
3187
3188     #[test]
3189     fn hover_doc_outer_inner_attribue() {
3190         check(
3191             r#"
3192 #[doc = "Be quick;"]
3193 mod Foo<|> {
3194     #![doc = "time is mana"]
3195
3196     #[doc = "This comment belongs to the function"]
3197     fn foo() {}
3198 }
3199 "#,
3200             expect![[r#"
3201                 *Foo*
3202
3203                 ```rust
3204                 test
3205                 ```
3206
3207                 ```rust
3208                 mod Foo
3209                 ```
3210
3211                 ---
3212
3213                 Be quick;
3214                 time is mana
3215             "#]],
3216         );
3217     }
3218
3219     #[test]
3220     fn hover_comments_dont_highlight_parent() {
3221         check_hover_no_result(
3222             r#"
3223 fn no_hover() {
3224     // no<|>hover
3225 }
3226 "#,
3227         );
3228     }
3229
3230     #[test]
3231     fn hover_label() {
3232         check(
3233             r#"
3234 fn foo() {
3235     'label<|>: loop {}
3236 }
3237 "#,
3238             expect![[r#"
3239             *'label*
3240
3241             ```rust
3242             'label
3243             ```
3244             "#]],
3245         );
3246     }
3247
3248     #[test]
3249     fn hover_lifetime() {
3250         check(
3251             r#"fn foo<'lifetime>(_: &'lifetime<|> ()) {}"#,
3252             expect![[r#"
3253             *'lifetime*
3254
3255             ```rust
3256             'lifetime
3257             ```
3258             "#]],
3259         );
3260     }
3261
3262     #[test]
3263     fn hover_type_param() {
3264         check(
3265             r#"
3266 struct Foo<T>(T);
3267 trait Copy {}
3268 trait Clone {}
3269 trait Sized {}
3270 impl<T: Copy + Clone> Foo<T<|>> where T: Sized {}
3271 "#,
3272             expect![[r#"
3273                 *T*
3274
3275                 ```rust
3276                 T: Copy + Clone + Sized
3277                 ```
3278             "#]],
3279         );
3280         check(
3281             r#"
3282 struct Foo<T>(T);
3283 impl<T> Foo<T<|>> {}
3284 "#,
3285             expect![[r#"
3286                 *T*
3287
3288                 ```rust
3289                 T
3290                 ```
3291                 "#]],
3292         );
3293         // lifetimes aren't being substituted yet
3294         check(
3295             r#"
3296 struct Foo<T>(T);
3297 impl<T: 'static> Foo<T<|>> {}
3298 "#,
3299             expect![[r#"
3300                 *T*
3301
3302                 ```rust
3303                 T: {error}
3304                 ```
3305                 "#]],
3306         );
3307     }
3308 }