This commit is contained in:
Lukas Wirth 2024-06-21 18:27:05 +02:00
parent 480bfd5a7d
commit c01f4cf902
4 changed files with 27 additions and 27 deletions

View file

@ -444,15 +444,18 @@ impl GenericParamsCollector {
impl GenericParams { impl GenericParams {
/// Number of Generic parameters (type_or_consts + lifetimes) /// Number of Generic parameters (type_or_consts + lifetimes)
#[inline]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.type_or_consts.len() + self.lifetimes.len() self.type_or_consts.len() + self.lifetimes.len()
} }
#[inline]
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.len() == 0 self.len() == 0
} }
/// Iterator of type_or_consts field /// Iterator of type_or_consts field
#[inline]
pub fn iter_type_or_consts( pub fn iter_type_or_consts(
&self, &self,
) -> impl DoubleEndedIterator<Item = (LocalTypeOrConstParamId, &TypeOrConstParamData)> { ) -> impl DoubleEndedIterator<Item = (LocalTypeOrConstParamId, &TypeOrConstParamData)> {
@ -460,6 +463,7 @@ impl GenericParams {
} }
/// Iterator of lifetimes field /// Iterator of lifetimes field
#[inline]
pub fn iter_lt( pub fn iter_lt(
&self, &self,
) -> impl DoubleEndedIterator<Item = (LocalLifetimeParamId, &LifetimeParamData)> { ) -> impl DoubleEndedIterator<Item = (LocalLifetimeParamId, &LifetimeParamData)> {
@ -608,7 +612,7 @@ impl GenericParams {
}) })
} }
pub fn find_trait_self_param(&self) -> Option<LocalTypeOrConstParamId> { pub fn trait_self_param(&self) -> Option<LocalTypeOrConstParamId> {
if self.type_or_consts.is_empty() { if self.type_or_consts.is_empty() {
return None; return None;
} }

View file

@ -923,6 +923,7 @@ pub enum GenericDefId {
ImplId(ImplId), ImplId(ImplId),
// enum variants cannot have generics themselves, but their parent enums // enum variants cannot have generics themselves, but their parent enums
// can, and this makes some code easier to write // can, and this makes some code easier to write
// FIXME: Try to remove this as that will reduce the amount of query slots generated per enum?
EnumVariantId(EnumVariantId), EnumVariantId(EnumVariantId),
// consts can have type parameters from their parents (i.e. associated consts of traits) // consts can have type parameters from their parents (i.e. associated consts of traits)
ConstId(ConstId), ConstId(ConstId),

View file

@ -50,13 +50,17 @@ impl Generics {
} }
pub(crate) fn iter_id(&self) -> impl Iterator<Item = GenericParamId> + '_ { pub(crate) fn iter_id(&self) -> impl Iterator<Item = GenericParamId> + '_ {
self.iter().map(|(id, _)| id) self.iter_self_id().chain(self.iter_parent_id())
} }
pub(crate) fn iter_self_id(&self) -> impl Iterator<Item = GenericParamId> + '_ { pub(crate) fn iter_self_id(&self) -> impl Iterator<Item = GenericParamId> + '_ {
self.iter_self().map(|(id, _)| id) self.iter_self().map(|(id, _)| id)
} }
fn iter_parent_id(&self) -> impl Iterator<Item = GenericParamId> + '_ {
self.iter_parent().map(|(id, _)| id)
}
pub(crate) fn iter_self_type_or_consts( pub(crate) fn iter_self_type_or_consts(
&self, &self,
) -> impl DoubleEndedIterator<Item = (LocalTypeOrConstParamId, &TypeOrConstParamData)> { ) -> impl DoubleEndedIterator<Item = (LocalTypeOrConstParamId, &TypeOrConstParamData)> {
@ -81,7 +85,7 @@ impl Generics {
} }
/// Iterator over types and const params of parent. /// Iterator over types and const params of parent.
pub(crate) fn iter_parent( fn iter_parent(
&self, &self,
) -> impl DoubleEndedIterator<Item = (GenericParamId, GenericParamDataRef<'_>)> + '_ { ) -> impl DoubleEndedIterator<Item = (GenericParamId, GenericParamDataRef<'_>)> + '_ {
self.parent_generics().into_iter().flat_map(|it| { self.parent_generics().into_iter().flat_map(|it| {
@ -108,7 +112,6 @@ impl Generics {
let mut type_params = 0; let mut type_params = 0;
let mut impl_trait_params = 0; let mut impl_trait_params = 0;
let mut const_params = 0; let mut const_params = 0;
let mut lifetime_params = 0;
self.params.iter_type_or_consts().for_each(|(_, data)| match data { self.params.iter_type_or_consts().for_each(|(_, data)| match data {
TypeOrConstParamData::TypeParamData(p) => match p.provenance { TypeOrConstParamData::TypeParamData(p) => match p.provenance {
TypeParamProvenance::TypeParamList => type_params += 1, TypeParamProvenance::TypeParamList => type_params += 1,
@ -118,52 +121,44 @@ impl Generics {
TypeOrConstParamData::ConstParamData(_) => const_params += 1, TypeOrConstParamData::ConstParamData(_) => const_params += 1,
}); });
self.params.iter_lt().for_each(|(_, _)| lifetime_params += 1); let lifetime_params = self.params.iter_lt().count();
let parent_len = self.parent_generics().map_or(0, Generics::len); let parent_len = self.parent_generics().map_or(0, Generics::len);
(parent_len, self_param, type_params, const_params, impl_trait_params, lifetime_params) (parent_len, self_param, type_params, const_params, impl_trait_params, lifetime_params)
} }
pub(crate) fn type_or_const_param_idx(&self, param: TypeOrConstParamId) -> Option<usize> { pub(crate) fn type_or_const_param_idx(&self, param: TypeOrConstParamId) -> Option<usize> {
Some(self.find_type_or_const_param(param)?.0) self.find_type_or_const_param(param)
} }
fn find_type_or_const_param( fn find_type_or_const_param(&self, param: TypeOrConstParamId) -> Option<usize> {
&self,
param: TypeOrConstParamId,
) -> Option<(usize, &TypeOrConstParamData)> {
if param.parent == self.def { if param.parent == self.def {
let idx = param.local_id.into_raw().into_u32() as usize; let idx = param.local_id.into_raw().into_u32() as usize;
if idx >= self.params.type_or_consts.len() { debug_assert!(idx <= self.params.type_or_consts.len());
return None; Some(idx)
}
Some((idx, &self.params.type_or_consts[param.local_id]))
} else { } else {
debug_assert_eq!(self.parent_generics().map(|it| it.def), Some(param.parent));
self.parent_generics() self.parent_generics()
.and_then(|g| g.find_type_or_const_param(param)) .and_then(|g| g.find_type_or_const_param(param))
// Remember that parent parameters come after parameters for self. // Remember that parent parameters come after parameters for self.
.map(|(idx, data)| (self.len_self() + idx, data)) .map(|idx| self.len_self() + idx)
} }
} }
pub(crate) fn lifetime_idx(&self, lifetime: LifetimeParamId) -> Option<usize> { pub(crate) fn lifetime_idx(&self, lifetime: LifetimeParamId) -> Option<usize> {
Some(self.find_lifetime(lifetime)?.0) self.find_lifetime(lifetime)
} }
fn find_lifetime(&self, lifetime: LifetimeParamId) -> Option<(usize, &LifetimeParamData)> { fn find_lifetime(&self, lifetime: LifetimeParamId) -> Option<usize> {
if lifetime.parent == self.def { if lifetime.parent == self.def {
let idx = lifetime.local_id.into_raw().into_u32() as usize; let idx = lifetime.local_id.into_raw().into_u32() as usize;
if idx >= self.params.lifetimes.len() { debug_assert!(idx <= self.params.lifetimes.len());
return None; Some(self.params.type_or_consts.len() + idx)
}
Some((
self.params.type_or_consts.len() + idx,
&self.params.lifetimes[lifetime.local_id],
))
} else { } else {
debug_assert_eq!(self.parent_generics().map(|it| it.def), Some(lifetime.parent));
self.parent_generics() self.parent_generics()
.and_then(|g| g.find_lifetime(lifetime)) .and_then(|g| g.find_lifetime(lifetime))
.map(|(idx, data)| (self.len_self() + idx, data)) .map(|idx| self.len_self() + idx)
} }
} }

View file

@ -155,7 +155,7 @@ impl Iterator for ClauseElaborator<'_> {
fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId, cb: impl FnMut(TraitId)) { fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId, cb: impl FnMut(TraitId)) {
let resolver = trait_.resolver(db); let resolver = trait_.resolver(db);
let generic_params = db.generic_params(trait_.into()); let generic_params = db.generic_params(trait_.into());
let trait_self = generic_params.find_trait_self_param(); let trait_self = generic_params.trait_self_param();
generic_params generic_params
.where_predicates .where_predicates
.iter() .iter()
@ -188,7 +188,7 @@ fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId, cb: impl FnMut(Tra
fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef, cb: impl FnMut(TraitRef)) { fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef, cb: impl FnMut(TraitRef)) {
let generic_params = db.generic_params(trait_ref.hir_trait_id().into()); let generic_params = db.generic_params(trait_ref.hir_trait_id().into());
let trait_self = match generic_params.find_trait_self_param() { let trait_self = match generic_params.trait_self_param() {
Some(p) => TypeOrConstParamId { parent: trait_ref.hir_trait_id().into(), local_id: p }, Some(p) => TypeOrConstParamId { parent: trait_ref.hir_trait_id().into(), local_id: p },
None => return, None => return,
}; };