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.rs73
1 files changed, 47 insertions, 26 deletions
diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs
index afd4d1f271..42c7a84032 100644
--- a/crates/hir-ty/src/utils.rs
+++ b/crates/hir-ty/src/utils.rs
@@ -262,7 +262,7 @@ impl<'a> ClosureSubst<'a> {
}
}
-#[derive(Debug)]
+#[derive(Clone, Debug)]
pub(crate) struct Generics {
def: GenericDefId,
pub(crate) params: Interned<GenericParams>,
@@ -274,6 +274,10 @@ impl Generics {
self.iter().map(|(id, _)| id)
}
+ pub(crate) fn def(&self) -> GenericDefId {
+ self.def
+ }
+
/// Iterator over types and const params of self, then parent.
pub(crate) fn iter<'a>(
&'a self,
@@ -304,7 +308,11 @@ impl Generics {
};
let lt_iter = self.params.iter_lt().map(from_lt_id(self));
- self.params.iter().map(from_toc_id(self)).chain(lt_iter).chain(self.iter_parent())
+ self.params
+ .iter_type_or_consts()
+ .map(from_toc_id(self))
+ .chain(lt_iter)
+ .chain(self.iter_parent())
}
/// Iterate over types and const params without parent params.
@@ -336,16 +344,19 @@ impl Generics {
}
};
- self.params.iter().map(from_toc_id(self)).chain(self.params.iter_lt().map(from_lt_id(self)))
+ self.params
+ .iter_type_or_consts()
+ .map(from_toc_id(self))
+ .chain(self.params.iter_lt().map(from_lt_id(self)))
}
/// Iterator over types and const params of parent.
- #[allow(clippy::needless_lifetimes)]
- pub(crate) fn iter_parent<'a>(
- &'a self,
- ) -> impl DoubleEndedIterator<Item = (GenericParamId, GenericParamDataRef<'a>)> + 'a {
+ pub(crate) fn iter_parent(
+ &self,
+ ) -> impl DoubleEndedIterator<Item = (GenericParamId, GenericParamDataRef<'_>)> + '_ {
self.parent_generics().into_iter().flat_map(|it| {
- let from_toc_id = move |(local_id, p): (_, &'a TypeOrConstParamData)| {
+ let from_toc_id = move |(local_id, p)| {
+ let p: &_ = p;
let id = TypeOrConstParamId { parent: it.def, local_id };
match p {
TypeOrConstParamData::TypeParamData(p) => (
@@ -359,14 +370,14 @@ impl Generics {
}
};
- let from_lt_id = move |(local_id, p): (_, &'a LifetimeParamData)| {
+ let from_lt_id = move |(local_id, p): (_, _)| {
(
GenericParamId::LifetimeParamId(LifetimeParamId { parent: it.def, local_id }),
GenericParamDataRef::LifetimeParamData(p),
)
};
let lt_iter = it.params.iter_lt().map(from_lt_id);
- it.params.iter().map(from_toc_id).chain(lt_iter)
+ it.params.iter_type_or_consts().map(from_toc_id).chain(lt_iter)
})
}
@@ -383,7 +394,7 @@ impl Generics {
}
/// Returns number of generic parameter excluding those from parent
- fn len_params(&self) -> usize {
+ fn len_type_and_const_params(&self) -> usize {
self.params.type_or_consts.len()
}
@@ -394,7 +405,7 @@ impl Generics {
let mut impl_trait_params = 0;
let mut const_params = 0;
let mut lifetime_params = 0;
- self.params.iter().for_each(|(_, data)| match data {
+ self.params.iter_type_or_consts().for_each(|(_, data)| match data {
TypeOrConstParamData::TypeParamData(p) => match p.provenance {
TypeParamProvenance::TypeParamList => type_params += 1,
TypeParamProvenance::TraitSelf => self_params += 1,
@@ -409,18 +420,23 @@ impl Generics {
(parent_len, self_params, type_params, const_params, impl_trait_params, lifetime_params)
}
- pub(crate) fn param_idx(&self, param: TypeOrConstParamId) -> Option<usize> {
- Some(self.find_param(param)?.0)
+ pub(crate) fn type_or_const_param_idx(&self, param: TypeOrConstParamId) -> Option<usize> {
+ Some(self.find_type_or_const_param(param)?.0)
}
- fn find_param(&self, param: TypeOrConstParamId) -> Option<(usize, &TypeOrConstParamData)> {
+ fn find_type_or_const_param(
+ &self,
+ param: TypeOrConstParamId,
+ ) -> Option<(usize, &TypeOrConstParamData)> {
if param.parent == self.def {
- let (idx, (_local_id, data)) =
- self.params.iter().enumerate().find(|(_, (idx, _))| *idx == param.local_id)?;
- Some((idx, data))
+ let idx = param.local_id.into_raw().into_u32() as usize;
+ if idx >= self.params.type_or_consts.len() {
+ return None;
+ }
+ Some((idx, &self.params.type_or_consts[param.local_id]))
} else {
self.parent_generics()
- .and_then(|g| g.find_param(param))
+ .and_then(|g| g.find_type_or_const_param(param))
// Remember that parent parameters come after parameters for self.
.map(|(idx, data)| (self.len_self() + idx, data))
}
@@ -432,13 +448,14 @@ impl Generics {
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((self.len_params() + idx, data))
+ let idx = lifetime.local_id.into_raw().into_u32() as usize;
+ if idx >= self.params.lifetimes.len() {
+ return None;
+ }
+ Some((
+ self.len_type_and_const_params() + idx,
+ &self.params.lifetimes[lifetime.local_id],
+ ))
} else {
self.parent_generics()
.and_then(|g| g.find_lifetime(lifetime))
@@ -450,6 +467,10 @@ impl Generics {
self.parent_generics.as_deref()
}
+ pub(crate) fn parent_or_self(&self) -> &Generics {
+ self.parent_generics.as_deref().unwrap_or(self)
+ }
+
/// Returns a Substitution that replaces each parameter by a bound variable.
pub(crate) fn bound_vars_subst(
&self,