Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/utils.rs')
| -rw-r--r-- | crates/hir-ty/src/utils.rs | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs index 8bd57820d2..84fcc31dd4 100644 --- a/crates/hir-ty/src/utils.rs +++ b/crates/hir-ty/src/utils.rs @@ -13,14 +13,15 @@ use either::Either; use hir_def::{ db::DefDatabase, generics::{ - GenericParams, TypeOrConstParamData, TypeParamProvenance, WherePredicate, - WherePredicateTypeTarget, + GenericParams, LifetimeParamData, TypeOrConstParamData, TypeParamProvenance, + WherePredicate, WherePredicateTypeTarget, }, lang_item::LangItem, resolver::{HasResolver, TypeNs}, type_ref::{TraitBoundModifier, TypeRef}, - ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId, ItemContainerId, Lookup, - OpaqueInternableThing, TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, + ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId, ItemContainerId, + LifetimeParamId, Lookup, OpaqueInternableThing, TraitId, TypeAliasId, TypeOrConstParamId, + TypeParamId, }; use hir_expand::name::Name; use intern::Interned; @@ -322,6 +323,11 @@ impl Generics { self.params.type_or_consts.len() } + /// Returns number of generic lifetime excluding those from parent. + pub(crate) fn len_lt_self(&self) -> usize { + self.params.lifetimes.len() + } + /// (parent total, self param, type param list, const param list, impl trait) pub(crate) fn provenance_split(&self) -> (usize, usize, usize, usize, usize) { let mut self_params = 0; @@ -358,6 +364,26 @@ impl Generics { } } + pub(crate) fn lifetime_idx(&self, lifetime: LifetimeParamId) -> Option<usize> { + Some(self.find_lifetime(lifetime)?.0) + } + + fn find_lifetime(&self, lifetime: LifetimeParamId) -> Option<(usize, &LifetimeParamData)> { + if lifetime.parent == self.def { + let (idx, (_local_id, data)) = self + .params + .iter_lt() + .enumerate() + .find(|(_, (idx, _))| *idx == lifetime.local_id)?; + + Some((idx, data)) + } else { + self.parent_generics() + .and_then(|g| g.find_lifetime(lifetime)) + .map(|(idx, data)| (self.len_lt_self() + idx, data)) + } + } + pub(crate) fn parent_generics(&self) -> Option<&Generics> { self.parent_generics.as_deref() } |