@@ -3,10 +3,10 @@ mod render;
3
3
#[ cfg( test) ]
4
4
mod tests;
5
5
6
- use std:: iter;
6
+ use std:: { iter, ops :: Not } ;
7
7
8
8
use either:: Either ;
9
- use hir:: { db:: DefDatabase , DescendPreference , HasSource , LangItem , Semantics } ;
9
+ use hir:: { db:: DefDatabase , DescendPreference , HasCrate , HasSource , LangItem , Semantics } ;
10
10
use ide_db:: {
11
11
base_db:: FileRange ,
12
12
defs:: { Definition , IdentClass , NameRefClass , OperatorClass } ,
@@ -64,7 +64,7 @@ pub enum HoverAction {
64
64
}
65
65
66
66
impl HoverAction {
67
- fn goto_type_from_targets ( db : & RootDatabase , targets : Vec < hir:: ModuleDef > ) -> Self {
67
+ fn goto_type_from_targets ( db : & RootDatabase , targets : Vec < hir:: ModuleDef > ) -> Option < Self > {
68
68
let targets = targets
69
69
. into_iter ( )
70
70
. filter_map ( |it| {
@@ -77,8 +77,8 @@ impl HoverAction {
77
77
nav : it. try_to_nav ( db) ?. call_site ( ) ,
78
78
} )
79
79
} )
80
- . collect ( ) ;
81
- HoverAction :: GoToType ( targets)
80
+ . collect :: < Vec < _ > > ( ) ;
81
+ targets . is_empty ( ) . not ( ) . then_some ( HoverAction :: GoToType ( targets) )
82
82
}
83
83
}
84
84
@@ -315,7 +315,7 @@ fn hover_simple(
315
315
ast:: IntNumber ( num) => {
316
316
res. markup = match num. value( ) {
317
317
Ok ( num) => {
318
- Markup :: fenced_block_text( format_args!( "{num} (0x{num:X}|0x {num:b})" ) )
318
+ Markup :: fenced_block_text( format_args!( "{num} (0x{num:X}|0b {num:b})" ) )
319
319
} ,
320
320
Err ( e) => {
321
321
Markup :: fenced_block_text( format_args!( "{e}" ) )
@@ -365,25 +365,44 @@ fn hover_ranged(
365
365
} )
366
366
}
367
367
368
+ // FIXME: Why is this pub(crate)?
368
369
pub ( crate ) fn hover_for_definition (
369
370
sema : & Semantics < ' _ , RootDatabase > ,
370
371
file_id : FileId ,
371
- definition : Definition ,
372
+ def : Definition ,
372
373
scope_node : & SyntaxNode ,
373
374
config : & HoverConfig ,
374
375
) -> Option < HoverResult > {
375
- let famous_defs = match & definition {
376
+ let famous_defs = match & def {
376
377
Definition :: BuiltinType ( _) => Some ( FamousDefs ( sema, sema. scope ( scope_node) ?. krate ( ) ) ) ,
377
378
_ => None ,
378
379
} ;
379
- render:: definition ( sema. db , definition, famous_defs. as_ref ( ) , config) . map ( |markup| {
380
+
381
+ let db = sema. db ;
382
+ let def_ty = match def {
383
+ Definition :: Local ( it) => Some ( it. ty ( db) ) ,
384
+ Definition :: GenericParam ( hir:: GenericParam :: ConstParam ( it) ) => Some ( it. ty ( db) ) ,
385
+ Definition :: GenericParam ( hir:: GenericParam :: TypeParam ( it) ) => Some ( it. ty ( db) ) ,
386
+ Definition :: Field ( field) => Some ( field. ty ( db) ) ,
387
+ Definition :: TupleField ( it) => Some ( it. ty ( db) ) ,
388
+ Definition :: Function ( it) => Some ( it. ty ( db) ) ,
389
+ Definition :: Adt ( it) => Some ( it. ty ( db) ) ,
390
+ Definition :: Const ( it) => Some ( it. ty ( db) ) ,
391
+ Definition :: Static ( it) => Some ( it. ty ( db) ) ,
392
+ Definition :: TypeAlias ( it) => Some ( it. ty ( db) ) ,
393
+ Definition :: BuiltinType ( it) => Some ( it. ty ( db) ) ,
394
+ _ => None ,
395
+ } ;
396
+ let notable_traits = def_ty. map ( |ty| notable_traits ( db, & ty) ) . unwrap_or_default ( ) ;
397
+
398
+ render:: definition ( sema. db , def, famous_defs. as_ref ( ) , & notable_traits, config) . map ( |markup| {
380
399
HoverResult {
381
- markup : render:: process_markup ( sema. db , definition , & markup, config) ,
400
+ markup : render:: process_markup ( sema. db , def , & markup, config) ,
382
401
actions : [
383
- show_implementations_action ( sema. db , definition ) ,
384
- show_fn_references_action ( sema. db , definition ) ,
385
- runnable_action ( sema, definition , file_id) ,
386
- goto_type_action_for_def ( sema. db , definition ) ,
402
+ show_implementations_action ( sema. db , def ) ,
403
+ show_fn_references_action ( sema. db , def ) ,
404
+ runnable_action ( sema, def , file_id) ,
405
+ goto_type_action_for_def ( sema. db , def , & notable_traits ) ,
387
406
]
388
407
. into_iter ( )
389
408
. flatten ( )
@@ -392,6 +411,32 @@ pub(crate) fn hover_for_definition(
392
411
} )
393
412
}
394
413
414
+ fn notable_traits (
415
+ db : & RootDatabase ,
416
+ ty : & hir:: Type ,
417
+ ) -> Vec < ( hir:: Trait , Vec < ( Option < hir:: Type > , hir:: Name ) > ) > {
418
+ db. notable_traits_in_deps ( ty. krate ( db) . into ( ) )
419
+ . iter ( )
420
+ . flat_map ( |it| & * * it)
421
+ . filter_map ( move |& trait_| {
422
+ let trait_ = trait_. into ( ) ;
423
+ ty. impls_trait ( db, trait_, & [ ] ) . then ( || {
424
+ (
425
+ trait_,
426
+ trait_
427
+ . items ( db)
428
+ . into_iter ( )
429
+ . filter_map ( hir:: AssocItem :: as_type_alias)
430
+ . map ( |alias| {
431
+ ( ty. normalize_trait_assoc_type ( db, & [ ] , alias) , alias. name ( db) )
432
+ } )
433
+ . collect :: < Vec < _ > > ( ) ,
434
+ )
435
+ } )
436
+ } )
437
+ . collect :: < Vec < _ > > ( )
438
+ }
439
+
395
440
fn show_implementations_action ( db : & RootDatabase , def : Definition ) -> Option < HoverAction > {
396
441
fn to_action ( nav_target : NavigationTarget ) -> HoverAction {
397
442
HoverAction :: Implementation ( FilePosition {
@@ -446,14 +491,25 @@ fn runnable_action(
446
491
}
447
492
}
448
493
449
- fn goto_type_action_for_def ( db : & RootDatabase , def : Definition ) -> Option < HoverAction > {
494
+ fn goto_type_action_for_def (
495
+ db : & RootDatabase ,
496
+ def : Definition ,
497
+ notable_traits : & [ ( hir:: Trait , Vec < ( Option < hir:: Type > , hir:: Name ) > ) ] ,
498
+ ) -> Option < HoverAction > {
450
499
let mut targets: Vec < hir:: ModuleDef > = Vec :: new ( ) ;
451
500
let mut push_new_def = |item : hir:: ModuleDef | {
452
501
if !targets. contains ( & item) {
453
502
targets. push ( item) ;
454
503
}
455
504
} ;
456
505
506
+ for & ( trait_, ref assocs) in notable_traits {
507
+ push_new_def ( trait_. into ( ) ) ;
508
+ assocs. iter ( ) . filter_map ( |( ty, _) | ty. as_ref ( ) ) . for_each ( |ty| {
509
+ walk_and_push_ty ( db, ty, & mut push_new_def) ;
510
+ } ) ;
511
+ }
512
+
457
513
if let Definition :: GenericParam ( hir:: GenericParam :: TypeParam ( it) ) = def {
458
514
let krate = it. module ( db) . krate ( ) ;
459
515
let sized_trait =
@@ -469,13 +525,13 @@ fn goto_type_action_for_def(db: &RootDatabase, def: Definition) -> Option<HoverA
469
525
Definition :: GenericParam ( hir:: GenericParam :: ConstParam ( it) ) => it. ty ( db) ,
470
526
Definition :: Field ( field) => field. ty ( db) ,
471
527
Definition :: Function ( function) => function. ret_type ( db) ,
472
- _ => return None ,
528
+ _ => return HoverAction :: goto_type_from_targets ( db , targets ) ,
473
529
} ;
474
530
475
531
walk_and_push_ty ( db, & ty, & mut push_new_def) ;
476
532
}
477
533
478
- Some ( HoverAction :: goto_type_from_targets ( db, targets) )
534
+ HoverAction :: goto_type_from_targets ( db, targets)
479
535
}
480
536
481
537
fn walk_and_push_ty (
@@ -530,7 +586,9 @@ fn dedupe_or_merge_hover_actions(actions: Vec<HoverAction>) -> Vec<HoverAction>
530
586
}
531
587
532
588
if !go_to_type_targets. is_empty ( ) {
533
- deduped_actions. push ( HoverAction :: GoToType ( go_to_type_targets. into_iter ( ) . collect ( ) ) ) ;
589
+ deduped_actions. push ( HoverAction :: GoToType (
590
+ go_to_type_targets. into_iter ( ) . sorted_by ( |a, b| a. mod_path . cmp ( & b. mod_path ) ) . collect ( ) ,
591
+ ) ) ;
534
592
}
535
593
536
594
deduped_actions
0 commit comments