mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Merge pull request #18950 from Veykril/push-okmsynnltxts
Generalize some type walking in hover type actions
This commit is contained in:
commit
2ca2e56d51
@ -5582,6 +5582,7 @@ impl Type {
|
||||
walk_substs(db, type_, &opaque_ty.substitution, cb);
|
||||
}
|
||||
TyKind::Placeholder(_) => {
|
||||
cb(type_.derived(ty.clone()));
|
||||
if let Some(bounds) = ty.impl_trait_bounds(db) {
|
||||
walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
|
||||
}
|
||||
|
@ -989,3 +989,19 @@ impl From<GenericDef> for Definition {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<Definition> for GenericDef {
|
||||
type Error = ();
|
||||
fn try_from(def: Definition) -> Result<Self, Self::Error> {
|
||||
match def {
|
||||
Definition::Function(it) => Ok(it.into()),
|
||||
Definition::Adt(it) => Ok(it.into()),
|
||||
Definition::Trait(it) => Ok(it.into()),
|
||||
Definition::TraitAlias(it) => Ok(it.into()),
|
||||
Definition::TypeAlias(it) => Ok(it.into()),
|
||||
Definition::SelfType(it) => Ok(it.into()),
|
||||
Definition::Const(it) => Ok(it.into()),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,40 +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());
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
it.trait_bounds(db)
|
||||
.into_iter()
|
||||
.filter(|&it| Some(it.into()) != sized_trait)
|
||||
.for_each(|it| push_new_def(it.into()));
|
||||
} else if let Definition::Function(function) = def {
|
||||
walk_and_push_ty(db, &function.ret_type(db), &mut push_new_def);
|
||||
|
||||
let krate = function.module(db).krate();
|
||||
let sized_trait =
|
||||
db.lang_item(krate.into(), LangItem::Sized).and_then(|lang_item| lang_item.as_trait());
|
||||
for param in function.params_without_self(db) {
|
||||
if let Some(type_param) = param.ty().as_type_param(db) {
|
||||
type_param
|
||||
.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) => 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))
|
||||
}
|
||||
} 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),
|
||||
_ => return HoverAction::goto_type_from_targets(db, targets, edition),
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -608,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()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user