mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 21:43:37 +00:00
Show GotoTypeAction for TypeParam
This commit is contained in:
parent
bd47e140b6
commit
54b9b03ca2
2 changed files with 66 additions and 17 deletions
|
@ -1276,6 +1276,18 @@ impl TypeParam {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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> {
|
pub fn default(self, db: &dyn HirDatabase) -> Option<Type> {
|
||||||
let params = db.generic_defaults(self.id.parent);
|
let params = db.generic_defaults(self.id.parent);
|
||||||
let local_idx = hir_ty::param_idx(db, self.id)?;
|
let local_idx = hir_ty::param_idx(db, self.id)?;
|
||||||
|
|
|
@ -228,11 +228,6 @@ fn runnable_action(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn goto_type_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> {
|
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 targets: Vec<ModuleDef> = Vec::new();
|
||||||
let mut push_new_def = |item: ModuleDef| {
|
let mut push_new_def = |item: ModuleDef| {
|
||||||
if !targets.contains(&item) {
|
if !targets.contains(&item) {
|
||||||
|
@ -240,6 +235,15 @@ fn goto_type_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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| {
|
ty.walk(db, |t| {
|
||||||
if let Some(adt) = t.as_adt() {
|
if let Some(adt) = t.as_adt() {
|
||||||
push_new_def(adt.into());
|
push_new_def(adt.into());
|
||||||
|
@ -251,6 +255,7 @@ fn goto_type_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> {
|
||||||
push_new_def(trait_.into());
|
push_new_def(trait_.into());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let targets = targets
|
let targets = targets
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -3112,6 +3117,38 @@ impl<const BAR: Bar> Foo<BAR<|>> {}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[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]
|
#[test]
|
||||||
fn hover_displays_normalized_crate_names() {
|
fn hover_displays_normalized_crate_names() {
|
||||||
check(
|
check(
|
||||||
|
|
Loading…
Reference in a new issue