Cleanup util::Generics method names

This commit is contained in:
Lukas Wirth 2024-04-06 14:29:40 +02:00
parent f3567bb604
commit a82e028e30
11 changed files with 82 additions and 49 deletions

View file

@ -3,13 +3,15 @@
//! generic parameters. See also the `Generics` type and the `generics_of` query //! generic parameters. See also the `Generics` type and the `generics_of` query
//! in rustc. //! in rustc.
use std::ops;
use either::Either; use either::Either;
use hir_expand::{ use hir_expand::{
name::{AsName, Name}, name::{AsName, Name},
ExpandResult, ExpandResult,
}; };
use intern::Interned; use intern::Interned;
use la_arena::{Arena, Idx}; use la_arena::Arena;
use once_cell::unsync::Lazy; use once_cell::unsync::Lazy;
use stdx::impl_from; use stdx::impl_from;
use syntax::ast::{self, HasGenericParams, HasName, HasTypeBounds}; use syntax::ast::{self, HasGenericParams, HasName, HasTypeBounds};
@ -23,7 +25,7 @@ use crate::{
nameres::{DefMap, MacroSubNs}, nameres::{DefMap, MacroSubNs},
type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRef}, type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRef},
AdtId, ConstParamId, GenericDefId, HasModule, ItemTreeLoc, LifetimeParamId, AdtId, ConstParamId, GenericDefId, HasModule, ItemTreeLoc, LifetimeParamId,
LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId, LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId,
}; };
/// Data about a generic type parameter (to a function, struct, impl, ...). /// Data about a generic type parameter (to a function, struct, impl, ...).
@ -158,6 +160,20 @@ pub struct GenericParams {
pub where_predicates: Box<[WherePredicate]>, pub where_predicates: Box<[WherePredicate]>,
} }
impl ops::Index<LocalTypeOrConstParamId> for GenericParams {
type Output = TypeOrConstParamData;
fn index(&self, index: LocalTypeOrConstParamId) -> &TypeOrConstParamData {
&self.type_or_consts[index]
}
}
impl ops::Index<LocalLifetimeParamId> for GenericParams {
type Output = LifetimeParamData;
fn index(&self, index: LocalLifetimeParamId) -> &LifetimeParamData {
&self.lifetimes[index]
}
}
/// A single predicate from a where clause, i.e. `where Type: Trait`. Combined /// A single predicate from a where clause, i.e. `where Type: Trait`. Combined
/// where clauses like `where T: Foo + Bar` are turned into multiple of these. /// where clauses like `where T: Foo + Bar` are turned into multiple of these.
/// It might still result in multiple actual predicates though, because of /// It might still result in multiple actual predicates though, because of
@ -199,7 +215,7 @@ impl GenericParamsCollector {
lower_ctx: &LowerCtx<'_>, lower_ctx: &LowerCtx<'_>,
node: &dyn HasGenericParams, node: &dyn HasGenericParams,
add_param_attrs: impl FnMut( add_param_attrs: impl FnMut(
Either<Idx<TypeOrConstParamData>, Idx<LifetimeParamData>>, Either<LocalTypeOrConstParamId, LocalLifetimeParamId>,
ast::GenericParam, ast::GenericParam,
), ),
) { ) {
@ -227,7 +243,7 @@ impl GenericParamsCollector {
lower_ctx: &LowerCtx<'_>, lower_ctx: &LowerCtx<'_>,
params: ast::GenericParamList, params: ast::GenericParamList,
mut add_param_attrs: impl FnMut( mut add_param_attrs: impl FnMut(
Either<Idx<TypeOrConstParamData>, Idx<LifetimeParamData>>, Either<LocalTypeOrConstParamId, LocalLifetimeParamId>,
ast::GenericParam, ast::GenericParam,
), ),
) { ) {
@ -416,16 +432,16 @@ impl GenericParams {
} }
/// Iterator of type_or_consts field /// Iterator of type_or_consts field
pub fn iter( pub fn iter_type_or_consts(
&self, &self,
) -> impl DoubleEndedIterator<Item = (Idx<TypeOrConstParamData>, &TypeOrConstParamData)> { ) -> impl DoubleEndedIterator<Item = (LocalTypeOrConstParamId, &TypeOrConstParamData)> {
self.type_or_consts.iter() self.type_or_consts.iter()
} }
/// Iterator of lifetimes field /// Iterator of lifetimes field
pub fn iter_lt( pub fn iter_lt(
&self, &self,
) -> impl DoubleEndedIterator<Item = (Idx<LifetimeParamData>, &LifetimeParamData)> { ) -> impl DoubleEndedIterator<Item = (LocalLifetimeParamId, &LifetimeParamData)> {
self.lifetimes.iter() self.lifetimes.iter()
} }

View file

@ -90,7 +90,7 @@ pub(crate) fn path_to_const(
} }
ParamLoweringMode::Variable => { ParamLoweringMode::Variable => {
let args = args(); let args = args();
match args.as_ref().and_then(|args| args.param_idx(p.into())) { match args.as_ref().and_then(|args| args.type_or_const_param_idx(p.into())) {
Some(it) => ConstValue::BoundVar(BoundVar::new(debruijn, it)), Some(it) => ConstValue::BoundVar(BoundVar::new(debruijn, it)),
None => { None => {
never!( never!(

View file

@ -453,7 +453,7 @@ impl HirDisplay for Const {
ConstValue::Placeholder(idx) => { ConstValue::Placeholder(idx) => {
let id = from_placeholder_idx(f.db, *idx); let id = from_placeholder_idx(f.db, *idx);
let generics = generics(f.db.upcast(), id.parent); let generics = generics(f.db.upcast(), id.parent);
let param_data = &generics.params.type_or_consts[id.local_id]; let param_data = &generics.params[id.local_id];
write!(f, "{}", param_data.name().unwrap().display(f.db.upcast()))?; write!(f, "{}", param_data.name().unwrap().display(f.db.upcast()))?;
Ok(()) Ok(())
} }
@ -1176,7 +1176,7 @@ impl HirDisplay for Ty {
TyKind::Placeholder(idx) => { TyKind::Placeholder(idx) => {
let id = from_placeholder_idx(db, *idx); let id = from_placeholder_idx(db, *idx);
let generics = generics(db.upcast(), id.parent); let generics = generics(db.upcast(), id.parent);
let param_data = &generics.params.type_or_consts[id.local_id]; let param_data = &generics.params[id.local_id];
match param_data { match param_data {
TypeOrConstParamData::TypeParamData(p) => match p.provenance { TypeOrConstParamData::TypeParamData(p) => match p.provenance {
TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => { TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => {
@ -1724,7 +1724,7 @@ impl HirDisplay for LifetimeData {
LifetimeData::Placeholder(idx) => { LifetimeData::Placeholder(idx) => {
let id = lt_from_placeholder_idx(f.db, *idx); let id = lt_from_placeholder_idx(f.db, *idx);
let generics = generics(f.db.upcast(), id.parent); let generics = generics(f.db.upcast(), id.parent);
let param_data = &generics.params.lifetimes[id.local_id]; let param_data = &generics.params[id.local_id];
write!(f, "{}", param_data.name.display(f.db.upcast()))?; write!(f, "{}", param_data.name.display(f.db.upcast()))?;
Ok(()) Ok(())
} }

View file

@ -357,7 +357,7 @@ impl CapturedItemWithoutTy {
outer_binder: DebruijnIndex, outer_binder: DebruijnIndex,
) -> Result<chalk_ir::Const<Interner>, Self::Error> { ) -> Result<chalk_ir::Const<Interner>, Self::Error> {
let x = from_placeholder_idx(self.db, idx); let x = from_placeholder_idx(self.db, idx);
let Some(idx) = self.generics.param_idx(x) else { let Some(idx) = self.generics.type_or_const_param_idx(x) else {
return Err(()); return Err(());
}; };
Ok(BoundVar::new(outer_binder, idx).to_const(Interner, ty)) Ok(BoundVar::new(outer_binder, idx).to_const(Interner, ty))
@ -369,7 +369,7 @@ impl CapturedItemWithoutTy {
outer_binder: DebruijnIndex, outer_binder: DebruijnIndex,
) -> std::result::Result<Ty, Self::Error> { ) -> std::result::Result<Ty, Self::Error> {
let x = from_placeholder_idx(self.db, idx); let x = from_placeholder_idx(self.db, idx);
let Some(idx) = self.generics.param_idx(x) else { let Some(idx) = self.generics.type_or_const_param_idx(x) else {
return Err(()); return Err(());
}; };
Ok(BoundVar::new(outer_binder, idx).to_ty(Interner)) Ok(BoundVar::new(outer_binder, idx).to_ty(Interner))

View file

@ -288,7 +288,7 @@ impl Hash for ConstScalar {
/// Return an index of a parameter in the generic type parameter list by it's id. /// Return an index of a parameter in the generic type parameter list by it's id.
pub fn param_idx(db: &dyn HirDatabase, id: TypeOrConstParamId) -> Option<usize> { pub fn param_idx(db: &dyn HirDatabase, id: TypeOrConstParamId) -> Option<usize> {
generics(db.upcast(), id.parent).param_idx(id) generics(db.upcast(), id.parent).type_or_const_param_idx(id)
} }
pub(crate) fn wrap_empty_binders<T>(value: T) -> Binders<T> pub(crate) fn wrap_empty_binders<T>(value: T) -> Binders<T>

View file

@ -578,7 +578,7 @@ impl<'a> TyLoweringContext<'a> {
let idx = match self let idx = match self
.generics() .generics()
.expect("generics in scope") .expect("generics in scope")
.param_idx(param_id.into()) .type_or_const_param_idx(param_id.into())
{ {
None => { None => {
never!("no matching generics"); never!("no matching generics");
@ -1026,7 +1026,7 @@ impl<'a> TyLoweringContext<'a> {
} }
ParamLoweringMode::Variable => { ParamLoweringMode::Variable => {
let idx = generics(self.db.upcast(), def) let idx = generics(self.db.upcast(), def)
.param_idx(param_id) .type_or_const_param_idx(param_id)
.expect("matching generics"); .expect("matching generics");
TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx)) TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))
} }
@ -1505,7 +1505,7 @@ fn named_associated_type_shorthand_candidates<R>(
// Handle `Self::Type` referring to own associated type in trait definitions // Handle `Self::Type` referring to own associated type in trait definitions
if let GenericDefId::TraitId(trait_id) = param_id.parent() { if let GenericDefId::TraitId(trait_id) = param_id.parent() {
let trait_generics = generics(db.upcast(), trait_id.into()); let trait_generics = generics(db.upcast(), trait_id.into());
if trait_generics.params.type_or_consts[param_id.local_id()].is_trait_self() { if trait_generics.params[param_id.local_id()].is_trait_self() {
let def_generics = generics(db.upcast(), def); let def_generics = generics(db.upcast(), def);
let starting_idx = match def { let starting_idx = match def {
GenericDefId::TraitId(_) => 0, GenericDefId::TraitId(_) => 0,

View file

@ -495,9 +495,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
ty, ty,
value: chalk_ir::ConstValue::BoundVar(BoundVar::new( value: chalk_ir::ConstValue::BoundVar(BoundVar::new(
DebruijnIndex::INNERMOST, DebruijnIndex::INNERMOST,
gen.param_idx(p.into()).ok_or(MirLowerError::TypeError( gen.type_or_const_param_idx(p.into()).ok_or(
MirLowerError::TypeError(
"fail to lower const generic param", "fail to lower const generic param",
))?, ),
)?,
)), )),
} }
.intern(Interner), .intern(Interner),

View file

@ -101,7 +101,7 @@ impl FallibleTypeFolder<Interner> for Filler<'_> {
_outer_binder: DebruijnIndex, _outer_binder: DebruijnIndex,
) -> std::result::Result<chalk_ir::Const<Interner>, Self::Error> { ) -> std::result::Result<chalk_ir::Const<Interner>, Self::Error> {
let it = from_placeholder_idx(self.db, idx); let it = from_placeholder_idx(self.db, idx);
let Some(idx) = self.generics.as_ref().and_then(|g| g.param_idx(it)) else { let Some(idx) = self.generics.as_ref().and_then(|g| g.type_or_const_param_idx(it)) else {
not_supported!("missing idx in generics"); not_supported!("missing idx in generics");
}; };
Ok(self Ok(self
@ -119,7 +119,7 @@ impl FallibleTypeFolder<Interner> for Filler<'_> {
_outer_binder: DebruijnIndex, _outer_binder: DebruijnIndex,
) -> std::result::Result<Ty, Self::Error> { ) -> std::result::Result<Ty, Self::Error> {
let it = from_placeholder_idx(self.db, idx); let it = from_placeholder_idx(self.db, idx);
let Some(idx) = self.generics.as_ref().and_then(|g| g.param_idx(it)) else { let Some(idx) = self.generics.as_ref().and_then(|g| g.type_or_const_param_idx(it)) else {
not_supported!("missing idx in generics"); not_supported!("missing idx in generics");
}; };
Ok(self Ok(self

View file

@ -308,7 +308,11 @@ impl Generics {
}; };
let lt_iter = self.params.iter_lt().map(from_lt_id(self)); 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. /// Iterate over types and const params without parent params.
@ -340,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. /// Iterator over types and const params of parent.
#[allow(clippy::needless_lifetimes)] pub(crate) fn iter_parent(
pub(crate) fn iter_parent<'a>( &self,
&'a self, ) -> impl DoubleEndedIterator<Item = (GenericParamId, GenericParamDataRef<'_>)> + '_ {
) -> impl DoubleEndedIterator<Item = (GenericParamId, GenericParamDataRef<'a>)> + 'a {
self.parent_generics().into_iter().flat_map(|it| { 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 }; let id = TypeOrConstParamId { parent: it.def, local_id };
match p { match p {
TypeOrConstParamData::TypeParamData(p) => ( TypeOrConstParamData::TypeParamData(p) => (
@ -363,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 }), GenericParamId::LifetimeParamId(LifetimeParamId { parent: it.def, local_id }),
GenericParamDataRef::LifetimeParamData(p), GenericParamDataRef::LifetimeParamData(p),
) )
}; };
let lt_iter = it.params.iter_lt().map(from_lt_id); 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)
}) })
} }
@ -387,7 +394,7 @@ impl Generics {
} }
/// Returns number of generic parameter excluding those from parent /// 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() self.params.type_or_consts.len()
} }
@ -398,7 +405,7 @@ impl Generics {
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; 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 { TypeOrConstParamData::TypeParamData(p) => match p.provenance {
TypeParamProvenance::TypeParamList => type_params += 1, TypeParamProvenance::TypeParamList => type_params += 1,
TypeParamProvenance::TraitSelf => self_params += 1, TypeParamProvenance::TraitSelf => self_params += 1,
@ -413,18 +420,23 @@ impl Generics {
(parent_len, self_params, type_params, const_params, impl_trait_params, lifetime_params) (parent_len, self_params, type_params, const_params, impl_trait_params, lifetime_params)
} }
pub(crate) fn param_idx(&self, param: TypeOrConstParamId) -> Option<usize> { pub(crate) fn type_or_const_param_idx(&self, param: TypeOrConstParamId) -> Option<usize> {
Some(self.find_param(param)?.0) 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 { if param.parent == self.def {
let (idx, (_local_id, data)) = let idx = param.local_id.into_raw().into_u32() as usize;
self.params.iter().enumerate().find(|(_, (idx, _))| *idx == param.local_id)?; if idx >= self.params.type_or_consts.len() {
Some((idx, data)) return None;
}
Some((idx, &self.params.type_or_consts[param.local_id]))
} else { } else {
self.parent_generics() 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. // Remember that parent parameters come after parameters for self.
.map(|(idx, data)| (self.len_self() + idx, data)) .map(|(idx, data)| (self.len_self() + idx, data))
} }
@ -436,13 +448,14 @@ impl Generics {
fn find_lifetime(&self, lifetime: LifetimeParamId) -> Option<(usize, &LifetimeParamData)> { fn find_lifetime(&self, lifetime: LifetimeParamId) -> Option<(usize, &LifetimeParamData)> {
if lifetime.parent == self.def { if lifetime.parent == self.def {
let (idx, (_local_id, data)) = self let idx = lifetime.local_id.into_raw().into_u32() as usize;
.params if idx >= self.params.lifetimes.len() {
.iter_lt() return None;
.enumerate() }
.find(|(_, (idx, _))| *idx == lifetime.local_id)?; Some((
self.len_type_and_const_params() + idx,
Some((self.len_params() + idx, data)) &self.params.lifetimes[lifetime.local_id],
))
} else { } else {
self.parent_generics() self.parent_generics()
.and_then(|g| g.find_lifetime(lifetime)) .and_then(|g| g.find_lifetime(lifetime))

View file

@ -653,7 +653,7 @@ impl Module {
GenericParamId::LifetimeParamId(LifetimeParamId { parent, local_id }) GenericParamId::LifetimeParamId(LifetimeParamId { parent, local_id })
}); });
let type_params = generic_params let type_params = generic_params
.iter() .iter_type_or_consts()
.filter(|(_, it)| it.type_param().is_some()) .filter(|(_, it)| it.type_param().is_some())
.map(|(local_id, _)| { .map(|(local_id, _)| {
GenericParamId::TypeParamId(TypeParamId::from_unchecked( GenericParamId::TypeParamId(TypeParamId::from_unchecked(

View file

@ -280,7 +280,9 @@ impl flags::AnalysisStats {
let mut fail = 0; let mut fail = 0;
for &a in adts { for &a in adts {
let generic_params = db.generic_params(a.into()); let generic_params = db.generic_params(a.into());
if generic_params.iter().next().is_some() || generic_params.iter_lt().next().is_some() { if generic_params.iter_type_or_consts().next().is_some()
|| generic_params.iter_lt().next().is_some()
{
// Data types with generics don't have layout. // Data types with generics don't have layout.
continue; continue;
} }