aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r--crates/hir_ty/src/infer/coerce.rs39
-rw-r--r--crates/hir_ty/src/infer/expr.rs158
-rw-r--r--crates/hir_ty/src/infer/pat.rs56
-rw-r--r--crates/hir_ty/src/infer/path.rs40
-rw-r--r--crates/hir_ty/src/infer/unify.rs103
5 files changed, 189 insertions, 207 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 9c62932b1..32c273afc 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -7,9 +7,7 @@
7use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; 7use chalk_ir::{cast::Cast, Mutability, TyVariableKind};
8use hir_def::lang_item::LangItemTarget; 8use hir_def::lang_item::LangItemTarget;
9 9
10use crate::{ 10use crate::{autoderef, Interner, Solution, Ty, TyBuilder, TyKind};
11 autoderef, to_chalk_trait_id, traits::Solution, Interner, Substitution, TraitRef, Ty, TyKind,
12};
13 11
14use super::{InEnvironment, InferenceContext}; 12use super::{InEnvironment, InferenceContext};
15 13
@@ -36,7 +34,7 @@ impl<'a> InferenceContext<'a> {
36 ty1.clone() 34 ty1.clone()
37 } else { 35 } else {
38 if let (TyKind::FnDef(..), TyKind::FnDef(..)) = 36 if let (TyKind::FnDef(..), TyKind::FnDef(..)) =
39 (ty1.interned(&Interner), ty2.interned(&Interner)) 37 (ty1.kind(&Interner), ty2.kind(&Interner))
40 { 38 {
41 cov_mark::hit!(coerce_fn_reification); 39 cov_mark::hit!(coerce_fn_reification);
42 // Special case: two function types. Try to coerce both to 40 // Special case: two function types. Try to coerce both to
@@ -44,8 +42,8 @@ impl<'a> InferenceContext<'a> {
44 // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916 42 // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916
45 let sig1 = ty1.callable_sig(self.db).expect("FnDef without callable sig"); 43 let sig1 = ty1.callable_sig(self.db).expect("FnDef without callable sig");
46 let sig2 = ty2.callable_sig(self.db).expect("FnDef without callable sig"); 44 let sig2 = ty2.callable_sig(self.db).expect("FnDef without callable sig");
47 let ptr_ty1 = Ty::fn_ptr(sig1); 45 let ptr_ty1 = TyBuilder::fn_ptr(sig1);
48 let ptr_ty2 = Ty::fn_ptr(sig2); 46 let ptr_ty2 = TyBuilder::fn_ptr(sig2);
49 self.coerce_merge_branch(&ptr_ty1, &ptr_ty2) 47 self.coerce_merge_branch(&ptr_ty1, &ptr_ty2)
50 } else { 48 } else {
51 cov_mark::hit!(coerce_merge_fail_fallback); 49 cov_mark::hit!(coerce_merge_fail_fallback);
@@ -55,7 +53,7 @@ impl<'a> InferenceContext<'a> {
55 } 53 }
56 54
57 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { 55 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool {
58 match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { 56 match (from_ty.kind(&Interner), to_ty.kind(&Interner)) {
59 // Never type will make type variable to fallback to Never Type instead of Unknown. 57 // Never type will make type variable to fallback to Never Type instead of Unknown.
60 (TyKind::Never, TyKind::InferenceVar(tv, TyVariableKind::General)) => { 58 (TyKind::Never, TyKind::InferenceVar(tv, TyVariableKind::General)) => {
61 self.table.type_variable_table.set_diverging(*tv, true); 59 self.table.type_variable_table.set_diverging(*tv, true);
@@ -73,7 +71,7 @@ impl<'a> InferenceContext<'a> {
73 } 71 }
74 72
75 // Pointer weakening and function to pointer 73 // Pointer weakening and function to pointer
76 match (from_ty.interned_mut(), to_ty.interned(&Interner)) { 74 match (from_ty.interned_mut(), to_ty.kind(&Interner)) {
77 // `*mut T` -> `*const T` 75 // `*mut T` -> `*const T`
78 // `&mut T` -> `&T` 76 // `&mut T` -> `&T`
79 (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) 77 (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..))
@@ -95,12 +93,12 @@ impl<'a> InferenceContext<'a> {
95 (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) { 93 (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) {
96 None => return false, 94 None => return false,
97 Some(sig) => { 95 Some(sig) => {
98 from_ty = Ty::fn_ptr(sig); 96 from_ty = TyBuilder::fn_ptr(sig);
99 } 97 }
100 }, 98 },
101 99
102 (TyKind::Closure(.., substs), TyKind::Function { .. }) => { 100 (TyKind::Closure(.., substs), TyKind::Function { .. }) => {
103 from_ty = substs[0].clone(); 101 from_ty = substs.at(&Interner, 0).assert_ty_ref(&Interner).clone();
104 } 102 }
105 103
106 _ => {} 104 _ => {}
@@ -111,7 +109,7 @@ impl<'a> InferenceContext<'a> {
111 } 109 }
112 110
113 // Auto Deref if cannot coerce 111 // Auto Deref if cannot coerce
114 match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { 112 match (from_ty.kind(&Interner), to_ty.kind(&Interner)) {
115 // FIXME: DerefMut 113 // FIXME: DerefMut
116 (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => self.unify_autoderef_behind_ref(st1, st2), 114 (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => self.unify_autoderef_behind_ref(st1, st2),
117 115
@@ -130,18 +128,15 @@ impl<'a> InferenceContext<'a> {
130 _ => return None, 128 _ => return None,
131 }; 129 };
132 130
133 let generic_params = crate::utils::generics(self.db.upcast(), coerce_unsized_trait.into()); 131 let trait_ref = {
134 if generic_params.len() != 2 { 132 let b = TyBuilder::trait_ref(self.db, coerce_unsized_trait);
135 // The CoerceUnsized trait should have two generic params: Self and T. 133 if b.remaining() != 2 {
136 return None; 134 // The CoerceUnsized trait should have two generic params: Self and T.
137 } 135 return None;
136 }
137 b.push(from_ty.clone()).push(to_ty.clone()).build()
138 };
138 139
139 let substs = Substitution::build_for_generics(&generic_params)
140 .push(from_ty.clone())
141 .push(to_ty.clone())
142 .build();
143 let trait_ref =
144 TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs };
145 let goal = InEnvironment::new(self.trait_env.env.clone(), trait_ref.cast(&Interner)); 140 let goal = InEnvironment::new(self.trait_env.env.clone(), trait_ref.cast(&Interner));
146 141
147 let canonicalizer = self.canonicalizer(); 142 let canonicalizer = self.canonicalizer();
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index e6ede05ca..6966d26e7 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -19,11 +19,11 @@ use crate::{
19 lower::lower_to_chalk_mutability, 19 lower::lower_to_chalk_mutability,
20 method_resolution, op, 20 method_resolution, op,
21 primitive::{self, UintTy}, 21 primitive::{self, UintTy},
22 to_assoc_type_id, to_chalk_trait_id, 22 to_chalk_trait_id,
23 traits::{chalk::from_chalk, FnTrait, InEnvironment}, 23 traits::{chalk::from_chalk, FnTrait},
24 utils::{generics, variant_data, Generics}, 24 utils::{generics, variant_data, Generics},
25 AdtId, Binders, CallableDefId, DomainGoal, FnPointer, FnSig, Interner, Rawness, Scalar, 25 AdtId, Binders, CallableDefId, FnPointer, FnSig, InEnvironment, Interner, Rawness, Scalar,
26 Substitution, TraitRef, Ty, TyKind, 26 Substitution, TraitRef, Ty, TyBuilder, TyKind,
27}; 27};
28 28
29use super::{ 29use super::{
@@ -73,38 +73,33 @@ impl<'a> InferenceContext<'a> {
73 let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?; 73 let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?;
74 let output_assoc_type = 74 let output_assoc_type =
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 let generic_params = generics(self.db.upcast(), fn_once_trait.into());
77 if generic_params.len() != 2 {
78 return None;
79 }
80 76
81 let mut param_builder = Substitution::builder(num_args);
82 let mut arg_tys = vec![]; 77 let mut arg_tys = vec![];
83 for _ in 0..num_args { 78 let arg_ty = TyBuilder::tuple(num_args)
84 let arg = self.table.new_type_var(); 79 .fill(repeat_with(|| {
85 param_builder = param_builder.push(arg.clone()); 80 let arg = self.table.new_type_var();
86 arg_tys.push(arg); 81 arg_tys.push(arg.clone());
87 } 82 arg
88 let parameters = param_builder.build(); 83 }))
89 let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner); 84 .build();
90 let substs = 85
91 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 86 let projection = {
87 let b = TyBuilder::assoc_type_projection(self.db, output_assoc_type);
88 if b.remaining() != 2 {
89 return None;
90 }
91 b.push(ty.clone()).push(arg_ty).build()
92 };
92 93
93 let trait_env = self.trait_env.env.clone(); 94 let trait_env = self.trait_env.env.clone();
94 let implements_fn_trait: DomainGoal = 95 let obligation = InEnvironment {
95 TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() } 96 goal: projection.trait_ref(self.db).cast(&Interner),
96 .cast(&Interner);
97 let goal = self.canonicalizer().canonicalize_obligation(InEnvironment {
98 goal: implements_fn_trait.clone(),
99 environment: trait_env, 97 environment: trait_env,
100 }); 98 };
101 if self.db.trait_solve(krate, goal.value).is_some() { 99 let canonical = self.canonicalizer().canonicalize_obligation(obligation.clone());
102 self.obligations.push(implements_fn_trait); 100 if self.db.trait_solve(krate, canonical.value).is_some() {
103 let output_proj_ty = crate::ProjectionTy { 101 self.push_obligation(obligation.goal);
104 associated_ty_id: to_assoc_type_id(output_assoc_type), 102 let return_ty = self.normalize_projection_ty(projection);
105 substitution: substs,
106 };
107 let return_ty = self.normalize_projection_ty(output_proj_ty);
108 Some((arg_tys, return_ty)) 103 Some((arg_tys, return_ty))
109 } else { 104 } else {
110 None 105 None
@@ -119,6 +114,8 @@ impl<'a> InferenceContext<'a> {
119 } 114 }
120 115
121 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { 116 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
117 self.db.check_canceled();
118
122 let body = Arc::clone(&self.body); // avoid borrow checker problem 119 let body = Arc::clone(&self.body); // avoid borrow checker problem
123 let ty = match &body[tgt_expr] { 120 let ty = match &body[tgt_expr] {
124 Expr::Missing => self.err_ty(), 121 Expr::Missing => self.err_ty(),
@@ -136,7 +133,7 @@ impl<'a> InferenceContext<'a> {
136 both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe); 133 both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe);
137 let else_ty = match else_branch { 134 let else_ty = match else_branch {
138 Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), 135 Some(else_branch) => self.infer_expr_inner(*else_branch, &expected),
139 None => Ty::unit(), 136 None => TyBuilder::unit(),
140 }; 137 };
141 both_arms_diverge &= self.diverges; 138 both_arms_diverge &= self.diverges;
142 139
@@ -191,7 +188,7 @@ impl<'a> InferenceContext<'a> {
191 break_ty: self.table.new_type_var(), 188 break_ty: self.table.new_type_var(),
192 label: label.map(|label| self.body[label].name.clone()), 189 label: label.map(|label| self.body[label].name.clone()),
193 }); 190 });
194 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 191 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
195 192
196 let ctxt = self.breakables.pop().expect("breakable stack broken"); 193 let ctxt = self.breakables.pop().expect("breakable stack broken");
197 if ctxt.may_break { 194 if ctxt.may_break {
@@ -215,11 +212,11 @@ impl<'a> InferenceContext<'a> {
215 *condition, 212 *condition,
216 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), 213 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)),
217 ); 214 );
218 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 215 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
219 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 216 let _ctxt = self.breakables.pop().expect("breakable stack broken");
220 // the body may not run, so it diverging doesn't mean we diverge 217 // the body may not run, so it diverging doesn't mean we diverge
221 self.diverges = Diverges::Maybe; 218 self.diverges = Diverges::Maybe;
222 Ty::unit() 219 TyBuilder::unit()
223 } 220 }
224 Expr::For { iterable, body, pat, label } => { 221 Expr::For { iterable, body, pat, label } => {
225 let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); 222 let iterable_ty = self.infer_expr(*iterable, &Expectation::none());
@@ -234,11 +231,11 @@ impl<'a> InferenceContext<'a> {
234 231
235 self.infer_pat(*pat, &pat_ty, BindingMode::default()); 232 self.infer_pat(*pat, &pat_ty, BindingMode::default());
236 233
237 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 234 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
238 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 235 let _ctxt = self.breakables.pop().expect("breakable stack broken");
239 // the body may not run, so it diverging doesn't mean we diverge 236 // the body may not run, so it diverging doesn't mean we diverge
240 self.diverges = Diverges::Maybe; 237 self.diverges = Diverges::Maybe;
241 Ty::unit() 238 TyBuilder::unit()
242 } 239 }
243 Expr::Lambda { body, args, ret_type, arg_types } => { 240 Expr::Lambda { body, args, ret_type, arg_types } => {
244 assert_eq!(args.len(), arg_types.len()); 241 assert_eq!(args.len(), arg_types.len());
@@ -264,7 +261,7 @@ impl<'a> InferenceContext<'a> {
264 let sig_ty = TyKind::Function(FnPointer { 261 let sig_ty = TyKind::Function(FnPointer {
265 num_args: sig_tys.len() - 1, 262 num_args: sig_tys.len() - 1,
266 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, 263 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
267 substs: Substitution(sig_tys.clone().into()), 264 substs: Substitution::from_iter(&Interner, sig_tys.clone()),
268 }) 265 })
269 .intern(&Interner); 266 .intern(&Interner);
270 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); 267 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();
@@ -358,7 +355,7 @@ impl<'a> InferenceContext<'a> {
358 let val_ty = if let Some(expr) = expr { 355 let val_ty = if let Some(expr) = expr {
359 self.infer_expr(*expr, &Expectation::none()) 356 self.infer_expr(*expr, &Expectation::none())
360 } else { 357 } else {
361 Ty::unit() 358 TyBuilder::unit()
362 }; 359 };
363 360
364 let last_ty = 361 let last_ty =
@@ -384,7 +381,7 @@ impl<'a> InferenceContext<'a> {
384 if let Some(expr) = expr { 381 if let Some(expr) = expr {
385 self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone())); 382 self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone()));
386 } else { 383 } else {
387 let unit = Ty::unit(); 384 let unit = TyBuilder::unit();
388 self.coerce(&unit, &self.return_ty.clone()); 385 self.coerce(&unit, &self.return_ty.clone());
389 } 386 }
390 TyKind::Never.intern(&Interner) 387 TyKind::Never.intern(&Interner)
@@ -404,7 +401,7 @@ impl<'a> InferenceContext<'a> {
404 401
405 self.unify(&ty, &expected.ty); 402 self.unify(&ty, &expected.ty);
406 403
407 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 404 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
408 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); 405 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
409 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); 406 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
410 for field in fields.iter() { 407 for field in fields.iter() {
@@ -422,7 +419,7 @@ impl<'a> InferenceContext<'a> {
422 self.result.record_field_resolutions.insert(field.expr, field_def); 419 self.result.record_field_resolutions.insert(field.expr, field_def);
423 } 420 }
424 let field_ty = field_def.map_or(self.err_ty(), |it| { 421 let field_ty = field_def.map_or(self.err_ty(), |it| {
425 field_types[it.local_id].clone().subst(&substs) 422 field_types[it.local_id].clone().substitute(&Interner, &substs)
426 }); 423 });
427 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); 424 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
428 } 425 }
@@ -453,10 +450,10 @@ impl<'a> InferenceContext<'a> {
453 }) 450 })
454 .unwrap_or(true) 451 .unwrap_or(true)
455 }; 452 };
456 match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) { 453 match canonicalized.decanonicalize_ty(derefed_ty.value).kind(&Interner) {
457 TyKind::Tuple(_, substs) => { 454 TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| {
458 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) 455 substs.interned().get(idx).map(|a| a.assert_ty_ref(&Interner)).cloned()
459 } 456 }),
460 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { 457 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
461 let local_id = self.db.struct_data(*s).variant_data.field(name)?; 458 let local_id = self.db.struct_data(*s).variant_data.field(name)?;
462 let field = FieldId { parent: (*s).into(), local_id }; 459 let field = FieldId { parent: (*s).into(), local_id };
@@ -465,7 +462,7 @@ impl<'a> InferenceContext<'a> {
465 Some( 462 Some(
466 self.db.field_types((*s).into())[field.local_id] 463 self.db.field_types((*s).into())[field.local_id]
467 .clone() 464 .clone()
468 .subst(&parameters), 465 .substitute(&Interner, &parameters),
469 ) 466 )
470 } else { 467 } else {
471 None 468 None
@@ -479,7 +476,7 @@ impl<'a> InferenceContext<'a> {
479 Some( 476 Some(
480 self.db.field_types((*u).into())[field.local_id] 477 self.db.field_types((*u).into())[field.local_id]
481 .clone() 478 .clone()
482 .subst(&parameters), 479 .substitute(&Interner, &parameters),
483 ) 480 )
484 } else { 481 } else {
485 None 482 None
@@ -533,17 +530,10 @@ impl<'a> InferenceContext<'a> {
533 Expr::Box { expr } => { 530 Expr::Box { expr } => {
534 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 531 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
535 if let Some(box_) = self.resolve_boxed_box() { 532 if let Some(box_) = self.resolve_boxed_box() {
536 let mut sb = 533 TyBuilder::adt(self.db, box_)
537 Substitution::build_for_generics(&generics(self.db.upcast(), box_.into())); 534 .push(inner_ty)
538 sb = sb.push(inner_ty); 535 .fill_with_defaults(self.db, || self.table.new_type_var())
539 match self.db.generic_defaults(box_.into()).get(1) { 536 .build()
540 Some(alloc_ty) if !alloc_ty.value.is_unknown() && sb.remaining() > 0 => {
541 sb = sb.push(alloc_ty.value.clone());
542 }
543 _ => (),
544 }
545 sb = sb.fill(repeat_with(|| self.table.new_type_var()));
546 Ty::adt_ty(box_, sb.build())
547 } else { 537 } else {
548 self.err_ty() 538 self.err_ty()
549 } 539 }
@@ -571,7 +561,7 @@ impl<'a> InferenceContext<'a> {
571 None => self.err_ty(), 561 None => self.err_ty(),
572 }, 562 },
573 UnaryOp::Neg => { 563 UnaryOp::Neg => {
574 match inner_ty.interned(&Interner) { 564 match inner_ty.kind(&Interner) {
575 // Fast path for builtins 565 // Fast path for builtins
576 TyKind::Scalar(Scalar::Int(_)) 566 TyKind::Scalar(Scalar::Int(_))
577 | TyKind::Scalar(Scalar::Uint(_)) 567 | TyKind::Scalar(Scalar::Uint(_))
@@ -584,7 +574,7 @@ impl<'a> InferenceContext<'a> {
584 } 574 }
585 } 575 }
586 UnaryOp::Not => { 576 UnaryOp::Not => {
587 match inner_ty.interned(&Interner) { 577 match inner_ty.kind(&Interner) {
588 // Fast path for builtins 578 // Fast path for builtins
589 TyKind::Scalar(Scalar::Bool) 579 TyKind::Scalar(Scalar::Bool)
590 | TyKind::Scalar(Scalar::Int(_)) 580 | TyKind::Scalar(Scalar::Int(_))
@@ -633,31 +623,31 @@ impl<'a> InferenceContext<'a> {
633 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); 623 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
634 match (range_type, lhs_ty, rhs_ty) { 624 match (range_type, lhs_ty, rhs_ty) {
635 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 625 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
636 Some(adt) => Ty::adt_ty(adt, Substitution::empty()), 626 Some(adt) => TyBuilder::adt(self.db, adt).build(),
637 None => self.err_ty(), 627 None => self.err_ty(),
638 }, 628 },
639 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 629 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
640 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 630 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
641 None => self.err_ty(), 631 None => self.err_ty(),
642 }, 632 },
643 (RangeOp::Inclusive, None, Some(ty)) => { 633 (RangeOp::Inclusive, None, Some(ty)) => {
644 match self.resolve_range_to_inclusive() { 634 match self.resolve_range_to_inclusive() {
645 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 635 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
646 None => self.err_ty(), 636 None => self.err_ty(),
647 } 637 }
648 } 638 }
649 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 639 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
650 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 640 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
651 None => self.err_ty(), 641 None => self.err_ty(),
652 }, 642 },
653 (RangeOp::Inclusive, Some(_), Some(ty)) => { 643 (RangeOp::Inclusive, Some(_), Some(ty)) => {
654 match self.resolve_range_inclusive() { 644 match self.resolve_range_inclusive() {
655 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 645 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
656 None => self.err_ty(), 646 None => self.err_ty(),
657 } 647 }
658 } 648 }
659 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 649 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
660 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 650 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
661 None => self.err_ty(), 651 None => self.err_ty(),
662 }, 652 },
663 (RangeOp::Inclusive, _, None) => self.err_ty(), 653 (RangeOp::Inclusive, _, None) => self.err_ty(),
@@ -690,10 +680,10 @@ impl<'a> InferenceContext<'a> {
690 } 680 }
691 } 681 }
692 Expr::Tuple { exprs } => { 682 Expr::Tuple { exprs } => {
693 let mut tys = match expected.ty.interned(&Interner) { 683 let mut tys = match expected.ty.kind(&Interner) {
694 TyKind::Tuple(_, substs) => substs 684 TyKind::Tuple(_, substs) => substs
695 .iter() 685 .iter(&Interner)
696 .cloned() 686 .map(|a| a.assert_ty_ref(&Interner).clone())
697 .chain(repeat_with(|| self.table.new_type_var())) 687 .chain(repeat_with(|| self.table.new_type_var()))
698 .take(exprs.len()) 688 .take(exprs.len())
699 .collect::<Vec<_>>(), 689 .collect::<Vec<_>>(),
@@ -704,10 +694,10 @@ impl<'a> InferenceContext<'a> {
704 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 694 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
705 } 695 }
706 696
707 TyKind::Tuple(tys.len(), Substitution(tys.into())).intern(&Interner) 697 TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner)
708 } 698 }
709 Expr::Array(array) => { 699 Expr::Array(array) => {
710 let elem_ty = match expected.ty.interned(&Interner) { 700 let elem_ty = match expected.ty.kind(&Interner) {
711 TyKind::Array(st) | TyKind::Slice(st) => st.clone(), 701 TyKind::Array(st) | TyKind::Slice(st) => st.clone(),
712 _ => self.table.new_type_var(), 702 _ => self.table.new_type_var(),
713 }; 703 };
@@ -822,8 +812,8 @@ impl<'a> InferenceContext<'a> {
822 // we don't even make an attempt at coercion 812 // we don't even make an attempt at coercion
823 self.table.new_maybe_never_var() 813 self.table.new_maybe_never_var()
824 } else { 814 } else {
825 self.coerce(&Ty::unit(), &expected.coercion_target()); 815 self.coerce(&TyBuilder::unit(), &expected.coercion_target());
826 Ty::unit() 816 TyBuilder::unit()
827 } 817 }
828 }; 818 };
829 ty 819 ty
@@ -859,10 +849,10 @@ impl<'a> InferenceContext<'a> {
859 self.write_method_resolution(tgt_expr, func); 849 self.write_method_resolution(tgt_expr, func);
860 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) 850 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into())))
861 } 851 }
862 None => (receiver_ty, Binders::new(0, self.err_ty()), None), 852 None => (receiver_ty, Binders::empty(&Interner, self.err_ty()), None),
863 }; 853 };
864 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); 854 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty);
865 let method_ty = method_ty.subst(&substs); 855 let method_ty = method_ty.substitute(&Interner, &substs);
866 let method_ty = self.insert_type_vars(method_ty); 856 let method_ty = self.insert_type_vars(method_ty);
867 self.register_obligations_for_call(&method_ty); 857 self.register_obligations_for_call(&method_ty);
868 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) { 858 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) {
@@ -951,18 +941,20 @@ impl<'a> InferenceContext<'a> {
951 substs.push(self.err_ty()); 941 substs.push(self.err_ty());
952 } 942 }
953 assert_eq!(substs.len(), total_len); 943 assert_eq!(substs.len(), total_len);
954 Substitution(substs.into()) 944 Substitution::from_iter(&Interner, substs)
955 } 945 }
956 946
957 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 947 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
958 if let TyKind::FnDef(fn_def, parameters) = callable_ty.interned(&Interner) { 948 if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(&Interner) {
959 let def: CallableDefId = from_chalk(self.db, *fn_def); 949 let def: CallableDefId = from_chalk(self.db, *fn_def);
960 let generic_predicates = self.db.generic_predicates(def.into()); 950 let generic_predicates = self.db.generic_predicates(def.into());
961 for predicate in generic_predicates.iter() { 951 for predicate in generic_predicates.iter() {
962 let (predicate, binders) = 952 let (predicate, binders) = predicate
963 predicate.clone().subst(parameters).into_value_and_skipped_binders(); 953 .clone()
964 always!(binders == 0); // quantified where clauses not yet handled 954 .substitute(&Interner, parameters)
965 self.obligations.push(predicate.cast(&Interner)); 955 .into_value_and_skipped_binders();
956 always!(binders.len(&Interner) == 0); // quantified where clauses not yet handled
957 self.push_obligation(predicate.cast(&Interner));
966 } 958 }
967 // add obligation for trait implementation, if this is a trait method 959 // add obligation for trait implementation, if this is a trait method
968 match def { 960 match def {
@@ -972,7 +964,7 @@ impl<'a> InferenceContext<'a> {
972 // construct a TraitRef 964 // construct a TraitRef
973 let substs = 965 let substs =
974 parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); 966 parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
975 self.obligations.push( 967 self.push_obligation(
976 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs } 968 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }
977 .cast(&Interner), 969 .cast(&Interner),
978 ); 970 );
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 474363709..252ae914a 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -13,9 +13,8 @@ use hir_expand::name::Name;
13 13
14use super::{BindingMode, Expectation, InferenceContext}; 14use super::{BindingMode, Expectation, InferenceContext};
15use crate::{ 15use crate::{
16 lower::lower_to_chalk_mutability, 16 lower::lower_to_chalk_mutability, utils::variant_data, Interner, Substitution, Ty, TyBuilder,
17 utils::{generics, variant_data}, 17 TyKind,
18 Interner, Substitution, Ty, TyKind,
19}; 18};
20 19
21impl<'a> InferenceContext<'a> { 20impl<'a> InferenceContext<'a> {
@@ -35,7 +34,7 @@ impl<'a> InferenceContext<'a> {
35 } 34 }
36 self.unify(&ty, expected); 35 self.unify(&ty, expected);
37 36
38 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 37 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
39 38
40 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 39 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
41 let (pre, post) = match ellipsis { 40 let (pre, post) = match ellipsis {
@@ -50,7 +49,9 @@ impl<'a> InferenceContext<'a> {
50 let expected_ty = var_data 49 let expected_ty = var_data
51 .as_ref() 50 .as_ref()
52 .and_then(|d| d.field(&Name::new_tuple_field(i))) 51 .and_then(|d| d.field(&Name::new_tuple_field(i)))
53 .map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs)); 52 .map_or(self.err_ty(), |field| {
53 field_tys[field].clone().substitute(&Interner, &substs)
54 });
54 let expected_ty = self.normalize_associated_types_in(expected_ty); 55 let expected_ty = self.normalize_associated_types_in(expected_ty);
55 self.infer_pat(subpat, &expected_ty, default_bm); 56 self.infer_pat(subpat, &expected_ty, default_bm);
56 } 57 }
@@ -74,7 +75,7 @@ impl<'a> InferenceContext<'a> {
74 75
75 self.unify(&ty, expected); 76 self.unify(&ty, expected);
76 77
77 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 78 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
78 79
79 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 80 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
80 for subpat in subpats { 81 for subpat in subpats {
@@ -84,8 +85,9 @@ impl<'a> InferenceContext<'a> {
84 self.result.record_pat_field_resolutions.insert(subpat.pat, field_def); 85 self.result.record_pat_field_resolutions.insert(subpat.pat, field_def);
85 } 86 }
86 87
87 let expected_ty = matching_field 88 let expected_ty = matching_field.map_or(self.err_ty(), |field| {
88 .map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs)); 89 field_tys[field].clone().substitute(&Interner, &substs)
90 });
89 let expected_ty = self.normalize_associated_types_in(expected_ty); 91 let expected_ty = self.normalize_associated_types_in(expected_ty);
90 self.infer_pat(subpat.pat, &expected_ty, default_bm); 92 self.infer_pat(subpat.pat, &expected_ty, default_bm);
91 } 93 }
@@ -124,7 +126,7 @@ impl<'a> InferenceContext<'a> {
124 let ty = match &body[pat] { 126 let ty = match &body[pat] {
125 &Pat::Tuple { ref args, ellipsis } => { 127 &Pat::Tuple { ref args, ellipsis } => {
126 let expectations = match expected.as_tuple() { 128 let expectations = match expected.as_tuple() {
127 Some(parameters) => &*parameters.0, 129 Some(parameters) => &*parameters.interned(),
128 _ => &[], 130 _ => &[],
129 }; 131 };
130 132
@@ -134,7 +136,8 @@ impl<'a> InferenceContext<'a> {
134 }; 136 };
135 let n_uncovered_patterns = expectations.len().saturating_sub(args.len()); 137 let n_uncovered_patterns = expectations.len().saturating_sub(args.len());
136 let err_ty = self.err_ty(); 138 let err_ty = self.err_ty();
137 let mut expectations_iter = expectations.iter().chain(repeat(&err_ty)); 139 let mut expectations_iter =
140 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); 141 let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm);
139 142
140 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len()); 143 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len());
@@ -142,7 +145,8 @@ impl<'a> InferenceContext<'a> {
142 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); 145 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
143 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); 146 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
144 147
145 TyKind::Tuple(inner_tys.len(), Substitution(inner_tys.into())).intern(&Interner) 148 TyKind::Tuple(inner_tys.len(), Substitution::from_iter(&Interner, inner_tys))
149 .intern(&Interner)
146 } 150 }
147 Pat::Or(ref pats) => { 151 Pat::Or(ref pats) => {
148 if let Some((first_pat, rest)) = pats.split_first() { 152 if let Some((first_pat, rest)) = pats.split_first() {
@@ -209,7 +213,7 @@ impl<'a> InferenceContext<'a> {
209 return inner_ty; 213 return inner_ty;
210 } 214 }
211 Pat::Slice { prefix, slice, suffix } => { 215 Pat::Slice { prefix, slice, suffix } => {
212 let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.interned(&Interner) { 216 let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.kind(&Interner) {
213 TyKind::Array(st) => (TyKind::Array, st.clone()), 217 TyKind::Array(st) => (TyKind::Array, st.clone()),
214 TyKind::Slice(st) => (TyKind::Slice, st.clone()), 218 TyKind::Slice(st) => (TyKind::Slice, st.clone()),
215 _ => (TyKind::Slice, self.err_ty()), 219 _ => (TyKind::Slice, self.err_ty()),
@@ -236,30 +240,20 @@ impl<'a> InferenceContext<'a> {
236 Pat::Box { inner } => match self.resolve_boxed_box() { 240 Pat::Box { inner } => match self.resolve_boxed_box() {
237 Some(box_adt) => { 241 Some(box_adt) => {
238 let (inner_ty, alloc_ty) = match expected.as_adt() { 242 let (inner_ty, alloc_ty) = match expected.as_adt() {
239 Some((adt, subst)) if adt == box_adt => { 243 Some((adt, subst)) if adt == box_adt => (
240 (subst[0].clone(), subst.get(1).cloned()) 244 subst.at(&Interner, 0).assert_ty_ref(&Interner).clone(),
241 } 245 subst.interned().get(1).and_then(|a| a.ty(&Interner).cloned()),
246 ),
242 _ => (self.result.standard_types.unknown.clone(), None), 247 _ => (self.result.standard_types.unknown.clone(), None),
243 }; 248 };
244 249
245 let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm); 250 let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm);
246 let mut sb = Substitution::build_for_generics(&generics( 251 let mut b = TyBuilder::adt(self.db, box_adt).push(inner_ty);
247 self.db.upcast(), 252
248 box_adt.into(), 253 if let Some(alloc_ty) = alloc_ty {
249 )); 254 b = b.push(alloc_ty);
250 sb = sb.push(inner_ty);
251 if sb.remaining() == 1 {
252 sb = sb.push(match alloc_ty {
253 Some(alloc_ty) if !alloc_ty.is_unknown() => alloc_ty,
254 _ => match self.db.generic_defaults(box_adt.into()).get(1) {
255 Some(alloc_ty) if !alloc_ty.value.is_unknown() => {
256 alloc_ty.value.clone()
257 }
258 _ => self.table.new_type_var(),
259 },
260 });
261 } 255 }
262 Ty::adt_ty(box_adt, sb.build()) 256 b.fill_with_defaults(self.db, || self.table.new_type_var()).build()
263 } 257 }
264 None => self.err_ty(), 258 None => self.err_ty(),
265 }, 259 },
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs
index cefa38509..14f705173 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -10,9 +10,7 @@ use hir_def::{
10}; 10};
11use hir_expand::name::Name; 11use hir_expand::name::Name;
12 12
13use crate::{ 13use crate::{method_resolution, Interner, Substitution, Ty, TyBuilder, TyKind, ValueTyDefId};
14 method_resolution, to_chalk_trait_id, Interner, Substitution, Ty, TyKind, ValueTyDefId,
15};
16 14
17use super::{ExprOrPatId, InferenceContext, TraitRef}; 15use super::{ExprOrPatId, InferenceContext, TraitRef};
18 16
@@ -82,10 +80,10 @@ impl<'a> InferenceContext<'a> {
82 } 80 }
83 ValueNs::ImplSelf(impl_id) => { 81 ValueNs::ImplSelf(impl_id) => {
84 let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); 82 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
85 let substs = Substitution::type_params_for_generics(self.db, &generics); 83 let substs = generics.type_params_subst(self.db);
86 let ty = self.db.impl_self_ty(impl_id).subst(&substs); 84 let ty = self.db.impl_self_ty(impl_id).substitute(&Interner, &substs);
87 if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() { 85 if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() {
88 let ty = self.db.value_ty(struct_id.into()).subst(&substs); 86 let ty = self.db.value_ty(struct_id.into()).substitute(&Interner, &substs);
89 return Some(ty); 87 return Some(ty);
90 } else { 88 } else {
91 // FIXME: diagnostic, invalid Self reference 89 // FIXME: diagnostic, invalid Self reference
@@ -95,16 +93,13 @@ impl<'a> InferenceContext<'a> {
95 ValueNs::GenericParam(it) => return Some(self.db.const_param_ty(it)), 93 ValueNs::GenericParam(it) => return Some(self.db.const_param_ty(it)),
96 }; 94 };
97 95
98 let ty = self.db.value_ty(typable); 96 let parent_substs = self_subst.unwrap_or_else(|| Substitution::empty(&Interner));
99 // self_subst is just for the parent
100 let parent_substs = self_subst.unwrap_or_else(Substitution::empty);
101 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); 97 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
102 let substs = ctx.substs_from_path(path, typable, true); 98 let substs = ctx.substs_from_path(path, typable, true);
103 let full_substs = Substitution::builder(substs.len()) 99 let ty = TyBuilder::value_ty(self.db, typable)
104 .use_parent_substs(&parent_substs) 100 .use_parent_substs(&parent_substs)
105 .fill(substs.0[parent_substs.len()..].iter().cloned()) 101 .fill(substs.interned()[parent_substs.len(&Interner)..].iter().cloned())
106 .build(); 102 .build();
107 let ty = ty.subst(&full_substs);
108 Some(ty) 103 Some(ty)
109 } 104 }
110 105
@@ -147,7 +142,7 @@ impl<'a> InferenceContext<'a> {
147 remaining_segments_for_ty, 142 remaining_segments_for_ty,
148 true, 143 true,
149 ); 144 );
150 if let TyKind::Unknown = ty.interned(&Interner) { 145 if let TyKind::Error = ty.kind(&Interner) {
151 return None; 146 return None;
152 } 147 }
153 148
@@ -212,7 +207,7 @@ impl<'a> InferenceContext<'a> {
212 name: &Name, 207 name: &Name,
213 id: ExprOrPatId, 208 id: ExprOrPatId,
214 ) -> Option<(ValueNs, Option<Substitution>)> { 209 ) -> Option<(ValueNs, Option<Substitution>)> {
215 if let TyKind::Unknown = ty.interned(&Interner) { 210 if let TyKind::Error = ty.kind(&Interner) {
216 return None; 211 return None;
217 } 212 }
218 213
@@ -245,27 +240,22 @@ impl<'a> InferenceContext<'a> {
245 }; 240 };
246 let substs = match container { 241 let substs = match container {
247 AssocContainerId::ImplId(impl_id) => { 242 AssocContainerId::ImplId(impl_id) => {
248 let impl_substs = Substitution::build_for_def(self.db, impl_id) 243 let impl_substs = TyBuilder::subst_for_def(self.db, impl_id)
249 .fill(iter::repeat_with(|| self.table.new_type_var())) 244 .fill(iter::repeat_with(|| self.table.new_type_var()))
250 .build(); 245 .build();
251 let impl_self_ty = self.db.impl_self_ty(impl_id).subst(&impl_substs); 246 let impl_self_ty =
247 self.db.impl_self_ty(impl_id).substitute(&Interner, &impl_substs);
252 self.unify(&impl_self_ty, &ty); 248 self.unify(&impl_self_ty, &ty);
253 Some(impl_substs) 249 Some(impl_substs)
254 } 250 }
255 AssocContainerId::TraitId(trait_) => { 251 AssocContainerId::TraitId(trait_) => {
256 // we're picking this method 252 // we're picking this method
257 let trait_substs = Substitution::build_for_def(self.db, trait_) 253 let trait_ref = TyBuilder::trait_ref(self.db, trait_)
258 .push(ty.clone()) 254 .push(ty.clone())
259 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 255 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
260 .build(); 256 .build();
261 self.obligations.push( 257 self.push_obligation(trait_ref.clone().cast(&Interner));
262 TraitRef { 258 Some(trait_ref.substitution)
263 trait_id: to_chalk_trait_id(trait_),
264 substitution: trait_substs.clone(),
265 }
266 .cast(&Interner),
267 );
268 Some(trait_substs)
269 } 259 }
270 AssocContainerId::ModuleId(_) => None, 260 AssocContainerId::ModuleId(_) => None,
271 }; 261 };
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 6e7b0f5a6..c90a16720 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -49,7 +49,7 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
49 49
50 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { 50 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T {
51 t.fold_binders( 51 t.fold_binders(
52 &mut |ty, binders| match ty.interned(&Interner) { 52 &mut |ty, binders| match ty.kind(&Interner) {
53 &TyKind::InferenceVar(var, kind) => { 53 &TyKind::InferenceVar(var, kind) => {
54 let inner = var.to_inner(); 54 let inner = var.to_inner();
55 if self.var_stack.contains(&inner) { 55 if self.var_stack.contains(&inner) {
@@ -108,19 +108,22 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
108} 108}
109 109
110impl<T> Canonicalized<T> { 110impl<T> Canonicalized<T> {
111 pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { 111 pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty {
112 ty.walk_mut_binders( 112 ty.fold_binders(
113 &mut |ty, binders| { 113 &mut |ty, binders| {
114 if let &mut TyKind::BoundVar(bound) = ty.interned_mut() { 114 if let TyKind::BoundVar(bound) = ty.kind(&Interner) {
115 if bound.debruijn >= binders { 115 if bound.debruijn >= binders {
116 let (v, k) = self.free_vars[bound.index]; 116 let (v, k) = self.free_vars[bound.index];
117 *ty = TyKind::InferenceVar(v, k).intern(&Interner); 117 TyKind::InferenceVar(v, k).intern(&Interner)
118 } else {
119 ty
118 } 120 }
121 } else {
122 ty
119 } 123 }
120 }, 124 },
121 DebruijnIndex::INNERMOST, 125 DebruijnIndex::INNERMOST,
122 ); 126 )
123 ty
124 } 127 }
125 128
126 pub(super) fn apply_solution( 129 pub(super) fn apply_solution(
@@ -129,29 +132,28 @@ impl<T> Canonicalized<T> {
129 solution: Canonical<Substitution>, 132 solution: Canonical<Substitution>,
130 ) { 133 ) {
131 // the solution may contain new variables, which we need to convert to new inference vars 134 // the solution may contain new variables, which we need to convert to new inference vars
132 let new_vars = Substitution( 135 let new_vars = Substitution::from_iter(
133 solution 136 &Interner,
134 .binders 137 solution.binders.iter(&Interner).map(|k| match k.kind {
135 .iter(&Interner) 138 VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(),
136 .map(|k| match k.kind { 139 VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(),
137 VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(), 140 VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(),
138 VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(), 141 // HACK: Chalk can sometimes return new lifetime variables. We
139 VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(), 142 // want to just skip them, but to not mess up the indices of
140 // HACK: Chalk can sometimes return new lifetime variables. We 143 // 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 144 // their place instead. This should not matter (we never see the
142 // other variables, we'll just create a new type variable in 145 // actual *uses* of the lifetime variable).
143 // their place instead. This should not matter (we never see the 146 VariableKind::Lifetime => ctx.table.new_type_var(),
144 // actual *uses* of the lifetime variable). 147 _ => panic!("const variable in solution"),
145 VariableKind::Lifetime => ctx.table.new_type_var(), 148 }),
146 _ => panic!("const variable in solution"),
147 })
148 .collect(),
149 ); 149 );
150 for (i, ty) in solution.value.into_iter().enumerate() { 150 for (i, ty) in solution.value.iter(&Interner).enumerate() {
151 let (v, k) = self.free_vars[i]; 151 let (v, k) = self.free_vars[i];
152 // eagerly replace projections in the type; we may be getting types 152 // eagerly replace projections in the type; we may be getting types
153 // e.g. from where clauses where this hasn't happened yet 153 // 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)); 154 let ty = ctx.normalize_associated_types_in(
155 new_vars.apply(ty.assert_ty_ref(&Interner).clone(), &Interner),
156 );
155 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); 157 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty);
156 } 158 }
157 } 159 }
@@ -163,22 +165,23 @@ pub fn could_unify(t1: &Ty, t2: &Ty) -> bool {
163 165
164pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { 166pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
165 let mut table = InferenceTable::new(); 167 let mut table = InferenceTable::new();
166 let vars = Substitution( 168 let vars = Substitution::from_iter(
169 &Interner,
167 tys.binders 170 tys.binders
168 .iter(&Interner) 171 .iter(&Interner)
169 // we always use type vars here because we want everything to 172 // we always use type vars here because we want everything to
170 // fallback to Unknown in the end (kind of hacky, as below) 173 // fallback to Unknown in the end (kind of hacky, as below)
171 .map(|_| table.new_type_var()) 174 .map(|_| table.new_type_var()),
172 .collect(),
173 ); 175 );
174 let ty1_with_vars = tys.value.0.clone().subst_bound_vars(&vars); 176 let ty1_with_vars = vars.apply(tys.value.0.clone(), &Interner);
175 let ty2_with_vars = tys.value.1.clone().subst_bound_vars(&vars); 177 let ty2_with_vars = vars.apply(tys.value.1.clone(), &Interner);
176 if !table.unify(&ty1_with_vars, &ty2_with_vars) { 178 if !table.unify(&ty1_with_vars, &ty2_with_vars) {
177 return None; 179 return None;
178 } 180 }
179 // default any type vars that weren't unified back to their original bound vars 181 // default any type vars that weren't unified back to their original bound vars
180 // (kind of hacky) 182 // (kind of hacky)
181 for (i, var) in vars.iter().enumerate() { 183 for (i, var) in vars.iter(&Interner).enumerate() {
184 let var = var.assert_ty_ref(&Interner);
182 if &*table.resolve_ty_shallow(var) == var { 185 if &*table.resolve_ty_shallow(var) == var {
183 table.unify( 186 table.unify(
184 var, 187 var,
@@ -186,11 +189,11 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
186 ); 189 );
187 } 190 }
188 } 191 }
189 Some( 192 Some(Substitution::from_iter(
190 Substitution::builder(tys.binders.len(&Interner)) 193 &Interner,
191 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) 194 vars.iter(&Interner)
192 .build(), 195 .map(|v| table.resolve_ty_completely(v.assert_ty_ref(&Interner).clone())),
193 ) 196 ))
194} 197}
195 198
196#[derive(Clone, Debug)] 199#[derive(Clone, Debug)]
@@ -214,7 +217,7 @@ impl TypeVariableTable {
214 fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { 217 fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty {
215 match kind { 218 match kind {
216 _ if self.inner[iv.to_inner().0 as usize].diverging => TyKind::Never, 219 _ if self.inner[iv.to_inner().0 as usize].diverging => TyKind::Never,
217 TyVariableKind::General => TyKind::Unknown, 220 TyVariableKind::General => TyKind::Error,
218 TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)), 221 TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)),
219 TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)), 222 TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)),
220 } 223 }
@@ -231,6 +234,7 @@ pub(crate) struct TypeVariableData {
231pub(crate) struct InferenceTable { 234pub(crate) struct InferenceTable {
232 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>, 235 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>,
233 pub(super) type_variable_table: TypeVariableTable, 236 pub(super) type_variable_table: TypeVariableTable,
237 pub(super) revision: u32,
234} 238}
235 239
236impl InferenceTable { 240impl InferenceTable {
@@ -238,6 +242,7 @@ impl InferenceTable {
238 InferenceTable { 242 InferenceTable {
239 var_unification_table: InPlaceUnificationTable::new(), 243 var_unification_table: InPlaceUnificationTable::new(),
240 type_variable_table: TypeVariableTable { inner: Vec::new() }, 244 type_variable_table: TypeVariableTable { inner: Vec::new() },
245 revision: 0,
241 } 246 }
242 } 247 }
243 248
@@ -282,7 +287,9 @@ impl InferenceTable {
282 substs2: &Substitution, 287 substs2: &Substitution,
283 depth: usize, 288 depth: usize,
284 ) -> bool { 289 ) -> bool {
285 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth)) 290 substs1.iter(&Interner).zip(substs2.iter(&Interner)).all(|(t1, t2)| {
291 self.unify_inner(t1.assert_ty_ref(&Interner), t2.assert_ty_ref(&Interner), depth)
292 })
286 } 293 }
287 294
288 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 {
@@ -297,7 +304,7 @@ impl InferenceTable {
297 let ty1 = self.resolve_ty_shallow(ty1); 304 let ty1 = self.resolve_ty_shallow(ty1);
298 let ty2 = self.resolve_ty_shallow(ty2); 305 let ty2 = self.resolve_ty_shallow(ty2);
299 if ty1.equals_ctor(&ty2) { 306 if ty1.equals_ctor(&ty2) {
300 match (ty1.interned(&Interner), ty2.interned(&Interner)) { 307 match (ty1.kind(&Interner), ty2.kind(&Interner)) {
301 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) 308 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2))
302 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) 309 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2))
303 | ( 310 | (
@@ -322,8 +329,8 @@ impl InferenceTable {
322 } 329 }
323 330
324 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 331 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {
325 match (ty1.interned(&Interner), ty2.interned(&Interner)) { 332 match (ty1.kind(&Interner), ty2.kind(&Interner)) {
326 (TyKind::Unknown, _) | (_, TyKind::Unknown) => true, 333 (TyKind::Error, _) | (_, TyKind::Error) => true,
327 334
328 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, 335 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true,
329 336
@@ -360,7 +367,10 @@ impl InferenceTable {
360 == self.type_variable_table.is_diverging(*tv2) => 367 == self.type_variable_table.is_diverging(*tv2) =>
361 { 368 {
362 // both type vars are unknown since we tried to resolve them 369 // both type vars are unknown since we tried to resolve them
363 self.var_unification_table.union(tv1.to_inner(), tv2.to_inner()); 370 if !self.var_unification_table.unioned(tv1.to_inner(), tv2.to_inner()) {
371 self.var_unification_table.union(tv1.to_inner(), tv2.to_inner());
372 self.revision += 1;
373 }
364 true 374 true
365 } 375 }
366 376
@@ -398,6 +408,7 @@ impl InferenceTable {
398 tv.to_inner(), 408 tv.to_inner(),
399 TypeVarValue::Known(other.clone().intern(&Interner)), 409 TypeVarValue::Known(other.clone().intern(&Interner)),
400 ); 410 );
411 self.revision += 1;
401 true 412 true
402 } 413 }
403 414
@@ -447,7 +458,7 @@ impl InferenceTable {
447 if i > 0 { 458 if i > 0 {
448 cov_mark::hit!(type_var_resolves_to_int_var); 459 cov_mark::hit!(type_var_resolves_to_int_var);
449 } 460 }
450 match ty.interned(&Interner) { 461 match ty.kind(&Interner) {
451 TyKind::InferenceVar(tv, _) => { 462 TyKind::InferenceVar(tv, _) => {
452 let inner = tv.to_inner(); 463 let inner = tv.to_inner();
453 match self.var_unification_table.inlined_probe_value(inner).known() { 464 match self.var_unification_table.inlined_probe_value(inner).known() {
@@ -470,7 +481,7 @@ impl InferenceTable {
470 /// be resolved as far as possible, i.e. contain no type variables with 481 /// be resolved as far as possible, i.e. contain no type variables with
471 /// known type. 482 /// known type.
472 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 483 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
473 ty.fold(&mut |ty| match ty.interned(&Interner) { 484 ty.fold(&mut |ty| match ty.kind(&Interner) {
474 &TyKind::InferenceVar(tv, kind) => { 485 &TyKind::InferenceVar(tv, kind) => {
475 let inner = tv.to_inner(); 486 let inner = tv.to_inner();
476 if tv_stack.contains(&inner) { 487 if tv_stack.contains(&inner) {
@@ -497,7 +508,7 @@ impl InferenceTable {
497 /// Resolves the type completely; type variables without known type are 508 /// Resolves the type completely; type variables without known type are
498 /// replaced by TyKind::Unknown. 509 /// replaced by TyKind::Unknown.
499 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 510 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
500 ty.fold(&mut |ty| match ty.interned(&Interner) { 511 ty.fold(&mut |ty| match ty.kind(&Interner) {
501 &TyKind::InferenceVar(tv, kind) => { 512 &TyKind::InferenceVar(tv, kind) => {
502 let inner = tv.to_inner(); 513 let inner = tv.to_inner();
503 if tv_stack.contains(&inner) { 514 if tv_stack.contains(&inner) {