aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/hir_ty/src/infer/expr.rs3
-rw-r--r--crates/hir_ty/src/infer/path.rs5
-rw-r--r--crates/hir_ty/src/infer/unify.rs13
-rw-r--r--crates/hir_ty/src/lib.rs66
4 files changed, 23 insertions, 64 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 9f5624eb0..c584a2c08 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -75,14 +75,13 @@ impl<'a> InferenceContext<'a> {
75 self.db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?; 75 self.db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?;
76 76
77 let mut arg_tys = vec![]; 77 let mut arg_tys = vec![];
78 let parameters = Substitution::builder(num_args) 78 let arg_ty = TyBuilder::tuple(num_args)
79 .fill(repeat_with(|| { 79 .fill(repeat_with(|| {
80 let arg = self.table.new_type_var(); 80 let arg = self.table.new_type_var();
81 arg_tys.push(arg.clone()); 81 arg_tys.push(arg.clone());
82 arg 82 arg
83 })) 83 }))
84 .build(); 84 .build();
85 let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner);
86 85
87 let projection = { 86 let projection = {
88 let b = TyBuilder::assoc_type_projection(self.db, output_assoc_type); 87 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 c9219776b..d55ae4900 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -93,16 +93,13 @@ impl<'a> InferenceContext<'a> {
93 ValueNs::GenericParam(it) => return Some(self.db.const_param_ty(it)), 93 ValueNs::GenericParam(it) => return Some(self.db.const_param_ty(it)),
94 }; 94 };
95 95
96 let ty = self.db.value_ty(typable);
97 // self_subst is just for the parent
98 let parent_substs = self_subst.unwrap_or_else(|| Substitution::empty(&Interner)); 96 let parent_substs = self_subst.unwrap_or_else(|| Substitution::empty(&Interner));
99 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); 97 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
100 let substs = ctx.substs_from_path(path, typable, true); 98 let substs = ctx.substs_from_path(path, typable, true);
101 let full_substs = Substitution::builder(substs.len(&Interner)) 99 let ty = TyBuilder::value_ty(self.db, typable)
102 .use_parent_substs(&parent_substs) 100 .use_parent_substs(&parent_substs)
103 .fill(substs.interned(&Interner)[parent_substs.len(&Interner)..].iter().cloned()) 101 .fill(substs.interned(&Interner)[parent_substs.len(&Interner)..].iter().cloned())
104 .build(); 102 .build();
105 let ty = ty.subst(&full_substs);
106 Some(ty) 103 Some(ty)
107 } 104 }
108 105
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index d2496db3b..a04b935ef 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<Substitution> {
186 ); 186 );
187 } 187 }
188 } 188 }
189 Some( 189 Some(Substitution::from_iter(
190 Substitution::builder(tys.binders.len(&Interner)) 190 &Interner,
191 .fill( 191 vars.iter(&Interner)
192 vars.iter(&Interner) 192 .map(|v| table.resolve_ty_completely(v.assert_ty_ref(&Interner).clone())),
193 .map(|v| table.resolve_ty_completely(v.assert_ty_ref(&Interner).clone())), 193 ))
194 )
195 .build(),
196 )
197} 194}
198 195
199#[derive(Clone, Debug)] 196#[derive(Clone, Debug)]
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 27ebb7b7c..f99b70f2b 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -492,10 +492,6 @@ impl Substitution {
492 .map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)), 492 .map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)),
493 ) 493 )
494 } 494 }
495
496 fn builder(param_count: usize) -> SubstsBuilder {
497 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count }
498 }
499} 495}
500 496
501/// Return an index of a parameter in the generic type parameter list by it's id. 497/// 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<usize> {
503 generics(db.upcast(), id.parent).param_idx(id) 499 generics(db.upcast(), id.parent).param_idx(id)
504} 500}
505 501
506#[derive(Debug, Clone)]
507pub struct SubstsBuilder {
508 vec: Vec<GenericArg>,
509 param_count: usize,
510}
511
512impl SubstsBuilder {
513 pub fn build(self) -> Substitution {
514 assert_eq!(self.vec.len(), self.param_count);
515 Substitution::from_iter(&Interner, self.vec)
516 }
517
518 pub fn push(mut self, ty: impl CastTo<GenericArg>) -> Self {
519 self.vec.push(ty.cast(&Interner));
520 self
521 }
522
523 fn remaining(&self) -> usize {
524 self.param_count - self.vec.len()
525 }
526
527 pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self {
528 self.fill(
529 (starting_from..)
530 .map(|idx| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)),
531 )
532 }
533
534 pub fn fill_with_unknown(self) -> Self {
535 self.fill(iter::repeat(TyKind::Unknown.intern(&Interner)))
536 }
537
538 pub fn fill(mut self, filler: impl Iterator<Item = impl CastTo<GenericArg>>) -> Self {
539 self.vec.extend(filler.take(self.remaining()).casted(&Interner));
540 assert_eq!(self.remaining(), 0);
541 self
542 }
543
544 pub fn use_parent_substs(mut self, parent_substs: &Substitution) -> Self {
545 assert!(self.vec.is_empty());
546 assert!(parent_substs.len(&Interner) <= self.param_count);
547 self.vec.extend(parent_substs.iter(&Interner).cloned());
548 self
549 }
550}
551
552#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] 502#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
553pub struct Binders<T> { 503pub struct Binders<T> {
554 pub num_binders: usize, 504 pub num_binders: usize,
@@ -921,6 +871,18 @@ impl TyBuilder<hir_def::AdtId> {
921 } 871 }
922} 872}
923 873
874struct Tuple(usize);
875impl TyBuilder<Tuple> {
876 pub fn tuple(size: usize) -> TyBuilder<Tuple> {
877 TyBuilder::new(Tuple(size), size)
878 }
879
880 pub fn build(self) -> Ty {
881 let (Tuple(size), subst) = self.build_internal();
882 TyKind::Tuple(size, subst).intern(&Interner)
883 }
884}
885
924impl TyBuilder<TraitId> { 886impl TyBuilder<TraitId> {
925 pub fn trait_ref(db: &dyn HirDatabase, trait_id: TraitId) -> TyBuilder<TraitId> { 887 pub fn trait_ref(db: &dyn HirDatabase, trait_id: TraitId) -> TyBuilder<TraitId> {
926 let generics = generics(db.upcast(), trait_id.into()); 888 let generics = generics(db.upcast(), trait_id.into());
@@ -970,6 +932,10 @@ impl TyBuilder<Binders<Ty>> {
970 pub fn impl_self_ty(db: &dyn HirDatabase, def: hir_def::ImplId) -> TyBuilder<Binders<Ty>> { 932 pub fn impl_self_ty(db: &dyn HirDatabase, def: hir_def::ImplId) -> TyBuilder<Binders<Ty>> {
971 TyBuilder::subst_binders(db.impl_self_ty(def)) 933 TyBuilder::subst_binders(db.impl_self_ty(def))
972 } 934 }
935
936 pub fn value_ty(db: &dyn HirDatabase, def: ValueTyDefId) -> TyBuilder<Binders<Ty>> {
937 TyBuilder::subst_binders(db.value_ty(def))
938 }
973} 939}
974 940
975impl Ty { 941impl Ty {