Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/hir/generics.rs')
-rw-r--r--crates/hir-def/src/hir/generics.rs52
1 files changed, 51 insertions, 1 deletions
diff --git a/crates/hir-def/src/hir/generics.rs b/crates/hir-def/src/hir/generics.rs
index 36ae821d74..b6e9fc2820 100644
--- a/crates/hir-def/src/hir/generics.rs
+++ b/crates/hir-def/src/hir/generics.rs
@@ -33,6 +33,19 @@ pub struct TypeParamData {
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct LifetimeParamData {
pub name: Name,
+ pub bound_type: LifetimeBoundType,
+}
+
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub enum LifetimeBoundType {
+ EarlyBound,
+ LateBound,
+}
+
+impl LifetimeParamData {
+ pub fn is_late_bound(&self) -> bool {
+ self.bound_type == LifetimeBoundType::LateBound
+ }
}
/// Data about a generic const parameter (to a function, struct, impl, ...).
@@ -293,7 +306,12 @@ impl GenericParams {
#[inline]
pub fn len_lifetimes(&self) -> usize {
- self.lifetimes.len()
+ self.lifetimes.len() - self.len_late_bound_lifetimes()
+ }
+
+ #[inline]
+ pub fn len_late_bound_lifetimes(&self) -> usize {
+ self.lifetimes.iter().filter(|(_, p)| p.bound_type == LifetimeBoundType::LateBound).count()
}
#[inline]
@@ -332,6 +350,20 @@ impl GenericParams {
self.lifetimes.iter()
}
+ #[inline]
+ pub fn iter_early_bound_lt(
+ &self,
+ ) -> impl DoubleEndedIterator<Item = (LocalLifetimeParamId, &LifetimeParamData)> {
+ self.lifetimes.iter().filter(|(_, p)| p.bound_type == LifetimeBoundType::EarlyBound)
+ }
+
+ #[inline]
+ pub fn iter_late_bound_lt(
+ &self,
+ ) -> impl DoubleEndedIterator<Item = (LocalLifetimeParamId, &LifetimeParamData)> {
+ self.lifetimes.iter().filter(|(_, p)| p.bound_type == LifetimeBoundType::LateBound)
+ }
+
pub fn find_type_by_name(&self, name: &Name, parent: GenericDefId) -> Option<TypeParamId> {
self.type_or_consts.iter().find_map(|(id, p)| {
if p.name().as_ref() == Some(&name) && p.type_param().is_some() {
@@ -376,4 +408,22 @@ impl GenericParams {
if &p.name == name { Some(LifetimeParamId { local_id: id, parent }) } else { None }
})
}
+
+ pub fn lifetime_param_idx(
+ &self,
+ lifetime_param_id: &LocalLifetimeParamId,
+ ) -> Option<(usize, bool)> {
+ let mut late_bound_idx = 0;
+ self.iter_lt().enumerate().find_map(|(idx, (param_id, param_data))| {
+ let idx = if param_data.is_late_bound() {
+ let prev = late_bound_idx;
+ late_bound_idx += 1;
+ prev
+ } else {
+ idx - late_bound_idx
+ };
+
+ (param_id == *lifetime_param_id).then(|| (idx, param_data.is_late_bound()))
+ })
+ }
}