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