aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/hover.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/hover.rs')
-rw-r--r--crates/ide/src/hover.rs182
1 files changed, 116 insertions, 66 deletions
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 6215df6bd..8d45b4875 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -1,7 +1,7 @@
1use either::Either; 1use either::Either;
2use hir::{ 2use hir::{
3 Adt, AsAssocItem, AssocItemContainer, FieldSource, GenericParam, HasAttrs, HasSource, 3 Adt, AsAssocItem, AssocItemContainer, GenericParam, HasAttrs, HasSource, HirDisplay, Module,
4 HirDisplay, Module, ModuleDef, ModuleSource, Semantics, 4 ModuleDef, Semantics,
5}; 5};
6use ide_db::{ 6use ide_db::{
7 base_db::SourceDatabase, 7 base_db::SourceDatabase,
@@ -14,7 +14,7 @@ use stdx::format_to;
14use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset, T}; 14use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset, T};
15 15
16use crate::{ 16use crate::{
17 display::{macro_label, ShortLabel, TryToNav}, 17 display::{macro_label, TryToNav},
18 doc_links::{remove_links, rewrite_links}, 18 doc_links::{remove_links, rewrite_links},
19 markdown_remove::remove_markdown, 19 markdown_remove::remove_markdown,
20 markup::Markup, 20 markup::Markup,
@@ -335,34 +335,18 @@ fn hover_for_definition(
335 let label = macro_label(&it.source(db)?.value); 335 let label = macro_label(&it.source(db)?.value);
336 from_def_source_labeled(db, it, Some(label), mod_path) 336 from_def_source_labeled(db, it, Some(label), mod_path)
337 } 337 }
338 Definition::Field(def) => { 338 Definition::Field(def) => from_hir_fmt(db, def, mod_path),
339 let src = def.source(db)?.value;
340 if let FieldSource::Named(it) = src {
341 from_def_source_labeled(db, def, it.short_label(), mod_path)
342 } else {
343 None
344 }
345 }
346 Definition::ModuleDef(it) => match it { 339 Definition::ModuleDef(it) => match it {
347 ModuleDef::Module(it) => from_def_source_labeled( 340 ModuleDef::Module(it) => from_hir_fmt(db, it, mod_path),
348 db, 341 ModuleDef::Function(it) => from_hir_fmt(db, it, mod_path),
349 it, 342 ModuleDef::Adt(Adt::Struct(it)) => from_hir_fmt(db, it, mod_path),
350 match it.definition_source(db).value { 343 ModuleDef::Adt(Adt::Union(it)) => from_hir_fmt(db, it, mod_path),
351 ModuleSource::Module(it) => it.short_label(), 344 ModuleDef::Adt(Adt::Enum(it)) => from_hir_fmt(db, it, mod_path),
352 ModuleSource::SourceFile(it) => it.short_label(), 345 ModuleDef::Variant(it) => from_hir_fmt(db, it, mod_path),
353 ModuleSource::BlockExpr(it) => it.short_label(), 346 ModuleDef::Const(it) => from_hir_fmt(db, it, mod_path),
354 }, 347 ModuleDef::Static(it) => from_hir_fmt(db, it, mod_path),
355 mod_path, 348 ModuleDef::Trait(it) => from_hir_fmt(db, it, mod_path),
356 ), 349 ModuleDef::TypeAlias(it) => from_hir_fmt(db, it, mod_path),
357 ModuleDef::Function(it) => from_def_source(db, it, mod_path),
358 ModuleDef::Adt(Adt::Struct(it)) => from_def_source(db, it, mod_path),
359 ModuleDef::Adt(Adt::Union(it)) => from_def_source(db, it, mod_path),
360 ModuleDef::Adt(Adt::Enum(it)) => from_def_source(db, it, mod_path),
361 ModuleDef::Variant(it) => from_def_source(db, it, mod_path),
362 ModuleDef::Const(it) => from_def_source(db, it, mod_path),
363 ModuleDef::Static(it) => from_def_source(db, it, mod_path),
364 ModuleDef::Trait(it) => from_def_source(db, it, mod_path),
365 ModuleDef::TypeAlias(it) => from_def_source(db, it, mod_path),
366 ModuleDef::BuiltinType(it) => famous_defs 350 ModuleDef::BuiltinType(it) => famous_defs
367 .and_then(|fd| hover_for_builtin(fd, it)) 351 .and_then(|fd| hover_for_builtin(fd, it))
368 .or_else(|| Some(Markup::fenced_block(&it.name()))), 352 .or_else(|| Some(Markup::fenced_block(&it.name()))),
@@ -370,26 +354,25 @@ fn hover_for_definition(
370 Definition::Local(it) => hover_for_local(it, db), 354 Definition::Local(it) => hover_for_local(it, db),
371 Definition::SelfType(impl_def) => { 355 Definition::SelfType(impl_def) => {
372 impl_def.target_ty(db).as_adt().and_then(|adt| match adt { 356 impl_def.target_ty(db).as_adt().and_then(|adt| match adt {
373 Adt::Struct(it) => from_def_source(db, it, mod_path), 357 Adt::Struct(it) => from_hir_fmt(db, it, mod_path),
374 Adt::Union(it) => from_def_source(db, it, mod_path), 358 Adt::Union(it) => from_hir_fmt(db, it, mod_path),
375 Adt::Enum(it) => from_def_source(db, it, mod_path), 359 Adt::Enum(it) => from_hir_fmt(db, it, mod_path),
376 }) 360 })
377 } 361 }
378 Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))), 362 Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))),
379 Definition::GenericParam(it) => match it { 363 Definition::GenericParam(it) => match it {
380 GenericParam::TypeParam(it) => Some(Markup::fenced_block(&it.display(db))), 364 GenericParam::TypeParam(it) => Some(Markup::fenced_block(&it.display(db))),
381 GenericParam::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))), 365 GenericParam::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))),
382 GenericParam::ConstParam(it) => from_def_source(db, it, None), 366 GenericParam::ConstParam(it) => Some(Markup::fenced_block(&it.display(db))),
383 }, 367 },
384 }; 368 };
385 369
386 fn from_def_source<A, D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<Markup> 370 fn from_hir_fmt<D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<Markup>
387 where 371 where
388 D: HasSource<Ast = A> + HasAttrs + Copy, 372 D: HasAttrs + HirDisplay,
389 A: ShortLabel,
390 { 373 {
391 let short_label = def.source(db)?.value.short_label(); 374 let label = def.display(db).to_string();
392 from_def_source_labeled(db, def, short_label, mod_path) 375 from_def_source_labeled(db, def, Some(label), mod_path)
393 } 376 }
394 377
395 fn from_def_source_labeled<D>( 378 fn from_def_source_labeled<D>(
@@ -670,7 +653,9 @@ fn main() { let foo_test = fo$0o(); }
670 ``` 653 ```
671 654
672 ```rust 655 ```rust
673 pub fn foo<'a, T: AsRef<str>>(b: &'a T) -> &'a str 656 pub fn foo<'a, T>(b: &'a T) -> &'a str
657 where
658 T: AsRef<str>,
674 ``` 659 ```
675 "#]], 660 "#]],
676 ); 661 );
@@ -878,7 +863,7 @@ fn main() { So$0me(12); }
878 ``` 863 ```
879 864
880 ```rust 865 ```rust
881 Some 866 Some(T)
882 ``` 867 ```
883 "#]], 868 "#]],
884 ); 869 );
@@ -944,7 +929,7 @@ fn main() {
944 ``` 929 ```
945 930
946 ```rust 931 ```rust
947 Some 932 Some(T)
948 ``` 933 ```
949 934
950 --- 935 ---
@@ -1441,13 +1426,14 @@ fn bar() { fo$0o(); }
1441 ``` 1426 ```
1442 "#]], 1427 "#]],
1443 ); 1428 );
1429 // Top level `pub(crate)` will be displayed as no visibility.
1444 check( 1430 check(
1445 r#"pub(crate) async unsafe extern "C" fn foo$0() {}"#, 1431 r#"mod m { pub(crate) async unsafe extern "C" fn foo$0() {} }"#,
1446 expect![[r#" 1432 expect![[r#"
1447 *foo* 1433 *foo*
1448 1434
1449 ```rust 1435 ```rust
1450 test 1436 test::m
1451 ``` 1437 ```
1452 1438
1453 ```rust 1439 ```rust
@@ -1489,11 +1475,18 @@ extern crate st$0d;
1489//! abc123 1475//! abc123
1490 "#, 1476 "#,
1491 expect![[r#" 1477 expect![[r#"
1492 *std* 1478 *std*
1493 Standard library for this test 1479
1480 ```rust
1481 extern crate std
1482 ```
1494 1483
1495 Printed? 1484 ---
1496 abc123 1485
1486 Standard library for this test
1487
1488 Printed?
1489 abc123
1497 "#]], 1490 "#]],
1498 ); 1491 );
1499 check( 1492 check(
@@ -1507,11 +1500,18 @@ extern crate std as ab$0c;
1507//! abc123 1500//! abc123
1508 "#, 1501 "#,
1509 expect![[r#" 1502 expect![[r#"
1510 *abc* 1503 *abc*
1511 Standard library for this test 1504
1505 ```rust
1506 extern crate std
1507 ```
1508
1509 ---
1512 1510
1513 Printed? 1511 Standard library for this test
1514 abc123 1512
1513 Printed?
1514 abc123
1515 "#]], 1515 "#]],
1516 ); 1516 );
1517 } 1517 }
@@ -2021,7 +2021,7 @@ enum E {
2021 ``` 2021 ```
2022 2022
2023 ```rust 2023 ```rust
2024 V 2024 V { field: i32 }
2025 ``` 2025 ```
2026 2026
2027 --- 2027 ---
@@ -2417,7 +2417,7 @@ fn main() { let s$0t = S{ f1:Arg(0) }; }
2417 focus_range: 24..25, 2417 focus_range: 24..25,
2418 name: "S", 2418 name: "S",
2419 kind: Struct, 2419 kind: Struct,
2420 description: "struct S", 2420 description: "struct S<T>",
2421 }, 2421 },
2422 }, 2422 },
2423 HoverGotoTypeData { 2423 HoverGotoTypeData {
@@ -2463,7 +2463,7 @@ fn main() { let s$0t = S{ f1: S{ f1: Arg(0) } }; }
2463 focus_range: 24..25, 2463 focus_range: 24..25,
2464 name: "S", 2464 name: "S",
2465 kind: Struct, 2465 kind: Struct,
2466 description: "struct S", 2466 description: "struct S<T>",
2467 }, 2467 },
2468 }, 2468 },
2469 HoverGotoTypeData { 2469 HoverGotoTypeData {
@@ -2605,7 +2605,7 @@ fn main() { let s$0t = foo(); }
2605 focus_range: 6..9, 2605 focus_range: 6..9,
2606 name: "Foo", 2606 name: "Foo",
2607 kind: Trait, 2607 kind: Trait,
2608 description: "trait Foo", 2608 description: "trait Foo<T>",
2609 }, 2609 },
2610 }, 2610 },
2611 HoverGotoTypeData { 2611 HoverGotoTypeData {
@@ -2702,7 +2702,7 @@ fn main() { let s$0t = foo(); }
2702 focus_range: 6..9, 2702 focus_range: 6..9,
2703 name: "Foo", 2703 name: "Foo",
2704 kind: Trait, 2704 kind: Trait,
2705 description: "trait Foo", 2705 description: "trait Foo<T>",
2706 }, 2706 },
2707 }, 2707 },
2708 HoverGotoTypeData { 2708 HoverGotoTypeData {
@@ -2715,7 +2715,7 @@ fn main() { let s$0t = foo(); }
2715 focus_range: 22..25, 2715 focus_range: 22..25,
2716 name: "Bar", 2716 name: "Bar",
2717 kind: Trait, 2717 kind: Trait,
2718 description: "trait Bar", 2718 description: "trait Bar<T>",
2719 }, 2719 },
2720 }, 2720 },
2721 HoverGotoTypeData { 2721 HoverGotoTypeData {
@@ -2819,7 +2819,7 @@ fn foo(ar$0g: &impl Foo + Bar<S>) {}
2819 focus_range: 19..22, 2819 focus_range: 19..22,
2820 name: "Bar", 2820 name: "Bar",
2821 kind: Trait, 2821 kind: Trait,
2822 description: "trait Bar", 2822 description: "trait Bar<T>",
2823 }, 2823 },
2824 }, 2824 },
2825 HoverGotoTypeData { 2825 HoverGotoTypeData {
@@ -2916,7 +2916,7 @@ fn foo(ar$0g: &impl Foo<S>) {}
2916 focus_range: 6..9, 2916 focus_range: 6..9,
2917 name: "Foo", 2917 name: "Foo",
2918 kind: Trait, 2918 kind: Trait,
2919 description: "trait Foo", 2919 description: "trait Foo<T>",
2920 }, 2920 },
2921 }, 2921 },
2922 HoverGotoTypeData { 2922 HoverGotoTypeData {
@@ -2966,7 +2966,7 @@ fn main() { let s$0t = foo(); }
2966 focus_range: 49..50, 2966 focus_range: 49..50,
2967 name: "B", 2967 name: "B",
2968 kind: Struct, 2968 kind: Struct,
2969 description: "struct B", 2969 description: "struct B<T>",
2970 }, 2970 },
2971 }, 2971 },
2972 HoverGotoTypeData { 2972 HoverGotoTypeData {
@@ -3042,7 +3042,7 @@ fn foo(ar$0g: &dyn Foo<S>) {}
3042 focus_range: 6..9, 3042 focus_range: 6..9,
3043 name: "Foo", 3043 name: "Foo",
3044 kind: Trait, 3044 kind: Trait,
3045 description: "trait Foo", 3045 description: "trait Foo<T>",
3046 }, 3046 },
3047 }, 3047 },
3048 HoverGotoTypeData { 3048 HoverGotoTypeData {
@@ -3090,7 +3090,7 @@ fn foo(a$0rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
3090 focus_range: 6..15, 3090 focus_range: 6..15,
3091 name: "ImplTrait", 3091 name: "ImplTrait",
3092 kind: Trait, 3092 kind: Trait,
3093 description: "trait ImplTrait", 3093 description: "trait ImplTrait<T>",
3094 }, 3094 },
3095 }, 3095 },
3096 HoverGotoTypeData { 3096 HoverGotoTypeData {
@@ -3103,7 +3103,7 @@ fn foo(a$0rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
3103 focus_range: 50..51, 3103 focus_range: 50..51,
3104 name: "B", 3104 name: "B",
3105 kind: Struct, 3105 kind: Struct,
3106 description: "struct B", 3106 description: "struct B<T>",
3107 }, 3107 },
3108 }, 3108 },
3109 HoverGotoTypeData { 3109 HoverGotoTypeData {
@@ -3116,7 +3116,7 @@ fn foo(a$0rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
3116 focus_range: 28..36, 3116 focus_range: 28..36,
3117 name: "DynTrait", 3117 name: "DynTrait",
3118 kind: Trait, 3118 kind: Trait,
3119 description: "trait DynTrait", 3119 description: "trait DynTrait<T>",
3120 }, 3120 },
3121 }, 3121 },
3122 HoverGotoTypeData { 3122 HoverGotoTypeData {
@@ -3582,6 +3582,17 @@ mod foo$0;
3582"#, 3582"#,
3583 expect![[r#" 3583 expect![[r#"
3584 *foo* 3584 *foo*
3585
3586 ```rust
3587 test
3588 ```
3589
3590 ```rust
3591 mod foo
3592 ```
3593
3594 ---
3595
3585 For the horde! 3596 For the horde!
3586 "#]], 3597 "#]],
3587 ); 3598 );
@@ -3606,7 +3617,7 @@ use foo::bar::{self$0};
3606 ``` 3617 ```
3607 3618
3608 ```rust 3619 ```rust
3609 pub mod bar 3620 mod bar
3610 ``` 3621 ```
3611 3622
3612 --- 3623 ---
@@ -3657,4 +3668,43 @@ cosnt _: &str$0 = ""; }"#;
3657 "#]], 3668 "#]],
3658 ); 3669 );
3659 } 3670 }
3671
3672 #[test]
3673 fn hover_macro_expanded_function() {
3674 check(
3675 r#"
3676struct S<'a, T>(&'a T);
3677trait Clone {}
3678macro_rules! foo {
3679 () => {
3680 fn bar<'t, T: Clone + 't>(s: &mut S<'t, T>, t: u32) -> *mut u32 where
3681 't: 't + 't,
3682 for<'a> T: Clone + 'a
3683 { 0 as _ }
3684 };
3685}
3686
3687foo!();
3688
3689fn main() {
3690 bar$0;
3691}
3692"#,
3693 expect![[r#"
3694 *bar*
3695
3696 ```rust
3697 test
3698 ```
3699
3700 ```rust
3701 fn bar<'t, T>(s: &mut S<'t, T>, t: u32) -> *mut u32
3702 where
3703 T: Clone + 't,
3704 't: 't + 't,
3705 for<'a> T: Clone + 'a,
3706 ```
3707 "#]],
3708 )
3709 }
3660} 3710}