diff options
| author | dfireBird <me@dfirebird.dev> | 2024-03-09 01:08:35 +0530 |
|---|---|---|
| committer | dfireBird <me@dfirebird.dev> | 2024-03-18 17:18:08 +0530 |
| commit | a6c8cbfd9116226541e91528e6a20c26d52ead46 (patch) | |
| tree | 0270378e218986f622a8653232ae3eccd76262a1 | |
| parent | d6e3929841cbf78adff4e2edb0f6005919ad3a35 (diff) | |
| download | rust-a6c8cbfd9116226541e91528e6a20c26d52ead46.tar.gz rust-a6c8cbfd9116226541e91528e6a20c26d52ead46.zip | |
update `Generics` iter methods to return `GenericParamId`
| -rw-r--r-- | crates/hir-def/src/generics.rs | 40 | ||||
| -rw-r--r-- | crates/hir-ty/src/builder.rs | 19 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/expr.rs | 21 | ||||
| -rw-r--r-- | crates/hir-ty/src/lib.rs | 2 | ||||
| -rw-r--r-- | crates/hir-ty/src/lower.rs | 49 | ||||
| -rw-r--r-- | crates/hir-ty/src/mir/monomorphization.rs | 12 | ||||
| -rw-r--r-- | crates/hir-ty/src/utils.rs | 149 |
7 files changed, 181 insertions, 111 deletions
diff --git a/crates/hir-def/src/generics.rs b/crates/hir-def/src/generics.rs index 8bdd9c6587d..c141acd2ec4 100644 --- a/crates/hir-def/src/generics.rs +++ b/crates/hir-def/src/generics.rs @@ -102,6 +102,46 @@ impl TypeOrConstParamData { impl_from!(TypeParamData, ConstParamData for TypeOrConstParamData); +#[derive(Clone, PartialEq, Eq, Debug, Hash)] +pub enum GenericParamData { + TypeParamData(TypeParamData), + ConstParamData(ConstParamData), + LifetimeParamData(LifetimeParamData), +} + +impl GenericParamData { + pub fn name(&self) -> Option<&Name> { + match self { + GenericParamData::TypeParamData(it) => it.name.as_ref(), + GenericParamData::ConstParamData(it) => Some(&it.name), + GenericParamData::LifetimeParamData(it) => Some(&it.name), + } + } + + pub fn type_param(&self) -> Option<&TypeParamData> { + match self { + GenericParamData::TypeParamData(it) => Some(it), + _ => None, + } + } + + pub fn const_param(&self) -> Option<&ConstParamData> { + match self { + GenericParamData::ConstParamData(it) => Some(it), + _ => None, + } + } + + pub fn lifetime_param(&self) -> Option<&LifetimeParamData> { + match self { + GenericParamData::LifetimeParamData(it) => Some(it), + _ => None, + } + } +} + +impl_from!(TypeParamData, ConstParamData, LifetimeParamData for GenericParamData); + /// Data about the generic parameters of a function, struct, impl, etc. #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct GenericParams { diff --git a/crates/hir-ty/src/builder.rs b/crates/hir-ty/src/builder.rs index e311338a2d6..536542f9a07 100644 --- a/crates/hir-ty/src/builder.rs +++ b/crates/hir-ty/src/builder.rs @@ -9,8 +9,7 @@ use chalk_ir::{ AdtId, DebruijnIndex, Scalar, }; use hir_def::{ - builtin_type::BuiltinType, generics::TypeOrConstParamData, ConstParamId, DefWithBodyId, - GenericDefId, TraitId, TypeAliasId, + builtin_type::BuiltinType, DefWithBodyId, GenericDefId, GenericParamId, TraitId, TypeAliasId, }; use smallvec::SmallVec; @@ -209,10 +208,11 @@ impl TyBuilder<()> { Substitution::from_iter( Interner, params.iter_id().map(|id| match id { - either::Either::Left(_) => TyKind::Error.intern(Interner).cast(Interner), - either::Either::Right(id) => { + GenericParamId::TypeParamId(_) => TyKind::Error.intern(Interner).cast(Interner), + GenericParamId::ConstParamId(id) => { unknown_const_as_generic(db.const_param_ty(id)).cast(Interner) } + GenericParamId::LifetimeParamId(_) => error_lifetime().cast(Interner), }), ) } @@ -225,16 +225,13 @@ impl TyBuilder<()> { ) -> TyBuilder<()> { let generics = generics(db.upcast(), def.into()); assert!(generics.parent_generics().is_some() == parent_subst.is_some()); - let lt_iter = generics.iter_lt_self().map(|_| ParamKind::Lifetime); let params = generics .iter_self() - .map(|(id, data)| match data { - TypeOrConstParamData::TypeParamData(_) => ParamKind::Type, - TypeOrConstParamData::ConstParamData(_) => { - ParamKind::Const(db.const_param_ty(ConstParamId::from_unchecked(id))) - } + .map(|(id, _data)| match id { + GenericParamId::TypeParamId(_) => ParamKind::Type, + GenericParamId::ConstParamId(id) => ParamKind::Const(db.const_param_ty(id)), + GenericParamId::LifetimeParamId(_) => ParamKind::Lifetime, }) - .chain(lt_iter) .collect(); TyBuilder::new((), params, parent_subst) } diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index edfc8a81654..82f7e87ac91 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -8,13 +8,12 @@ use std::{ use chalk_ir::{cast::Cast, fold::Shift, DebruijnIndex, Mutability, TyVariableKind}; use either::Either; use hir_def::{ - generics::TypeOrConstParamData, hir::{ ArithOp, Array, BinaryOp, ClosureKind, Expr, ExprId, LabelId, Literal, Statement, UnaryOp, }, lang_item::{LangItem, LangItemTarget}, path::{GenericArgs, Path}, - BlockId, ConstParamId, FieldId, ItemContainerId, Lookup, TupleFieldId, TupleId, + BlockId, FieldId, GenericParamId, ItemContainerId, Lookup, TupleFieldId, TupleId, }; use hir_expand::name::{name, Name}; use stdx::always; @@ -1836,7 +1835,7 @@ impl InferenceContext<'_> { .args .iter() .take(type_params + const_params + lifetime_params) - .zip(def_generics.iter_id_with_lt()) + .zip(def_generics.iter_id()) { if let Some(g) = generic_arg_to_chalk( self.db, @@ -1866,16 +1865,16 @@ impl InferenceContext<'_> { // Handle everything else as unknown. This also handles generic arguments for the method's // parent (impl or trait), which should come after those for the method. - for (id, data) in def_generics.iter().skip(substs.len()) { - match data { - TypeOrConstParamData::TypeParamData(_) => { + for (id, _data) in def_generics.iter().skip(substs.len()) { + match id { + GenericParamId::TypeParamId(_) => { substs.push(self.table.new_type_var().cast(Interner)) } - TypeOrConstParamData::ConstParamData(_) => substs.push( - self.table - .new_const_var(self.db.const_param_ty(ConstParamId::from_unchecked(id))) - .cast(Interner), - ), + GenericParamId::ConstParamId(id) => { + substs.push(self.table.new_const_var(self.db.const_param_ty(id)).cast(Interner)) + } + // FIXME: create `new_lifetime_var` in infer + GenericParamId::LifetimeParamId(_) => substs.push(static_lifetime().cast(Interner)), } } assert_eq!(substs.len(), total_len); diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs index f5410ca6a14..fc7ed79f5cf 100644 --- a/crates/hir-ty/src/lib.rs +++ b/crates/hir-ty/src/lib.rs @@ -337,7 +337,7 @@ pub(crate) fn make_binders_with_count<T: HasInterner<Interner = Interner>>( generics: &Generics, value: T, ) -> Binders<T> { - let it = generics.iter_id_with_lt().take(count); + let it = generics.iter_id().take(count); Binders::new( VariableKinds::from_iter( diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index 453ac2fca78..854893fcee0 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -18,13 +18,13 @@ use chalk_ir::{ cast::Cast, fold::Shift, fold::TypeFoldable, interner::HasInterner, Mutability, Safety, }; -use either::Either; use hir_def::{ builtin_type::BuiltinType, data::adt::StructKind, expander::Expander, generics::{ - TypeOrConstParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget, + GenericParamData, TypeOrConstParamData, TypeParamProvenance, WherePredicate, + WherePredicateTypeTarget, }, lang_item::LangItem, nameres::MacroSubNs, @@ -354,13 +354,18 @@ impl<'a> TyLoweringContext<'a> { .filter(|(_, data)| { matches!( data, - TypeOrConstParamData::TypeParamData(data) + GenericParamData::TypeParamData(data) if data.provenance == TypeParamProvenance::ArgumentImplTrait ) }) .nth(idx as usize) .map_or(TyKind::Error, |(id, _)| { - TyKind::Placeholder(to_placeholder_idx(self.db, id)) + if let GenericParamId::TypeParamId(id) = id { + TyKind::Placeholder(to_placeholder_idx(self.db, id.into())) + } else { + // we just filtered them out + unreachable!("Unexpected lifetime or const argument"); + } }); param.intern(Interner) } else { @@ -837,7 +842,7 @@ impl<'a> TyLoweringContext<'a> { let ty_error = TyKind::Error.intern(Interner).cast(Interner); - let mut def_generic_iter = def_generics.iter_id_with_lt(); + let mut def_generic_iter = def_generics.iter_id(); let fill_self_params = || { for x in explicit_self_ty @@ -1732,9 +1737,9 @@ pub(crate) fn generic_defaults_query( let generic_params = generics(db.upcast(), def); let parent_start_idx = generic_params.len_self(); - let toc_iter = generic_params.iter().enumerate().map(|(idx, (id, p))| { + let defaults = Arc::from_iter(generic_params.iter().enumerate().map(|(idx, (id, p))| { match p { - TypeOrConstParamData::TypeParamData(p) => { + GenericParamData::TypeParamData(p) => { let mut ty = p.default.as_ref().map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t)); // Each default can only refer to previous parameters. @@ -1743,13 +1748,13 @@ pub(crate) fn generic_defaults_query( ty = fallback_bound_vars(ty, idx, parent_start_idx); crate::make_binders(db, &generic_params, ty.cast(Interner)) } - TypeOrConstParamData::ConstParamData(p) => { + GenericParamData::ConstParamData(p) => { + let GenericParamId::ConstParamId(id) = id else { + unreachable!("Unexpected lifetime or type argument") + }; + let mut val = p.default.as_ref().map_or_else( - || { - unknown_const_as_generic( - db.const_param_ty(ConstParamId::from_unchecked(id)), - ) - }, + || unknown_const_as_generic(db.const_param_ty(id.into())), |c| { let c = ctx.lower_const(c, ctx.lower_ty(&p.ty)); c.cast(Interner) @@ -1759,15 +1764,12 @@ pub(crate) fn generic_defaults_query( val = fallback_bound_vars(val, idx, parent_start_idx); make_binders(db, &generic_params, val) } + GenericParamData::LifetimeParamData(_) => { + // using static because it requires defaults + make_binders(db, &generic_params, static_lifetime().cast(Interner)) + } } - }); - - let lt_iter = generic_params - .iter_lt() - .enumerate() - .map(|_| make_binders(db, &generic_params, static_lifetime().cast(Interner))); - - let defaults = Arc::from_iter(toc_iter.chain(lt_iter)); + })); defaults } @@ -1782,8 +1784,9 @@ pub(crate) fn generic_defaults_recover( // we still need one default per parameter let defaults = Arc::from_iter(generic_params.iter_id().map(|id| { let val = match id { - Either::Left(_) => TyKind::Error.intern(Interner).cast(Interner), - Either::Right(id) => unknown_const_as_generic(db.const_param_ty(id)), + GenericParamId::TypeParamId(_) => TyKind::Error.intern(Interner).cast(Interner), + GenericParamId::ConstParamId(id) => unknown_const_as_generic(db.const_param_ty(id)), + GenericParamId::LifetimeParamId(_) => static_lifetime().cast(Interner), }; crate::make_binders(db, &generic_params, val) })); diff --git a/crates/hir-ty/src/mir/monomorphization.rs b/crates/hir-ty/src/mir/monomorphization.rs index 12ad67cdc45..d6557c3a816 100644 --- a/crates/hir-ty/src/mir/monomorphization.rs +++ b/crates/hir-ty/src/mir/monomorphization.rs @@ -184,8 +184,16 @@ impl Filler<'_> { self.generics .as_ref() .and_then(|it| it.iter().nth(b.index)) - .unwrap() - .0, + .and_then(|(id, _)| match id { + hir_def::GenericParamId::ConstParamId(id) => { + Some(hir_def::TypeOrConstParamId::from(id)) + } + hir_def::GenericParamId::TypeParamId(id) => { + Some(hir_def::TypeOrConstParamId::from(id)) + } + _ => None, + }) + .unwrap(), self.subst.clone(), ) })? diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs index 39e7bdd9623..cadb099c2b8 100644 --- a/crates/hir-ty/src/utils.rs +++ b/crates/hir-ty/src/utils.rs @@ -9,12 +9,11 @@ use chalk_ir::{ fold::{FallibleTypeFolder, Shift}, BoundVar, DebruijnIndex, }; -use either::Either; use hir_def::{ db::DefDatabase, generics::{ - GenericParams, LifetimeParamData, TypeOrConstParamData, TypeParamProvenance, - WherePredicate, WherePredicateTypeTarget, + GenericParamData, GenericParams, LifetimeParamData, TypeOrConstParamData, + TypeParamProvenance, WherePredicate, WherePredicateTypeTarget, }, lang_item::LangItem, resolver::{HasResolver, TypeNs}, @@ -271,81 +270,102 @@ pub(crate) struct Generics { } impl Generics { - pub(crate) fn iter_id(&self) -> impl Iterator<Item = Either<TypeParamId, ConstParamId>> + '_ { - self.iter().map(|(id, data)| match data { - TypeOrConstParamData::TypeParamData(_) => Either::Left(TypeParamId::from_unchecked(id)), - TypeOrConstParamData::ConstParamData(_) => { - Either::Right(ConstParamId::from_unchecked(id)) - } - }) + pub(crate) fn iter_id(&self) -> impl Iterator<Item = GenericParamId> + '_ { + self.iter().map(|(id, _)| id) } /// Iterator over types and const params of self, then parent. pub(crate) fn iter<'a>( &'a self, - ) -> impl DoubleEndedIterator<Item = (TypeOrConstParamId, &'a TypeOrConstParamData)> + 'a { - let to_toc_id = |it: &'a Generics| { - move |(local_id, p)| (TypeOrConstParamId { parent: it.def, local_id }, p) + ) -> impl DoubleEndedIterator<Item = (GenericParamId, GenericParamData)> + 'a { + let from_toc_id = |it: &'a Generics| { + move |(local_id, p): (_, &TypeOrConstParamData)| { + let id = TypeOrConstParamId { parent: it.def, local_id }; + match p { + TypeOrConstParamData::TypeParamData(p) => ( + GenericParamId::TypeParamId(TypeParamId::from_unchecked(id)), + GenericParamData::TypeParamData(p.clone()), + ), + TypeOrConstParamData::ConstParamData(p) => ( + GenericParamId::ConstParamId(ConstParamId::from_unchecked(id)), + GenericParamData::ConstParamData(p.clone()), + ), + } + } }; - self.params.iter().map(to_toc_id(self)).chain(self.iter_parent()) + + let from_lt_id = |it: &'a Generics| { + move |(local_id, p): (_, &LifetimeParamData)| { + ( + GenericParamId::LifetimeParamId(LifetimeParamId { parent: it.def, local_id }), + GenericParamData::LifetimeParamData(p.clone()), + ) + } + }; + + 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()) } /// Iterate over types and const params without parent params. pub(crate) fn iter_self<'a>( &'a self, - ) -> impl DoubleEndedIterator<Item = (TypeOrConstParamId, &'a TypeOrConstParamData)> + 'a { - let to_toc_id = |it: &'a Generics| { - move |(local_id, p)| (TypeOrConstParamId { parent: it.def, local_id }, p) + ) -> impl DoubleEndedIterator<Item = (GenericParamId, GenericParamData)> + 'a { + let from_toc_id = |it: &'a Generics| { + move |(local_id, p): (_, &TypeOrConstParamData)| { + let id = TypeOrConstParamId { parent: it.def, local_id }; + match p { + TypeOrConstParamData::TypeParamData(p) => ( + GenericParamId::TypeParamId(TypeParamId::from_unchecked(id)), + GenericParamData::TypeParamData(p.clone()), + ), + TypeOrConstParamData::ConstParamData(p) => ( + GenericParamId::ConstParamId(ConstParamId::from_unchecked(id)), + GenericParamData::ConstParamData(p.clone()), + ), + } + } }; - self.params.iter().map(to_toc_id(self)) - } - /// Iterator over types and const params of parent. - pub(crate) fn iter_parent( - &self, - ) -> impl DoubleEndedIterator<Item = (TypeOrConstParamId, &TypeOrConstParamData)> { - self.parent_generics().into_iter().flat_map(|it| { - let to_toc_id = - move |(local_id, p)| (TypeOrConstParamId { parent: it.def, local_id }, p); - it.params.iter().map(to_toc_id) - }) - } - - pub(crate) fn iter_id_with_lt(&self) -> impl Iterator<Item = GenericParamId> + '_ { - let toc_iter = self.iter().map(|(id, data)| match data { - TypeOrConstParamData::TypeParamData(_) => { - GenericParamId::TypeParamId(TypeParamId::from_unchecked(id)) - } - TypeOrConstParamData::ConstParamData(_) => { - GenericParamId::ConstParamId(ConstParamId::from_unchecked(id)) + let from_lt_id = |it: &'a Generics| { + move |(local_id, p): (_, &LifetimeParamData)| { + ( + GenericParamId::LifetimeParamId(LifetimeParamId { parent: it.def, local_id }), + GenericParamData::LifetimeParamData(p.clone()), + ) } - }); - let lt_iter = self.iter_lt().map(|(id, _)| GenericParamId::LifetimeParamId(id)); - - toc_iter.chain(lt_iter) - } - - pub(crate) fn iter_lt<'a>( - &'a self, - ) -> impl DoubleEndedIterator<Item = (LifetimeParamId, &'a LifetimeParamData)> + 'a { - self.iter_lt_self().chain(self.iter_lt_parent()) - } - - fn iter_lt_self<'a>( - &'a self, - ) -> impl DoubleEndedIterator<Item = (LifetimeParamId, &'a LifetimeParamData)> + 'a { - let to_id = |it: &'a Generics| { - move |(local_id, p)| (LifetimeParamId { parent: it.def, local_id }, p) }; - self.params.iter_lt().map(to_id(self)) + + self.params.iter().map(from_toc_id(self)).chain(self.params.iter_lt().map(from_lt_id(self))) } - fn iter_lt_parent( + /// Iterator over types and const params of parent. + pub(crate) fn iter_parent( &self, - ) -> impl DoubleEndedIterator<Item = (LifetimeParamId, &LifetimeParamData)> { + ) -> impl DoubleEndedIterator<Item = (GenericParamId, GenericParamData)> + '_ { self.parent_generics().into_iter().flat_map(|it| { - let to_id = move |(local_id, p)| (LifetimeParamId { parent: it.def, local_id }, p); - it.params.iter_lt().map(to_id) + let from_toc_id = move |(local_id, p): (_, &TypeOrConstParamData)| { + let id = TypeOrConstParamId { parent: it.def, local_id }; + match p { + TypeOrConstParamData::TypeParamData(p) => ( + GenericParamId::TypeParamId(TypeParamId::from_unchecked(id)), + GenericParamData::TypeParamData(p.clone()), + ), + TypeOrConstParamData::ConstParamData(p) => ( + GenericParamId::ConstParamId(ConstParamId::from_unchecked(id)), + GenericParamData::ConstParamData(p.clone()), + ), + } + }; + + let from_lt_id = move |(local_id, p): (_, &LifetimeParamData)| { + ( + GenericParamId::LifetimeParamId(LifetimeParamId { parent: it.def, local_id }), + GenericParamData::LifetimeParamData(p.clone()), + ) + }; + let lt_iter = it.params.iter_lt().map(from_lt_id); + it.params.iter().map(from_toc_id).chain(lt_iter) }) } @@ -437,7 +457,7 @@ impl Generics { ) -> Substitution { Substitution::from_iter( Interner, - self.iter_id_with_lt().enumerate().map(|(idx, id)| match id { + self.iter_id().enumerate().map(|(idx, id)| match id { GenericParamId::ConstParamId(id) => BoundVar::new(debruijn, idx) .to_const(Interner, db.const_param_ty(id)) .cast(Interner), @@ -456,12 +476,15 @@ impl Generics { Substitution::from_iter( Interner, self.iter_id().map(|id| match id { - Either::Left(id) => { + GenericParamId::TypeParamId(id) => { crate::to_placeholder_idx(db, id.into()).to_ty(Interner).cast(Interner) } - Either::Right(id) => crate::to_placeholder_idx(db, id.into()) - .to_const(Interner, db.const_param_ty(id)) + GenericParamId::ConstParamId(id) => crate::to_placeholder_idx(db, id.into()) + .to_const(Interner, db.const_param_ty(id.into())) .cast(Interner), + GenericParamId::LifetimeParamId(id) => { + crate::lt_to_placeholder_idx(db, id.into()).to_lifetime(Interner).cast(Interner) + } }), ) } |
