Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/hover.rs')
| -rw-r--r-- | crates/ide/src/hover.rs | 51 |
1 files changed, 33 insertions, 18 deletions
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 1431bd8ca2..18a3fed07e 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -6,7 +6,9 @@ mod tests; use std::{iter, ops::Not}; use either::Either; -use hir::{db::DefDatabase, GenericSubstitution, HasCrate, HasSource, LangItem, Semantics}; +use hir::{ + db::DefDatabase, GenericDef, GenericSubstitution, HasCrate, HasSource, LangItem, Semantics, +}; use ide_db::{ defs::{Definition, IdentClass, NameRefClass, OperatorClass}, famous_defs::FamousDefs, @@ -548,24 +550,29 @@ fn goto_type_action_for_def( }); } - if let Definition::GenericParam(hir::GenericParam::TypeParam(it)) = def { - let krate = it.module(db).krate(); - let sized_trait = - db.lang_item(krate.into(), LangItem::Sized).and_then(|lang_item| lang_item.as_trait()); - - it.trait_bounds(db) - .into_iter() - .filter(|&it| Some(it.into()) != sized_trait) - .for_each(|it| push_new_def(it.into())); - } else { - let ty = match def { - Definition::Local(it) => it.ty(db), - Definition::GenericParam(hir::GenericParam::ConstParam(it)) => it.ty(db), - Definition::Field(field) => field.ty(db), - Definition::Function(function) => function.ret_type(db), - _ => return HoverAction::goto_type_from_targets(db, targets, edition), - }; + if let Ok(generic_def) = GenericDef::try_from(def) { + generic_def.type_or_const_params(db).into_iter().for_each(|it| { + walk_and_push_ty(db, &it.ty(db), &mut push_new_def); + }); + } + let ty = match def { + Definition::Local(it) => Some(it.ty(db)), + Definition::Field(field) => Some(field.ty(db)), + Definition::TupleField(field) => Some(field.ty(db)), + Definition::Const(it) => Some(it.ty(db)), + Definition::Static(it) => Some(it.ty(db)), + Definition::Function(func) => { + for param in func.assoc_fn_params(db) { + walk_and_push_ty(db, param.ty(), &mut push_new_def); + } + Some(func.ret_type(db)) + } + Definition::GenericParam(hir::GenericParam::ConstParam(it)) => Some(it.ty(db)), + Definition::GenericParam(hir::GenericParam::TypeParam(it)) => Some(it.ty(db)), + _ => None, + }; + if let Some(ty) = ty { walk_and_push_ty(db, &ty, &mut push_new_def); } @@ -592,6 +599,14 @@ fn walk_and_push_ty( traits.for_each(|it| push_new_def(it.into())); } else if let Some(trait_) = t.as_associated_type_parent_trait(db) { push_new_def(trait_.into()); + } else if let Some(tp) = t.as_type_param(db) { + let sized_trait = db + .lang_item(t.krate(db).into(), LangItem::Sized) + .and_then(|lang_item| lang_item.as_trait()); + tp.trait_bounds(db) + .into_iter() + .filter(|&it| Some(it.into()) != sized_trait) + .for_each(|it| push_new_def(it.into())); } }); } |