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