about summary refs log tree commit diff
diff options
context:
space:
mode:
authordfireBird <me@dfirebird.dev>2024-03-08 18:00:07 +0530
committerdfireBird <me@dfirebird.dev>2024-03-18 17:18:08 +0530
commite463a3e1cf5041581bdc8ede2488d60a1ef638ae (patch)
tree8ae6d1a6aeac447cde800f3661388a3d9a86cfa5
parent16493e301ee6eca66ce8806c2e92139e7a964193 (diff)
downloadrust-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.rs22
-rw-r--r--crates/hir-ty/src/utils.rs53
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)
+                }
             }),
         )
     }