Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/builder.rs')
-rw-r--r--crates/hir-ty/src/builder.rs78
1 files changed, 39 insertions, 39 deletions
diff --git a/crates/hir-ty/src/builder.rs b/crates/hir-ty/src/builder.rs
index 76d9c60f6f..77d15a73af 100644
--- a/crates/hir-ty/src/builder.rs
+++ b/crates/hir-ty/src/builder.rs
@@ -3,21 +3,21 @@
use std::iter;
use chalk_ir::{
+ AdtId, DebruijnIndex, Scalar,
cast::{Cast, CastTo, Caster},
fold::TypeFoldable,
interner::HasInterner,
- AdtId, DebruijnIndex, Scalar,
};
use hir_def::{
- builtin_type::BuiltinType, DefWithBodyId, GenericDefId, GenericParamId, TraitId, TypeAliasId,
+ DefWithBodyId, GenericDefId, GenericParamId, TraitId, TypeAliasId, builtin_type::BuiltinType,
};
use smallvec::SmallVec;
use crate::{
- consteval::unknown_const_as_generic, db::HirDatabase, error_lifetime, generics::generics,
- infer::unify::InferenceTable, primitive, to_assoc_type_id, to_chalk_trait_id, Binders,
- BoundVar, CallableSig, GenericArg, GenericArgData, Interner, ProjectionTy, Substitution,
- TraitRef, Ty, TyDefId, TyExt, TyKind,
+ Binders, BoundVar, CallableSig, GenericArg, GenericArgData, Interner, ProjectionTy,
+ Substitution, TraitRef, Ty, TyDefId, TyExt, TyKind, consteval::unknown_const_as_generic,
+ db::HirDatabase, error_lifetime, generics::generics, infer::unify::InferenceTable, primitive,
+ to_assoc_type_id, to_chalk_trait_id,
};
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -76,7 +76,7 @@ impl<D> TyBuilder<D> {
}
let subst = Substitution::from_iter(
Interner,
- self.vec.into_iter().chain(self.parent_subst.iter(Interner).cloned()),
+ self.parent_subst.iter(Interner).cloned().chain(self.vec),
);
(self.data, subst)
}
@@ -209,12 +209,12 @@ impl TyBuilder<()> {
}
pub fn placeholder_subst(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substitution {
- let params = generics(db.upcast(), def.into());
+ let params = generics(db, def.into());
params.placeholder_subst(db)
}
pub fn unknown_subst(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substitution {
- let params = generics(db.upcast(), def.into());
+ let params = generics(db, def.into());
Substitution::from_iter(
Interner,
params.iter_id().map(|id| match id {
@@ -233,7 +233,7 @@ impl TyBuilder<()> {
def: impl Into<GenericDefId>,
parent_subst: Option<Substitution>,
) -> TyBuilder<()> {
- let generics = generics(db.upcast(), def.into());
+ let generics = generics(db, def.into());
assert!(generics.parent_generics().is_some() == parent_subst.is_some());
let params = generics
.iter_self()
@@ -259,11 +259,10 @@ impl TyBuilder<()> {
/// This method prepopulates the builder with placeholder substitution of `parent`, so you
/// should only push exactly 3 `GenericArg`s before building.
pub fn subst_for_coroutine(db: &dyn HirDatabase, parent: DefWithBodyId) -> TyBuilder<()> {
- let parent_subst = parent
- .as_generic_def_id(db.upcast())
- .map(|p| generics(db.upcast(), p).placeholder_subst(db));
+ let parent_subst =
+ parent.as_generic_def_id(db).map(|p| generics(db, p).placeholder_subst(db));
// These represent resume type, yield type, and return type of coroutine.
- let params = std::iter::repeat(ParamKind::Type).take(3).collect();
+ let params = std::iter::repeat_n(ParamKind::Type, 3).collect();
TyBuilder::new((), params, parent_subst)
}
@@ -274,13 +273,15 @@ impl TyBuilder<()> {
) -> Substitution {
let sig_ty = sig_ty.cast(Interner);
let self_subst = iter::once(&sig_ty);
- let Some(parent) = parent.as_generic_def_id(db.upcast()) else {
+ let Some(parent) = parent.as_generic_def_id(db) else {
return Substitution::from_iter(Interner, self_subst);
};
Substitution::from_iter(
Interner,
- self_subst
- .chain(generics(db.upcast(), parent).placeholder_subst(db).iter(Interner))
+ generics(db, parent)
+ .placeholder_subst(db)
+ .iter(Interner)
+ .chain(self_subst)
.cloned()
.collect::<Vec<_>>(),
)
@@ -305,29 +306,28 @@ impl TyBuilder<hir_def::AdtId> {
// Note that we're building ADT, so we never have parent generic parameters.
let defaults = db.generic_defaults(self.data.into());
- for default_ty in &defaults[self.vec.len()..] {
- // NOTE(skip_binders): we only check if the arg type is error type.
- if let Some(x) = default_ty.skip_binders().ty(Interner) {
- if x.is_unknown() {
- self.vec.push(fallback().cast(Interner));
- continue;
+ if let Some(defaults) = defaults.get(self.vec.len()..) {
+ for default_ty in defaults {
+ // NOTE(skip_binders): we only check if the arg type is error type.
+ if let Some(x) = default_ty.skip_binders().ty(Interner) {
+ if x.is_unknown() {
+ self.vec.push(fallback().cast(Interner));
+ continue;
+ }
}
+ // Each default can only depend on the previous parameters.
+ self.vec.push(default_ty.clone().substitute(Interner, &*self.vec).cast(Interner));
}
- // Each default can only depend on the previous parameters.
- let subst_so_far = Substitution::from_iter(
- Interner,
- self.vec
- .iter()
- .cloned()
- .chain(self.param_kinds[self.vec.len()..].iter().map(|it| match it {
- ParamKind::Type => TyKind::Error.intern(Interner).cast(Interner),
- ParamKind::Lifetime => error_lifetime().cast(Interner),
- ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
- }))
- .take(self.param_kinds.len()),
- );
- self.vec.push(default_ty.clone().substitute(Interner, &subst_so_far).cast(Interner));
}
+
+ // The defaults may be missing if no param has default, so fill that.
+ let filler = self.param_kinds[self.vec.len()..].iter().map(|x| match x {
+ ParamKind::Type => fallback().cast(Interner),
+ ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
+ ParamKind::Lifetime => error_lifetime().cast(Interner),
+ });
+ self.vec.extend(filler.casted(Interner));
+
self
}
@@ -340,7 +340,7 @@ impl TyBuilder<hir_def::AdtId> {
pub struct Tuple(usize);
impl TyBuilder<Tuple> {
pub fn tuple(size: usize) -> TyBuilder<Tuple> {
- TyBuilder::new(Tuple(size), iter::repeat(ParamKind::Type).take(size).collect(), None)
+ TyBuilder::new(Tuple(size), std::iter::repeat_n(ParamKind::Type, size).collect(), None)
}
pub fn build(self) -> Ty {
@@ -356,7 +356,7 @@ impl TyBuilder<Tuple> {
let elements = elements.into_iter();
let len = elements.len();
let mut b =
- TyBuilder::new(Tuple(len), iter::repeat(ParamKind::Type).take(len).collect(), None);
+ TyBuilder::new(Tuple(len), std::iter::repeat_n(ParamKind::Type, len).collect(), None);
for e in elements {
b = b.push(e);
}