diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 9f5624eb0f1..c584a2c0850 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs @@ -75,14 +75,13 @@ fn callable_sig_from_fn_trait(&mut self, ty: &Ty, num_args: usize) -> Option<(Ve self.db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?; let mut arg_tys = vec![]; - let parameters = Substitution::builder(num_args) + let arg_ty = TyBuilder::tuple(num_args) .fill(repeat_with(|| { let arg = self.table.new_type_var(); arg_tys.push(arg.clone()); arg })) .build(); - let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner); let projection = { let b = TyBuilder::assoc_type_projection(self.db, output_assoc_type); diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs index c9219776bde..d55ae49005a 100644 --- a/crates/hir_ty/src/infer/path.rs +++ b/crates/hir_ty/src/infer/path.rs @@ -93,16 +93,13 @@ fn resolve_value_path( ValueNs::GenericParam(it) => return Some(self.db.const_param_ty(it)), }; - let ty = self.db.value_ty(typable); - // self_subst is just for the parent let parent_substs = self_subst.unwrap_or_else(|| Substitution::empty(&Interner)); let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); let substs = ctx.substs_from_path(path, typable, true); - let full_substs = Substitution::builder(substs.len(&Interner)) + let ty = TyBuilder::value_ty(self.db, typable) .use_parent_substs(&parent_substs) .fill(substs.interned(&Interner)[parent_substs.len(&Interner)..].iter().cloned()) .build(); - let ty = ty.subst(&full_substs); Some(ty) } diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index d2496db3ba4..a04b935ef9f 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs @@ -186,14 +186,11 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option { ); } } - Some( - Substitution::builder(tys.binders.len(&Interner)) - .fill( - vars.iter(&Interner) - .map(|v| table.resolve_ty_completely(v.assert_ty_ref(&Interner).clone())), - ) - .build(), - ) + Some(Substitution::from_iter( + &Interner, + vars.iter(&Interner) + .map(|v| table.resolve_ty_completely(v.assert_ty_ref(&Interner).clone())), + )) } #[derive(Clone, Debug)] diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 27ebb7b7cd3..f99b70f2b94 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs @@ -492,10 +492,6 @@ pub(crate) fn bound_vars(generic_params: &Generics, debruijn: DebruijnIndex) -> .map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)), ) } - - fn builder(param_count: usize) -> SubstsBuilder { - SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } - } } /// Return an index of a parameter in the generic type parameter list by it's id. @@ -503,52 +499,6 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option { generics(db.upcast(), id.parent).param_idx(id) } -#[derive(Debug, Clone)] -pub struct SubstsBuilder { - vec: Vec, - param_count: usize, -} - -impl SubstsBuilder { - pub fn build(self) -> Substitution { - assert_eq!(self.vec.len(), self.param_count); - Substitution::from_iter(&Interner, self.vec) - } - - pub fn push(mut self, ty: impl CastTo) -> Self { - self.vec.push(ty.cast(&Interner)); - self - } - - fn remaining(&self) -> usize { - self.param_count - self.vec.len() - } - - pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { - self.fill( - (starting_from..) - .map(|idx| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)), - ) - } - - pub fn fill_with_unknown(self) -> Self { - self.fill(iter::repeat(TyKind::Unknown.intern(&Interner))) - } - - pub fn fill(mut self, filler: impl Iterator>) -> Self { - self.vec.extend(filler.take(self.remaining()).casted(&Interner)); - assert_eq!(self.remaining(), 0); - self - } - - pub fn use_parent_substs(mut self, parent_substs: &Substitution) -> Self { - assert!(self.vec.is_empty()); - assert!(parent_substs.len(&Interner) <= self.param_count); - self.vec.extend(parent_substs.iter(&Interner).cloned()); - self - } -} - #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] pub struct Binders { pub num_binders: usize, @@ -921,6 +871,18 @@ pub fn build(self) -> Ty { } } +struct Tuple(usize); +impl TyBuilder { + pub fn tuple(size: usize) -> TyBuilder { + TyBuilder::new(Tuple(size), size) + } + + pub fn build(self) -> Ty { + let (Tuple(size), subst) = self.build_internal(); + TyKind::Tuple(size, subst).intern(&Interner) + } +} + impl TyBuilder { pub fn trait_ref(db: &dyn HirDatabase, trait_id: TraitId) -> TyBuilder { let generics = generics(db.upcast(), trait_id.into()); @@ -970,6 +932,10 @@ pub fn def_ty(db: &dyn HirDatabase, def: TyDefId) -> TyBuilder> { pub fn impl_self_ty(db: &dyn HirDatabase, def: hir_def::ImplId) -> TyBuilder> { TyBuilder::subst_binders(db.impl_self_ty(def)) } + + pub fn value_ty(db: &dyn HirDatabase, def: ValueTyDefId) -> TyBuilder> { + TyBuilder::subst_binders(db.value_ty(def)) + } } impl Ty {