@@ -3,10 +3,10 @@ mod render;
33#[ cfg( test) ]
44mod tests;
55
6- use std:: iter;
6+ use std:: { iter, ops :: Not } ;
77
88use either:: Either ;
9- use hir:: { db:: DefDatabase , DescendPreference , HasSource , LangItem , Semantics } ;
9+ use hir:: { db:: DefDatabase , DescendPreference , HasCrate , HasSource , LangItem , Semantics } ;
1010use ide_db:: {
1111 base_db:: FileRange ,
1212 defs:: { Definition , IdentClass , NameRefClass , OperatorClass } ,
@@ -64,7 +64,7 @@ pub enum HoverAction {
6464}
6565
6666impl 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 > {
6868 let targets = targets
6969 . into_iter ( )
7070 . filter_map ( |it| {
@@ -77,8 +77,8 @@ impl HoverAction {
7777 nav : it. try_to_nav ( db) ?. call_site ( ) ,
7878 } )
7979 } )
80- . collect ( ) ;
81- HoverAction :: GoToType ( targets)
80+ . collect :: < Vec < _ > > ( ) ;
81+ targets . is_empty ( ) . not ( ) . then_some ( HoverAction :: GoToType ( targets) )
8282 }
8383}
8484
@@ -315,7 +315,7 @@ fn hover_simple(
315315 ast:: IntNumber ( num) => {
316316 res. markup = match num. value( ) {
317317 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})" ) )
319319 } ,
320320 Err ( e) => {
321321 Markup :: fenced_block_text( format_args!( "{e}" ) )
@@ -365,25 +365,67 @@ fn hover_ranged(
365365 } )
366366}
367367
368+ // FIXME: Why is this pub(crate)?
368369pub ( crate ) fn hover_for_definition (
369370 sema : & Semantics < ' _ , RootDatabase > ,
370371 file_id : FileId ,
371- definition : Definition ,
372+ def : Definition ,
372373 scope_node : & SyntaxNode ,
373374 config : & HoverConfig ,
374375) -> Option < HoverResult > {
375- let famous_defs = match & definition {
376+ let famous_defs = match & def {
376377 Definition :: BuiltinType ( _) => Some ( FamousDefs ( sema, sema. scope ( scope_node) ?. krate ( ) ) ) ,
377378 _ => None ,
378379 } ;
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
397+ . map ( |ty| {
398+ db. notable_traits_in_deps ( ty. krate ( db) . into ( ) )
399+ . iter ( )
400+ . flat_map ( |it| & * * it)
401+ . filter_map ( move |& trait_| {
402+ let trait_ = trait_. into ( ) ;
403+ ty. impls_trait ( db, trait_, & [ ] ) . then ( || {
404+ (
405+ trait_,
406+ trait_
407+ . items ( db)
408+ . into_iter ( )
409+ . filter_map ( hir:: AssocItem :: as_type_alias)
410+ . map ( |alias| {
411+ ( ty. normalize_trait_assoc_type ( db, & [ ] , alias) , alias. name ( db) )
412+ } )
413+ . collect :: < Vec < _ > > ( ) ,
414+ )
415+ } )
416+ } )
417+ . collect :: < Vec < _ > > ( )
418+ } )
419+ . unwrap_or_default ( ) ;
420+
421+ render:: definition ( sema. db , def, famous_defs. as_ref ( ) , & notable_traits, config) . map ( |markup| {
380422 HoverResult {
381- markup : render:: process_markup ( sema. db , definition , & markup, config) ,
423+ markup : render:: process_markup ( sema. db , def , & markup, config) ,
382424 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 ) ,
425+ show_implementations_action ( sema. db , def ) ,
426+ show_fn_references_action ( sema. db , def ) ,
427+ runnable_action ( sema, def , file_id) ,
428+ goto_type_action_for_def ( sema. db , def , & notable_traits ) ,
387429 ]
388430 . into_iter ( )
389431 . flatten ( )
@@ -446,14 +488,25 @@ fn runnable_action(
446488 }
447489}
448490
449- fn goto_type_action_for_def ( db : & RootDatabase , def : Definition ) -> Option < HoverAction > {
491+ fn goto_type_action_for_def (
492+ db : & RootDatabase ,
493+ def : Definition ,
494+ notable_traits : & [ ( hir:: Trait , Vec < ( Option < hir:: Type > , hir:: Name ) > ) ] ,
495+ ) -> Option < HoverAction > {
450496 let mut targets: Vec < hir:: ModuleDef > = Vec :: new ( ) ;
451497 let mut push_new_def = |item : hir:: ModuleDef | {
452498 if !targets. contains ( & item) {
453499 targets. push ( item) ;
454500 }
455501 } ;
456502
503+ for & ( trait_, ref assocs) in notable_traits {
504+ push_new_def ( trait_. into ( ) ) ;
505+ assocs. iter ( ) . filter_map ( |( ty, _) | ty. as_ref ( ) ) . for_each ( |ty| {
506+ walk_and_push_ty ( db, ty, & mut push_new_def) ;
507+ } ) ;
508+ }
509+
457510 if let Definition :: GenericParam ( hir:: GenericParam :: TypeParam ( it) ) = def {
458511 let krate = it. module ( db) . krate ( ) ;
459512 let sized_trait =
@@ -469,13 +522,13 @@ fn goto_type_action_for_def(db: &RootDatabase, def: Definition) -> Option<HoverA
469522 Definition :: GenericParam ( hir:: GenericParam :: ConstParam ( it) ) => it. ty ( db) ,
470523 Definition :: Field ( field) => field. ty ( db) ,
471524 Definition :: Function ( function) => function. ret_type ( db) ,
472- _ => return None ,
525+ _ => return HoverAction :: goto_type_from_targets ( db , targets ) ,
473526 } ;
474527
475528 walk_and_push_ty ( db, & ty, & mut push_new_def) ;
476529 }
477530
478- Some ( HoverAction :: goto_type_from_targets ( db, targets) )
531+ HoverAction :: goto_type_from_targets ( db, targets)
479532}
480533
481534fn walk_and_push_ty (
0 commit comments