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