mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
update make_binders
to include lifetimes in generics
adds a bunch of iter methods that include lifetimes
This commit is contained in:
parent
16493e301e
commit
e463a3e1cf
2 changed files with 65 additions and 10 deletions
|
@ -337,11 +337,23 @@ pub(crate) fn make_binders_with_count<T: HasInterner<Interner = Interner>>(
|
||||||
generics: &Generics,
|
generics: &Generics,
|
||||||
value: T,
|
value: T,
|
||||||
) -> Binders<T> {
|
) -> Binders<T> {
|
||||||
let it = generics.iter_id().take(count).map(|id| match id {
|
let it = generics.iter_id_with_lt().take(count);
|
||||||
Either::Left(_) => None,
|
|
||||||
Either::Right(id) => Some(db.const_param_ty(id)),
|
Binders::new(
|
||||||
});
|
VariableKinds::from_iter(
|
||||||
crate::make_type_and_const_binders(it, value)
|
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>>(
|
pub(crate) fn make_binders<T: HasInterner<Interner = Interner>>(
|
||||||
|
|
|
@ -19,7 +19,7 @@ use hir_def::{
|
||||||
lang_item::LangItem,
|
lang_item::LangItem,
|
||||||
resolver::{HasResolver, TypeNs},
|
resolver::{HasResolver, TypeNs},
|
||||||
type_ref::{TraitBoundModifier, TypeRef},
|
type_ref::{TraitBoundModifier, TypeRef},
|
||||||
ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId, ItemContainerId,
|
ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId, GenericParamId, ItemContainerId,
|
||||||
LifetimeParamId, Lookup, OpaqueInternableThing, TraitId, TypeAliasId, TypeOrConstParamId,
|
LifetimeParamId, Lookup, OpaqueInternableThing, TraitId, TypeAliasId, TypeOrConstParamId,
|
||||||
TypeParamId,
|
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.
|
/// Returns total number of generic parameters in scope, including those from parent.
|
||||||
pub(crate) fn len(&self) -> usize {
|
pub(crate) fn len(&self) -> usize {
|
||||||
let parent = self.parent_generics().map_or(0, Generics::len);
|
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
|
parent + child
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,11 +434,16 @@ impl Generics {
|
||||||
) -> Substitution {
|
) -> Substitution {
|
||||||
Substitution::from_iter(
|
Substitution::from_iter(
|
||||||
Interner,
|
Interner,
|
||||||
self.iter_id().enumerate().map(|(idx, id)| match id {
|
self.iter_id_with_lt().enumerate().map(|(idx, id)| match id {
|
||||||
Either::Left(_) => BoundVar::new(debruijn, idx).to_ty(Interner).cast(Interner),
|
GenericParamId::ConstParamId(id) => BoundVar::new(debruijn, idx)
|
||||||
Either::Right(id) => BoundVar::new(debruijn, idx)
|
|
||||||
.to_const(Interner, db.const_param_ty(id))
|
.to_const(Interner, db.const_param_ty(id))
|
||||||
.cast(Interner),
|
.cast(Interner),
|
||||||
|
GenericParamId::TypeParamId(_) => {
|
||||||
|
BoundVar::new(debruijn, idx).to_ty(Interner).cast(Interner)
|
||||||
|
}
|
||||||
|
GenericParamId::LifetimeParamId(_) => {
|
||||||
|
BoundVar::new(debruijn, idx).to_lifetime(Interner).cast(Interner)
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue