diff options
| author | dfireBird <me@dfirebird.dev> | 2024-03-08 18:00:07 +0530 |
|---|---|---|
| committer | dfireBird <me@dfirebird.dev> | 2024-03-18 17:18:08 +0530 |
| commit | e463a3e1cf5041581bdc8ede2488d60a1ef638ae (patch) | |
| tree | 8ae6d1a6aeac447cde800f3661388a3d9a86cfa5 | |
| parent | 16493e301ee6eca66ce8806c2e92139e7a964193 (diff) | |
| download | rust-e463a3e1cf5041581bdc8ede2488d60a1ef638ae.tar.gz rust-e463a3e1cf5041581bdc8ede2488d60a1ef638ae.zip | |
update `make_binders` to include lifetimes in generics
adds a bunch of iter methods that include lifetimes
| -rw-r--r-- | crates/hir-ty/src/lib.rs | 22 | ||||
| -rw-r--r-- | crates/hir-ty/src/utils.rs | 53 |
2 files changed, 65 insertions, 10 deletions
diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs index accf306dde0..97a8f8660a4 100644 --- a/crates/hir-ty/src/lib.rs +++ b/crates/hir-ty/src/lib.rs @@ -337,11 +337,23 @@ pub(crate) fn make_binders_with_count<T: HasInterner<Interner = Interner>>( generics: &Generics, value: T, ) -> Binders<T> { - let it = generics.iter_id().take(count).map(|id| match id { - Either::Left(_) => None, - Either::Right(id) => Some(db.const_param_ty(id)), - }); - crate::make_type_and_const_binders(it, value) + let it = generics.iter_id_with_lt().take(count); + + Binders::new( + VariableKinds::from_iter( + Interner, + it.map(|x| match x { + hir_def::GenericParamId::ConstParamId(id) => { + chalk_ir::VariableKind::Const(db.const_param_ty(id)) + } + hir_def::GenericParamId::TypeParamId(_) => { + chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General) + } + hir_def::GenericParamId::LifetimeParamId(_) => chalk_ir::VariableKind::Lifetime, + }), + ), + value, + ) } pub(crate) fn make_binders<T: HasInterner<Interner = Interner>>( diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs index f45fe863df1..5e084ffb08b 100644 --- a/crates/hir-ty/src/utils.rs +++ b/crates/hir-ty/src/utils.rs @@ -19,7 +19,7 @@ use hir_def::{ lang_item::LangItem, resolver::{HasResolver, TypeNs}, type_ref::{TraitBoundModifier, TypeRef}, - ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId, ItemContainerId, + ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId, GenericParamId, ItemContainerId, LifetimeParamId, Lookup, OpaqueInternableThing, TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, }; @@ -311,10 +311,48 @@ impl Generics { }) } + 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 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)) + } + + fn iter_lt_parent( + &self, + ) -> impl DoubleEndedIterator<Item = (LifetimeParamId, &LifetimeParamData)> { + 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) + }) + } + /// Returns total number of generic parameters in scope, including those from parent. pub(crate) fn len(&self) -> usize { let parent = self.parent_generics().map_or(0, Generics::len); - let child = self.params.type_or_consts.len(); + let child = self.params.type_or_consts.len() + self.params.lifetimes.len(); parent + child } @@ -396,11 +434,16 @@ impl Generics { ) -> Substitution { Substitution::from_iter( Interner, - self.iter_id().enumerate().map(|(idx, id)| match id { - Either::Left(_) => BoundVar::new(debruijn, idx).to_ty(Interner).cast(Interner), - Either::Right(id) => BoundVar::new(debruijn, idx) + self.iter_id_with_lt().enumerate().map(|(idx, id)| match id { + GenericParamId::ConstParamId(id) => BoundVar::new(debruijn, idx) .to_const(Interner, db.const_param_ty(id)) .cast(Interner), + GenericParamId::TypeParamId(_) => { + BoundVar::new(debruijn, idx).to_ty(Interner).cast(Interner) + } + GenericParamId::LifetimeParamId(_) => { + BoundVar::new(debruijn, idx).to_lifetime(Interner).cast(Interner) + } }), ) } |
