}
}
+ pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> {
+ db.generic_predicates_for_param(self.id)
+ .into_iter()
+ .filter_map(|pred| match &pred.value {
+ hir_ty::GenericPredicate::Implemented(trait_ref) => {
+ Some(Trait::from(trait_ref.trait_))
+ }
+ _ => None,
+ })
+ .collect()
+ }
+
pub fn default(self, db: &dyn HirDatabase) -> Option<Type> {
let params = db.generic_defaults(self.id.parent);
let local_idx = hir_ty::param_idx(db, self.id)?;
}
fn goto_type_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> {
- let ty = match def {
- Definition::Local(it) => it.ty(db),
- Definition::ConstParam(it) => it.ty(db),
- _ => return None,
- };
let mut targets: Vec<ModuleDef> = Vec::new();
let mut push_new_def = |item: ModuleDef| {
if !targets.contains(&item) {
}
};
- ty.walk(db, |t| {
- if let Some(adt) = t.as_adt() {
- push_new_def(adt.into());
- } else if let Some(trait_) = t.as_dyn_trait() {
- push_new_def(trait_.into());
- } else if let Some(traits) = t.as_impl_traits(db) {
- traits.into_iter().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());
- }
- });
+ if let Definition::TypeParam(it) = def {
+ it.trait_bounds(db).into_iter().for_each(|it| push_new_def(it.into()));
+ } else {
+ let ty = match def {
+ Definition::Local(it) => it.ty(db),
+ Definition::ConstParam(it) => it.ty(db),
+ _ => return None,
+ };
+
+ ty.walk(db, |t| {
+ if let Some(adt) = t.as_adt() {
+ push_new_def(adt.into());
+ } else if let Some(trait_) = t.as_dyn_trait() {
+ push_new_def(trait_.into());
+ } else if let Some(traits) = t.as_impl_traits(db) {
+ traits.into_iter().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());
+ }
+ });
+ }
let targets = targets
.into_iter()
struct Bar;
struct Foo<const BAR: Bar>;
-impl<const BAR: Bar> Foo<BAR<|>> {}
+impl<const BAR: Bar> Foo<BAR<|>> {}
"#,
expect![[r#"
[
);
}
+ #[test]
+ fn test_hover_type_param_has_goto_type_action() {
+ check_actions(
+ r#"
+trait Foo {}
+
+fn foo<T: Foo>(t: T<|>){}
+"#,
+ expect![[r#"
+ [
+ GoToType(
+ [
+ HoverGotoTypeData {
+ mod_path: "test::Foo",
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 0..12,
+ focus_range: 6..9,
+ name: "Foo",
+ kind: Trait,
+ description: "trait Foo",
+ },
+ },
+ ],
+ ),
+ ]
+ "#]],
+ );
+ }
+
#[test]
fn hover_displays_normalized_crate_names() {
check(