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