mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 13:51:31 +00:00
Add const generics
This commit is contained in:
parent
5e85158706
commit
b301b040f5
32 changed files with 1272 additions and 527 deletions
|
@ -15,16 +15,18 @@ use hir_def::{
|
|||
path::Path,
|
||||
resolver::{HasResolver, TypeNs},
|
||||
type_ref::{TraitBoundModifier, TypeRef},
|
||||
GenericDefId, ItemContainerId, Lookup, TraitId, TypeAliasId, TypeOrConstParamId,
|
||||
ConstParamId, GenericDefId, ItemContainerId, Lookup, TraitId, TypeAliasId, TypeOrConstParamId,
|
||||
TypeParamId,
|
||||
};
|
||||
use hir_expand::name::{name, Name};
|
||||
use itertools::Either;
|
||||
use rustc_hash::FxHashSet;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use syntax::SmolStr;
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase, ChalkTraitId, Interner, Substitution, TraitRef, TraitRefExt, TyKind,
|
||||
WhereClause,
|
||||
db::HirDatabase, ChalkTraitId, ConstData, ConstValue, GenericArgData, Interner, Substitution,
|
||||
TraitRef, TraitRefExt, TyKind, WhereClause,
|
||||
};
|
||||
|
||||
pub(crate) fn fn_traits(db: &dyn DefDatabase, krate: CrateId) -> impl Iterator<Item = TraitId> {
|
||||
|
@ -203,30 +205,43 @@ impl Generics {
|
|||
)
|
||||
}
|
||||
|
||||
pub(crate) fn toc_iter<'a>(
|
||||
pub(crate) fn iter_id<'a>(
|
||||
&'a self,
|
||||
) -> impl Iterator<Item = (TypeOrConstParamId, &'a TypeOrConstParamData)> + 'a {
|
||||
) -> impl Iterator<Item = Either<TypeParamId, ConstParamId>> + 'a {
|
||||
self.iter().map(|(id, data)| match data {
|
||||
TypeOrConstParamData::TypeParamData(_) => Either::Left(TypeParamId::from_unchecked(id)),
|
||||
TypeOrConstParamData::ConstParamData(_) => {
|
||||
Either::Right(ConstParamId::from_unchecked(id))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Iterator over types and const params of parent, then self.
|
||||
pub(crate) fn iter<'a>(
|
||||
&'a self,
|
||||
) -> impl DoubleEndedIterator<Item = (TypeOrConstParamId, &'a TypeOrConstParamData)> + 'a {
|
||||
self.parent_generics
|
||||
.as_ref()
|
||||
.into_iter()
|
||||
.flat_map(|it| {
|
||||
it.params
|
||||
.toc_iter()
|
||||
.iter()
|
||||
.map(move |(local_id, p)| (TypeOrConstParamId { parent: it.def, local_id }, p))
|
||||
})
|
||||
.chain(
|
||||
self.params.toc_iter().map(move |(local_id, p)| {
|
||||
self.params.iter().map(move |(local_id, p)| {
|
||||
(TypeOrConstParamId { parent: self.def, local_id }, p)
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
/// Iterator over types and const params of parent.
|
||||
pub(crate) fn iter_parent<'a>(
|
||||
&'a self,
|
||||
) -> impl Iterator<Item = (TypeOrConstParamId, &'a TypeOrConstParamData)> + 'a {
|
||||
self.parent_generics.as_ref().into_iter().flat_map(|it| {
|
||||
it.params
|
||||
.tocs
|
||||
.type_or_consts
|
||||
.iter()
|
||||
.map(move |(local_id, p)| (TypeOrConstParamId { parent: it.def, local_id }, p))
|
||||
})
|
||||
|
@ -239,7 +254,7 @@ impl Generics {
|
|||
/// (total, parents, child)
|
||||
pub(crate) fn len_split(&self) -> (usize, usize, usize) {
|
||||
let parent = self.parent_generics.as_ref().map_or(0, |p| p.len());
|
||||
let child = self.params.tocs.len();
|
||||
let child = self.params.type_or_consts.len();
|
||||
(parent + child, parent, child)
|
||||
}
|
||||
|
||||
|
@ -248,22 +263,20 @@ impl Generics {
|
|||
let parent = self.parent_generics.as_ref().map_or(0, |p| p.len());
|
||||
let self_params = self
|
||||
.params
|
||||
.tocs
|
||||
.iter()
|
||||
.filter_map(|x| x.1.type_param())
|
||||
.filter(|p| p.provenance == TypeParamProvenance::TraitSelf)
|
||||
.count();
|
||||
let type_params = self
|
||||
.params
|
||||
.tocs
|
||||
.type_or_consts
|
||||
.iter()
|
||||
.filter_map(|x| x.1.type_param())
|
||||
.filter(|p| p.provenance == TypeParamProvenance::TypeParamList)
|
||||
.count();
|
||||
let const_params = self.params.tocs.iter().filter_map(|x| x.1.const_param()).count();
|
||||
let const_params = self.params.iter().filter_map(|x| x.1.const_param()).count();
|
||||
let impl_trait_params = self
|
||||
.params
|
||||
.tocs
|
||||
.iter()
|
||||
.filter_map(|x| x.1.type_param())
|
||||
.filter(|p| p.provenance == TypeParamProvenance::ArgumentImplTrait)
|
||||
|
@ -279,7 +292,7 @@ impl Generics {
|
|||
if param.parent == self.def {
|
||||
let (idx, (_local_id, data)) = self
|
||||
.params
|
||||
.tocs
|
||||
.type_or_consts
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, (idx, _))| *idx == param.local_id)
|
||||
|
@ -292,21 +305,47 @@ impl Generics {
|
|||
}
|
||||
|
||||
/// Returns a Substitution that replaces each parameter by a bound variable.
|
||||
pub(crate) fn bound_vars_subst(&self, debruijn: DebruijnIndex) -> Substitution {
|
||||
pub(crate) fn bound_vars_subst(
|
||||
&self,
|
||||
db: &dyn HirDatabase,
|
||||
debruijn: DebruijnIndex,
|
||||
) -> Substitution {
|
||||
Substitution::from_iter(
|
||||
Interner,
|
||||
self.toc_iter()
|
||||
.enumerate()
|
||||
.map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(Interner)),
|
||||
self.iter_id().enumerate().map(|(idx, id)| match id {
|
||||
Either::Left(_) => GenericArgData::Ty(
|
||||
TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(Interner),
|
||||
)
|
||||
.intern(Interner),
|
||||
Either::Right(id) => GenericArgData::Const(
|
||||
ConstData {
|
||||
value: ConstValue::BoundVar(BoundVar::new(debruijn, idx)),
|
||||
ty: db.const_param_ty(id),
|
||||
}
|
||||
.intern(Interner),
|
||||
)
|
||||
.intern(Interner),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns a Substitution that replaces each parameter by itself (i.e. `Ty::Param`).
|
||||
pub(crate) fn type_params_subst(&self, db: &dyn HirDatabase) -> Substitution {
|
||||
pub(crate) fn placeholder_subst(&self, db: &dyn HirDatabase) -> Substitution {
|
||||
Substitution::from_iter(
|
||||
Interner,
|
||||
self.toc_iter().map(|(id, _)| {
|
||||
TyKind::Placeholder(crate::to_placeholder_idx(db, id)).intern(Interner)
|
||||
self.iter_id().map(|id| match id {
|
||||
Either::Left(id) => GenericArgData::Ty(
|
||||
TyKind::Placeholder(crate::to_placeholder_idx(db, id.into())).intern(Interner),
|
||||
)
|
||||
.intern(Interner),
|
||||
Either::Right(id) => GenericArgData::Const(
|
||||
ConstData {
|
||||
value: ConstValue::Placeholder(crate::to_placeholder_idx(db, id.into())),
|
||||
ty: db.const_param_ty(id),
|
||||
}
|
||||
.intern(Interner),
|
||||
)
|
||||
.intern(Interner),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue