aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2021-04-01 20:04:02 +0100
committerFlorian Diebold <[email protected]>2021-04-03 10:17:13 +0100
commite480d81988fc0c0e4f80f1c54058b95b9aaf1ebf (patch)
tree079dabc4e0de72e30d2bd04bd50427ff6950b348 /crates/hir_ty/src/infer
parent327f3a0a3017e047be58b8312f8bf3ac690db3fd (diff)
Introduce `GenericArg` like in Chalk
Plus some more adaptations to Substitution. Lots of `assert_ty_ref` that we should revisit when introducing lifetime/const parameters.
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r--crates/hir_ty/src/infer/coerce.rs2
-rw-r--r--crates/hir_ty/src/infer/expr.rs24
-rw-r--r--crates/hir_ty/src/infer/pat.rs17
-rw-r--r--crates/hir_ty/src/infer/path.rs6
-rw-r--r--crates/hir_ty/src/infer/unify.rs55
5 files changed, 58 insertions, 46 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 9c62932b1..8f7322b36 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -100,7 +100,7 @@ impl<'a> InferenceContext<'a> {
100 }, 100 },
101 101
102 (TyKind::Closure(.., substs), TyKind::Function { .. }) => { 102 (TyKind::Closure(.., substs), TyKind::Function { .. }) => {
103 from_ty = substs[0].clone(); 103 from_ty = substs.at(&Interner, 0).assert_ty_ref(&Interner).clone();
104 } 104 }
105 105
106 _ => {} 106 _ => {}
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 25ab3ea4c..b99b6cd21 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -266,7 +266,7 @@ impl<'a> InferenceContext<'a> {
266 let sig_ty = TyKind::Function(FnPointer { 266 let sig_ty = TyKind::Function(FnPointer {
267 num_args: sig_tys.len() - 1, 267 num_args: sig_tys.len() - 1,
268 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, 268 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
269 substs: Substitution(sig_tys.clone().into()), 269 substs: Substitution::from_iter(&Interner, sig_tys.clone()),
270 }) 270 })
271 .intern(&Interner); 271 .intern(&Interner);
272 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); 272 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();
@@ -406,7 +406,7 @@ impl<'a> InferenceContext<'a> {
406 406
407 self.unify(&ty, &expected.ty); 407 self.unify(&ty, &expected.ty);
408 408
409 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 409 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
410 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); 410 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
411 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); 411 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
412 for field in fields.iter() { 412 for field in fields.iter() {
@@ -456,9 +456,13 @@ impl<'a> InferenceContext<'a> {
456 .unwrap_or(true) 456 .unwrap_or(true)
457 }; 457 };
458 match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) { 458 match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) {
459 TyKind::Tuple(_, substs) => { 459 TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| {
460 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) 460 substs
461 } 461 .interned(&Interner)
462 .get(idx)
463 .map(|a| a.assert_ty_ref(&Interner))
464 .cloned()
465 }),
462 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { 466 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
463 let local_id = self.db.struct_data(*s).variant_data.field(name)?; 467 let local_id = self.db.struct_data(*s).variant_data.field(name)?;
464 let field = FieldId { parent: (*s).into(), local_id }; 468 let field = FieldId { parent: (*s).into(), local_id };
@@ -635,7 +639,7 @@ impl<'a> InferenceContext<'a> {
635 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); 639 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
636 match (range_type, lhs_ty, rhs_ty) { 640 match (range_type, lhs_ty, rhs_ty) {
637 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 641 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
638 Some(adt) => Ty::adt_ty(adt, Substitution::empty()), 642 Some(adt) => Ty::adt_ty(adt, Substitution::empty(&Interner)),
639 None => self.err_ty(), 643 None => self.err_ty(),
640 }, 644 },
641 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 645 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
@@ -694,8 +698,8 @@ impl<'a> InferenceContext<'a> {
694 Expr::Tuple { exprs } => { 698 Expr::Tuple { exprs } => {
695 let mut tys = match expected.ty.interned(&Interner) { 699 let mut tys = match expected.ty.interned(&Interner) {
696 TyKind::Tuple(_, substs) => substs 700 TyKind::Tuple(_, substs) => substs
697 .iter() 701 .iter(&Interner)
698 .cloned() 702 .map(|a| a.assert_ty_ref(&Interner).clone())
699 .chain(repeat_with(|| self.table.new_type_var())) 703 .chain(repeat_with(|| self.table.new_type_var()))
700 .take(exprs.len()) 704 .take(exprs.len())
701 .collect::<Vec<_>>(), 705 .collect::<Vec<_>>(),
@@ -706,7 +710,7 @@ impl<'a> InferenceContext<'a> {
706 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 710 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
707 } 711 }
708 712
709 TyKind::Tuple(tys.len(), Substitution(tys.into())).intern(&Interner) 713 TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner)
710 } 714 }
711 Expr::Array(array) => { 715 Expr::Array(array) => {
712 let elem_ty = match expected.ty.interned(&Interner) { 716 let elem_ty = match expected.ty.interned(&Interner) {
@@ -953,7 +957,7 @@ impl<'a> InferenceContext<'a> {
953 substs.push(self.err_ty()); 957 substs.push(self.err_ty());
954 } 958 }
955 assert_eq!(substs.len(), total_len); 959 assert_eq!(substs.len(), total_len);
956 Substitution(substs.into()) 960 Substitution::from_iter(&Interner, substs)
957 } 961 }
958 962
959 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 963 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 474363709..f1316415f 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -35,7 +35,7 @@ impl<'a> InferenceContext<'a> {
35 } 35 }
36 self.unify(&ty, expected); 36 self.unify(&ty, expected);
37 37
38 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 38 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
39 39
40 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 40 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
41 let (pre, post) = match ellipsis { 41 let (pre, post) = match ellipsis {
@@ -74,7 +74,7 @@ impl<'a> InferenceContext<'a> {
74 74
75 self.unify(&ty, expected); 75 self.unify(&ty, expected);
76 76
77 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 77 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
78 78
79 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 79 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
80 for subpat in subpats { 80 for subpat in subpats {
@@ -134,7 +134,8 @@ impl<'a> InferenceContext<'a> {
134 }; 134 };
135 let n_uncovered_patterns = expectations.len().saturating_sub(args.len()); 135 let n_uncovered_patterns = expectations.len().saturating_sub(args.len());
136 let err_ty = self.err_ty(); 136 let err_ty = self.err_ty();
137 let mut expectations_iter = expectations.iter().chain(repeat(&err_ty)); 137 let mut expectations_iter =
138 expectations.iter().map(|a| a.assert_ty_ref(&Interner)).chain(repeat(&err_ty));
138 let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm); 139 let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm);
139 140
140 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len()); 141 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len());
@@ -142,7 +143,8 @@ impl<'a> InferenceContext<'a> {
142 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); 143 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
143 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); 144 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
144 145
145 TyKind::Tuple(inner_tys.len(), Substitution(inner_tys.into())).intern(&Interner) 146 TyKind::Tuple(inner_tys.len(), Substitution::from_iter(&Interner, inner_tys))
147 .intern(&Interner)
146 } 148 }
147 Pat::Or(ref pats) => { 149 Pat::Or(ref pats) => {
148 if let Some((first_pat, rest)) = pats.split_first() { 150 if let Some((first_pat, rest)) = pats.split_first() {
@@ -236,9 +238,10 @@ impl<'a> InferenceContext<'a> {
236 Pat::Box { inner } => match self.resolve_boxed_box() { 238 Pat::Box { inner } => match self.resolve_boxed_box() {
237 Some(box_adt) => { 239 Some(box_adt) => {
238 let (inner_ty, alloc_ty) = match expected.as_adt() { 240 let (inner_ty, alloc_ty) = match expected.as_adt() {
239 Some((adt, subst)) if adt == box_adt => { 241 Some((adt, subst)) if adt == box_adt => (
240 (subst[0].clone(), subst.get(1).cloned()) 242 subst.at(&Interner, 0).assert_ty_ref(&Interner).clone(),
241 } 243 subst.interned(&Interner).get(1).and_then(|a| a.ty(&Interner).cloned()),
244 ),
242 _ => (self.result.standard_types.unknown.clone(), None), 245 _ => (self.result.standard_types.unknown.clone(), None),
243 }; 246 };
244 247
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs
index 717738789..b96391776 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -97,12 +97,12 @@ impl<'a> InferenceContext<'a> {
97 97
98 let ty = self.db.value_ty(typable); 98 let ty = self.db.value_ty(typable);
99 // self_subst is just for the parent 99 // self_subst is just for the parent
100 let parent_substs = self_subst.unwrap_or_else(Substitution::empty); 100 let parent_substs = self_subst.unwrap_or_else(|| Substitution::empty(&Interner));
101 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); 101 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
102 let substs = ctx.substs_from_path(path, typable, true); 102 let substs = ctx.substs_from_path(path, typable, true);
103 let full_substs = Substitution::builder(substs.len()) 103 let full_substs = Substitution::builder(substs.len(&Interner))
104 .use_parent_substs(&parent_substs) 104 .use_parent_substs(&parent_substs)
105 .fill(substs.0[parent_substs.len()..].iter().cloned()) 105 .fill(substs.interned(&Interner)[parent_substs.len(&Interner)..].iter().cloned())
106 .build(); 106 .build();
107 let ty = ty.subst(&full_substs); 107 let ty = ty.subst(&full_substs);
108 Some(ty) 108 Some(ty)
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 5ea4b7481..0efc62e53 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -129,29 +129,28 @@ impl<T> Canonicalized<T> {
129 solution: Canonical<Substitution>, 129 solution: Canonical<Substitution>,
130 ) { 130 ) {
131 // the solution may contain new variables, which we need to convert to new inference vars 131 // the solution may contain new variables, which we need to convert to new inference vars
132 let new_vars = Substitution( 132 let new_vars = Substitution::from_iter(
133 solution 133 &Interner,
134 .binders 134 solution.binders.iter(&Interner).map(|k| match k.kind {
135 .iter(&Interner) 135 VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(),
136 .map(|k| match k.kind { 136 VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(),
137 VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(), 137 VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(),
138 VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(), 138 // HACK: Chalk can sometimes return new lifetime variables. We
139 VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(), 139 // want to just skip them, but to not mess up the indices of
140 // HACK: Chalk can sometimes return new lifetime variables. We 140 // other variables, we'll just create a new type variable in
141 // want to just skip them, but to not mess up the indices of 141 // their place instead. This should not matter (we never see the
142 // other variables, we'll just create a new type variable in 142 // actual *uses* of the lifetime variable).
143 // their place instead. This should not matter (we never see the 143 VariableKind::Lifetime => ctx.table.new_type_var(),
144 // actual *uses* of the lifetime variable). 144 _ => panic!("const variable in solution"),
145 VariableKind::Lifetime => ctx.table.new_type_var(), 145 }),
146 _ => panic!("const variable in solution"),
147 })
148 .collect(),
149 ); 146 );
150 for (i, ty) in solution.value.into_iter().enumerate() { 147 for (i, ty) in solution.value.iter(&Interner).enumerate() {
151 let (v, k) = self.free_vars[i]; 148 let (v, k) = self.free_vars[i];
152 // eagerly replace projections in the type; we may be getting types 149 // eagerly replace projections in the type; we may be getting types
153 // e.g. from where clauses where this hasn't happened yet 150 // e.g. from where clauses where this hasn't happened yet
154 let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); 151 let ty = ctx.normalize_associated_types_in(
152 ty.assert_ty_ref(&Interner).clone().subst_bound_vars(&new_vars),
153 );
155 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); 154 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty);
156 } 155 }
157 } 156 }
@@ -163,13 +162,13 @@ pub fn could_unify(t1: &Ty, t2: &Ty) -> bool {
163 162
164pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { 163pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
165 let mut table = InferenceTable::new(); 164 let mut table = InferenceTable::new();
166 let vars = Substitution( 165 let vars = Substitution::from_iter(
166 &Interner,
167 tys.binders 167 tys.binders
168 .iter(&Interner) 168 .iter(&Interner)
169 // we always use type vars here because we want everything to 169 // we always use type vars here because we want everything to
170 // fallback to Unknown in the end (kind of hacky, as below) 170 // fallback to Unknown in the end (kind of hacky, as below)
171 .map(|_| table.new_type_var()) 171 .map(|_| table.new_type_var()),
172 .collect(),
173 ); 172 );
174 let ty1_with_vars = tys.value.0.clone().subst_bound_vars(&vars); 173 let ty1_with_vars = tys.value.0.clone().subst_bound_vars(&vars);
175 let ty2_with_vars = tys.value.1.clone().subst_bound_vars(&vars); 174 let ty2_with_vars = tys.value.1.clone().subst_bound_vars(&vars);
@@ -178,7 +177,8 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
178 } 177 }
179 // default any type vars that weren't unified back to their original bound vars 178 // default any type vars that weren't unified back to their original bound vars
180 // (kind of hacky) 179 // (kind of hacky)
181 for (i, var) in vars.iter().enumerate() { 180 for (i, var) in vars.iter(&Interner).enumerate() {
181 let var = var.assert_ty_ref(&Interner);
182 if &*table.resolve_ty_shallow(var) == var { 182 if &*table.resolve_ty_shallow(var) == var {
183 table.unify( 183 table.unify(
184 var, 184 var,
@@ -188,7 +188,10 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
188 } 188 }
189 Some( 189 Some(
190 Substitution::builder(tys.binders.len(&Interner)) 190 Substitution::builder(tys.binders.len(&Interner))
191 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) 191 .fill(
192 vars.iter(&Interner)
193 .map(|v| table.resolve_ty_completely(v.assert_ty_ref(&Interner).clone())),
194 )
192 .build(), 195 .build(),
193 ) 196 )
194} 197}
@@ -284,7 +287,9 @@ impl InferenceTable {
284 substs2: &Substitution, 287 substs2: &Substitution,
285 depth: usize, 288 depth: usize,
286 ) -> bool { 289 ) -> bool {
287 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth)) 290 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| {
291 self.unify_inner(t1.assert_ty_ref(&Interner), t2.assert_ty_ref(&Interner), depth)
292 })
288 } 293 }
289 294
290 fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 295 fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {