Skip to content

Commit 4d5632b

Browse files
committed
Generalize some type walking in hover type actions
1 parent 8ec9094 commit 4d5632b

File tree

3 files changed

+47
-31
lines changed

3 files changed

+47
-31
lines changed

src/tools/rust-analyzer/crates/hir/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5582,6 +5582,7 @@ impl Type {
55825582
walk_substs(db, type_, &opaque_ty.substitution, cb);
55835583
}
55845584
TyKind::Placeholder(_) => {
5585+
cb(type_.derived(ty.clone()));
55855586
if let Some(bounds) = ty.impl_trait_bounds(db) {
55865587
walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
55875588
}

src/tools/rust-analyzer/crates/ide-db/src/defs.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -989,3 +989,19 @@ impl From<GenericDef> for Definition {
989989
}
990990
}
991991
}
992+
993+
impl TryFrom<Definition> for GenericDef {
994+
type Error = ();
995+
fn try_from(def: Definition) -> Result<Self, Self::Error> {
996+
match def {
997+
Definition::Function(it) => Ok(it.into()),
998+
Definition::Adt(it) => Ok(it.into()),
999+
Definition::Trait(it) => Ok(it.into()),
1000+
Definition::TraitAlias(it) => Ok(it.into()),
1001+
Definition::TypeAlias(it) => Ok(it.into()),
1002+
Definition::SelfType(it) => Ok(it.into()),
1003+
Definition::Const(it) => Ok(it.into()),
1004+
_ => Err(()),
1005+
}
1006+
}
1007+
}

src/tools/rust-analyzer/crates/ide/src/hover.rs

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ mod tests;
66
use std::{iter, ops::Not};
77

88
use either::Either;
9-
use hir::{db::DefDatabase, GenericSubstitution, HasCrate, HasSource, LangItem, Semantics};
9+
use hir::{
10+
db::DefDatabase, GenericDef, GenericSubstitution, HasCrate, HasSource, LangItem, Semantics,
11+
};
1012
use ide_db::{
1113
defs::{Definition, IdentClass, NameRefClass, OperatorClass},
1214
famous_defs::FamousDefs,
@@ -548,40 +550,29 @@ fn goto_type_action_for_def(
548550
});
549551
}
550552

551-
if let Definition::GenericParam(hir::GenericParam::TypeParam(it)) = def {
552-
let krate = it.module(db).krate();
553-
let sized_trait =
554-
db.lang_item(krate.into(), LangItem::Sized).and_then(|lang_item| lang_item.as_trait());
553+
if let Ok(generic_def) = GenericDef::try_from(def) {
554+
generic_def.type_or_const_params(db).into_iter().for_each(|it| {
555+
walk_and_push_ty(db, &it.ty(db), &mut push_new_def);
556+
});
557+
}
555558

556-
it.trait_bounds(db)
557-
.into_iter()
558-
.filter(|&it| Some(it.into()) != sized_trait)
559-
.for_each(|it| push_new_def(it.into()));
560-
} else if let Definition::Function(function) = def {
561-
walk_and_push_ty(db, &function.ret_type(db), &mut push_new_def);
562-
563-
let krate = function.module(db).krate();
564-
let sized_trait =
565-
db.lang_item(krate.into(), LangItem::Sized).and_then(|lang_item| lang_item.as_trait());
566-
for param in function.params_without_self(db) {
567-
if let Some(type_param) = param.ty().as_type_param(db) {
568-
type_param
569-
.trait_bounds(db)
570-
.into_iter()
571-
.filter(|&it| Some(it.into()) != sized_trait)
572-
.for_each(|it| push_new_def(it.into()));
573-
} else {
559+
let ty = match def {
560+
Definition::Local(it) => Some(it.ty(db)),
561+
Definition::Field(field) => Some(field.ty(db)),
562+
Definition::TupleField(field) => Some(field.ty(db)),
563+
Definition::Const(it) => Some(it.ty(db)),
564+
Definition::Static(it) => Some(it.ty(db)),
565+
Definition::Function(func) => {
566+
for param in func.assoc_fn_params(db) {
574567
walk_and_push_ty(db, param.ty(), &mut push_new_def);
575568
}
569+
Some(func.ret_type(db))
576570
}
577-
} else {
578-
let ty = match def {
579-
Definition::Local(it) => it.ty(db),
580-
Definition::GenericParam(hir::GenericParam::ConstParam(it)) => it.ty(db),
581-
Definition::Field(field) => field.ty(db),
582-
_ => return HoverAction::goto_type_from_targets(db, targets, edition),
583-
};
584-
571+
Definition::GenericParam(hir::GenericParam::ConstParam(it)) => Some(it.ty(db)),
572+
Definition::GenericParam(hir::GenericParam::TypeParam(it)) => Some(it.ty(db)),
573+
_ => None,
574+
};
575+
if let Some(ty) = ty {
585576
walk_and_push_ty(db, &ty, &mut push_new_def);
586577
}
587578

@@ -608,6 +599,14 @@ fn walk_and_push_ty(
608599
traits.for_each(|it| push_new_def(it.into()));
609600
} else if let Some(trait_) = t.as_associated_type_parent_trait(db) {
610601
push_new_def(trait_.into());
602+
} else if let Some(tp) = t.as_type_param(db) {
603+
let sized_trait = db
604+
.lang_item(t.krate(db).into(), LangItem::Sized)
605+
.and_then(|lang_item| lang_item.as_trait());
606+
tp.trait_bounds(db)
607+
.into_iter()
608+
.filter(|&it| Some(it.into()) != sized_trait)
609+
.for_each(|it| push_new_def(it.into()));
611610
}
612611
});
613612
}

0 commit comments

Comments
 (0)