Skip to content

Commit e463a3e

Browse files
committed
update make_binders to include lifetimes in generics
adds a bunch of iter methods that include lifetimes
1 parent 16493e3 commit e463a3e

File tree

2 files changed

+65
-10
lines changed

2 files changed

+65
-10
lines changed

crates/hir-ty/src/lib.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -337,11 +337,23 @@ pub(crate) fn make_binders_with_count<T: HasInterner<Interner = Interner>>(
337337
generics: &Generics,
338338
value: T,
339339
) -> Binders<T> {
340-
let it = generics.iter_id().take(count).map(|id| match id {
341-
Either::Left(_) => None,
342-
Either::Right(id) => Some(db.const_param_ty(id)),
343-
});
344-
crate::make_type_and_const_binders(it, value)
340+
let it = generics.iter_id_with_lt().take(count);
341+
342+
Binders::new(
343+
VariableKinds::from_iter(
344+
Interner,
345+
it.map(|x| match x {
346+
hir_def::GenericParamId::ConstParamId(id) => {
347+
chalk_ir::VariableKind::Const(db.const_param_ty(id))
348+
}
349+
hir_def::GenericParamId::TypeParamId(_) => {
350+
chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)
351+
}
352+
hir_def::GenericParamId::LifetimeParamId(_) => chalk_ir::VariableKind::Lifetime,
353+
}),
354+
),
355+
value,
356+
)
345357
}
346358

347359
pub(crate) fn make_binders<T: HasInterner<Interner = Interner>>(

crates/hir-ty/src/utils.rs

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use hir_def::{
1919
lang_item::LangItem,
2020
resolver::{HasResolver, TypeNs},
2121
type_ref::{TraitBoundModifier, TypeRef},
22-
ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId, ItemContainerId,
22+
ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId, GenericParamId, ItemContainerId,
2323
LifetimeParamId, Lookup, OpaqueInternableThing, TraitId, TypeAliasId, TypeOrConstParamId,
2424
TypeParamId,
2525
};
@@ -311,10 +311,48 @@ impl Generics {
311311
})
312312
}
313313

314+
pub(crate) fn iter_id_with_lt(&self) -> impl Iterator<Item = GenericParamId> + '_ {
315+
let toc_iter = self.iter().map(|(id, data)| match data {
316+
TypeOrConstParamData::TypeParamData(_) => {
317+
GenericParamId::TypeParamId(TypeParamId::from_unchecked(id))
318+
}
319+
TypeOrConstParamData::ConstParamData(_) => {
320+
GenericParamId::ConstParamId(ConstParamId::from_unchecked(id))
321+
}
322+
});
323+
let lt_iter = self.iter_lt().map(|(id, _)| GenericParamId::LifetimeParamId(id));
324+
325+
toc_iter.chain(lt_iter)
326+
}
327+
328+
pub(crate) fn iter_lt<'a>(
329+
&'a self,
330+
) -> impl DoubleEndedIterator<Item = (LifetimeParamId, &'a LifetimeParamData)> + 'a {
331+
self.iter_lt_self().chain(self.iter_lt_parent())
332+
}
333+
334+
fn iter_lt_self<'a>(
335+
&'a self,
336+
) -> impl DoubleEndedIterator<Item = (LifetimeParamId, &'a LifetimeParamData)> + 'a {
337+
let to_id = |it: &'a Generics| {
338+
move |(local_id, p)| (LifetimeParamId { parent: it.def, local_id }, p)
339+
};
340+
self.params.iter_lt().map(to_id(self))
341+
}
342+
343+
fn iter_lt_parent(
344+
&self,
345+
) -> impl DoubleEndedIterator<Item = (LifetimeParamId, &LifetimeParamData)> {
346+
self.parent_generics().into_iter().flat_map(|it| {
347+
let to_id = move |(local_id, p)| (LifetimeParamId { parent: it.def, local_id }, p);
348+
it.params.iter_lt().map(to_id)
349+
})
350+
}
351+
314352
/// Returns total number of generic parameters in scope, including those from parent.
315353
pub(crate) fn len(&self) -> usize {
316354
let parent = self.parent_generics().map_or(0, Generics::len);
317-
let child = self.params.type_or_consts.len();
355+
let child = self.params.type_or_consts.len() + self.params.lifetimes.len();
318356
parent + child
319357
}
320358

@@ -396,11 +434,16 @@ impl Generics {
396434
) -> Substitution {
397435
Substitution::from_iter(
398436
Interner,
399-
self.iter_id().enumerate().map(|(idx, id)| match id {
400-
Either::Left(_) => BoundVar::new(debruijn, idx).to_ty(Interner).cast(Interner),
401-
Either::Right(id) => BoundVar::new(debruijn, idx)
437+
self.iter_id_with_lt().enumerate().map(|(idx, id)| match id {
438+
GenericParamId::ConstParamId(id) => BoundVar::new(debruijn, idx)
402439
.to_const(Interner, db.const_param_ty(id))
403440
.cast(Interner),
441+
GenericParamId::TypeParamId(_) => {
442+
BoundVar::new(debruijn, idx).to_ty(Interner).cast(Interner)
443+
}
444+
GenericParamId::LifetimeParamId(_) => {
445+
BoundVar::new(debruijn, idx).to_lifetime(Interner).cast(Interner)
446+
}
404447
}),
405448
)
406449
}

0 commit comments

Comments
 (0)