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