Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/generics.rs')
-rw-r--r--crates/hir-def/src/generics.rs80
1 files changed, 78 insertions, 2 deletions
diff --git a/crates/hir-def/src/generics.rs b/crates/hir-def/src/generics.rs
index 1d2c7c3a55..4638b37719 100644
--- a/crates/hir-def/src/generics.rs
+++ b/crates/hir-def/src/generics.rs
@@ -22,8 +22,8 @@ use crate::{
lower::LowerCtx,
nameres::{DefMap, MacroSubNs},
type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRef},
- AdtId, ConstParamId, GenericDefId, HasModule, ItemTreeLoc, LocalTypeOrConstParamId, Lookup,
- TypeOrConstParamId, TypeParamId,
+ AdtId, ConstParamId, GenericDefId, HasModule, ItemTreeLoc, LifetimeParamId,
+ LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId,
};
/// Data about a generic type parameter (to a function, struct, impl, ...).
@@ -102,6 +102,52 @@ impl TypeOrConstParamData {
impl_from!(TypeParamData, ConstParamData for TypeOrConstParamData);
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub enum GenericParamData {
+ TypeParamData(TypeParamData),
+ ConstParamData(ConstParamData),
+ LifetimeParamData(LifetimeParamData),
+}
+
+impl GenericParamData {
+ pub fn name(&self) -> Option<&Name> {
+ match self {
+ GenericParamData::TypeParamData(it) => it.name.as_ref(),
+ GenericParamData::ConstParamData(it) => Some(&it.name),
+ GenericParamData::LifetimeParamData(it) => Some(&it.name),
+ }
+ }
+
+ pub fn type_param(&self) -> Option<&TypeParamData> {
+ match self {
+ GenericParamData::TypeParamData(it) => Some(it),
+ _ => None,
+ }
+ }
+
+ pub fn const_param(&self) -> Option<&ConstParamData> {
+ match self {
+ GenericParamData::ConstParamData(it) => Some(it),
+ _ => None,
+ }
+ }
+
+ pub fn lifetime_param(&self) -> Option<&LifetimeParamData> {
+ match self {
+ GenericParamData::LifetimeParamData(it) => Some(it),
+ _ => None,
+ }
+ }
+}
+
+impl_from!(TypeParamData, ConstParamData, LifetimeParamData for GenericParamData);
+
+pub enum GenericParamDataRef<'a> {
+ TypeParamData(&'a TypeParamData),
+ ConstParamData(&'a ConstParamData),
+ LifetimeParamData(&'a LifetimeParamData),
+}
+
/// Data about the generic parameters of a function, struct, impl, etc.
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct GenericParams {
@@ -358,6 +404,15 @@ impl GenericParamsCollector {
}
impl GenericParams {
+ /// Number of Generic parameters (type_or_consts + lifetimes)
+ pub fn len(&self) -> usize {
+ self.type_or_consts.len() + self.lifetimes.len()
+ }
+
+ pub fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+
/// Iterator of type_or_consts field
pub fn iter(
&self,
@@ -365,6 +420,13 @@ impl GenericParams {
self.type_or_consts.iter()
}
+ /// Iterator of lifetimes field
+ pub fn iter_lt(
+ &self,
+ ) -> impl DoubleEndedIterator<Item = (Idx<LifetimeParamData>, &LifetimeParamData)> {
+ self.lifetimes.iter()
+ }
+
pub(crate) fn generic_params_query(
db: &dyn DefDatabase,
def: GenericDefId,
@@ -507,4 +569,18 @@ impl GenericParams {
.then(|| id)
})
}
+
+ pub fn find_lifetime_by_name(
+ &self,
+ name: &Name,
+ parent: GenericDefId,
+ ) -> Option<LifetimeParamId> {
+ self.lifetimes.iter().find_map(|(id, p)| {
+ if &p.name == name {
+ Some(LifetimeParamId { local_id: id, parent })
+ } else {
+ None
+ }
+ })
+ }
}