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