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.rs | 81 |
1 files changed, 60 insertions, 21 deletions
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs index a6706aa81d..343e89eb9b 100644 --- a/crates/hir_ty/src/utils.rs +++ b/crates/hir_ty/src/utils.rs @@ -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), }), ) } |