mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-11 16:34:12 +00:00
Merge pull request #18707 from ChayimFriedman2/subst
feat: Show substitution where hovering over generic things
This commit is contained in:
commit
e30ce42671
29 changed files with 1019 additions and 190 deletions
|
|
@ -3574,6 +3574,61 @@ impl GenericDef {
|
|||
}
|
||||
}
|
||||
|
||||
// We cannot call this `Substitution` unfortunately...
|
||||
#[derive(Debug)]
|
||||
pub struct GenericSubstitution {
|
||||
def: GenericDefId,
|
||||
subst: Substitution,
|
||||
env: Arc<TraitEnvironment>,
|
||||
}
|
||||
|
||||
impl GenericSubstitution {
|
||||
fn new(def: GenericDefId, subst: Substitution, env: Arc<TraitEnvironment>) -> Self {
|
||||
Self { def, subst, env }
|
||||
}
|
||||
|
||||
pub fn types(&self, db: &dyn HirDatabase) -> Vec<(Symbol, Type)> {
|
||||
let container = match self.def {
|
||||
GenericDefId::ConstId(id) => Some(id.lookup(db.upcast()).container),
|
||||
GenericDefId::FunctionId(id) => Some(id.lookup(db.upcast()).container),
|
||||
GenericDefId::TypeAliasId(id) => Some(id.lookup(db.upcast()).container),
|
||||
_ => None,
|
||||
};
|
||||
let container_type_params = container
|
||||
.and_then(|container| match container {
|
||||
ItemContainerId::ImplId(container) => Some(container.into()),
|
||||
ItemContainerId::TraitId(container) => Some(container.into()),
|
||||
_ => None,
|
||||
})
|
||||
.map(|container| {
|
||||
db.generic_params(container)
|
||||
.iter_type_or_consts()
|
||||
.filter_map(|param| match param.1 {
|
||||
TypeOrConstParamData::TypeParamData(param) => Some(param.name.clone()),
|
||||
TypeOrConstParamData::ConstParamData(_) => None,
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
let generics = db.generic_params(self.def);
|
||||
let type_params = generics.iter_type_or_consts().filter_map(|param| match param.1 {
|
||||
TypeOrConstParamData::TypeParamData(param) => Some(param.name.clone()),
|
||||
TypeOrConstParamData::ConstParamData(_) => None,
|
||||
});
|
||||
// The `Substitution` is first self then container, we want the reverse order.
|
||||
let self_params = self.subst.type_parameters(Interner).zip(type_params);
|
||||
let container_params = self.subst.as_slice(Interner)[generics.len()..]
|
||||
.iter()
|
||||
.filter_map(|param| param.ty(Interner).cloned())
|
||||
.zip(container_type_params.into_iter().flatten());
|
||||
container_params
|
||||
.chain(self_params)
|
||||
.filter_map(|(ty, name)| {
|
||||
Some((name?.symbol().clone(), Type { ty, env: self.env.clone() }))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
/// A single local definition.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct Local {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue