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