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.rs138
-rw-r--r--crates/hir_ty/src/infer/pat.rs47
-rw-r--r--crates/hir_ty/src/infer/path.rs33
-rw-r--r--crates/hir_ty/src/infer/unify.rs80
5 files changed, 154 insertions, 183 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 6279aa572..ccaae53e9 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
@@ -138,7 +133,7 @@ impl<'a> InferenceContext<'a> {
138 both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe); 133 both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe);
139 let else_ty = match else_branch { 134 let else_ty = match else_branch {
140 Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), 135 Some(else_branch) => self.infer_expr_inner(*else_branch, &expected),
141 None => Ty::unit(), 136 None => TyBuilder::unit(),
142 }; 137 };
143 both_arms_diverge &= self.diverges; 138 both_arms_diverge &= self.diverges;
144 139
@@ -193,7 +188,7 @@ impl<'a> InferenceContext<'a> {
193 break_ty: self.table.new_type_var(), 188 break_ty: self.table.new_type_var(),
194 label: label.map(|label| self.body[label].name.clone()), 189 label: label.map(|label| self.body[label].name.clone()),
195 }); 190 });
196 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 191 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
197 192
198 let ctxt = self.breakables.pop().expect("breakable stack broken"); 193 let ctxt = self.breakables.pop().expect("breakable stack broken");
199 if ctxt.may_break { 194 if ctxt.may_break {
@@ -217,11 +212,11 @@ impl<'a> InferenceContext<'a> {
217 *condition, 212 *condition,
218 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), 213 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)),
219 ); 214 );
220 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 215 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
221 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 216 let _ctxt = self.breakables.pop().expect("breakable stack broken");
222 // 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
223 self.diverges = Diverges::Maybe; 218 self.diverges = Diverges::Maybe;
224 Ty::unit() 219 TyBuilder::unit()
225 } 220 }
226 Expr::For { iterable, body, pat, label } => { 221 Expr::For { iterable, body, pat, label } => {
227 let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); 222 let iterable_ty = self.infer_expr(*iterable, &Expectation::none());
@@ -236,11 +231,11 @@ impl<'a> InferenceContext<'a> {
236 231
237 self.infer_pat(*pat, &pat_ty, BindingMode::default()); 232 self.infer_pat(*pat, &pat_ty, BindingMode::default());
238 233
239 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 234 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
240 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 235 let _ctxt = self.breakables.pop().expect("breakable stack broken");
241 // 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
242 self.diverges = Diverges::Maybe; 237 self.diverges = Diverges::Maybe;
243 Ty::unit() 238 TyBuilder::unit()
244 } 239 }
245 Expr::Lambda { body, args, ret_type, arg_types } => { 240 Expr::Lambda { body, args, ret_type, arg_types } => {
246 assert_eq!(args.len(), arg_types.len()); 241 assert_eq!(args.len(), arg_types.len());
@@ -266,7 +261,7 @@ impl<'a> InferenceContext<'a> {
266 let sig_ty = TyKind::Function(FnPointer { 261 let sig_ty = TyKind::Function(FnPointer {
267 num_args: sig_tys.len() - 1, 262 num_args: sig_tys.len() - 1,
268 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, 263 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
269 substs: Substitution(sig_tys.clone().into()), 264 substs: Substitution::from_iter(&Interner, sig_tys.clone()),
270 }) 265 })
271 .intern(&Interner); 266 .intern(&Interner);
272 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();
@@ -360,7 +355,7 @@ impl<'a> InferenceContext<'a> {
360 let val_ty = if let Some(expr) = expr { 355 let val_ty = if let Some(expr) = expr {
361 self.infer_expr(*expr, &Expectation::none()) 356 self.infer_expr(*expr, &Expectation::none())
362 } else { 357 } else {
363 Ty::unit() 358 TyBuilder::unit()
364 }; 359 };
365 360
366 let last_ty = 361 let last_ty =
@@ -386,7 +381,7 @@ impl<'a> InferenceContext<'a> {
386 if let Some(expr) = expr { 381 if let Some(expr) = expr {
387 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()));
388 } else { 383 } else {
389 let unit = Ty::unit(); 384 let unit = TyBuilder::unit();
390 self.coerce(&unit, &self.return_ty.clone()); 385 self.coerce(&unit, &self.return_ty.clone());
391 } 386 }
392 TyKind::Never.intern(&Interner) 387 TyKind::Never.intern(&Interner)
@@ -406,7 +401,7 @@ impl<'a> InferenceContext<'a> {
406 401
407 self.unify(&ty, &expected.ty); 402 self.unify(&ty, &expected.ty);
408 403
409 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 404 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(); 405 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)); 406 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
412 for field in fields.iter() { 407 for field in fields.iter() {
@@ -455,10 +450,10 @@ impl<'a> InferenceContext<'a> {
455 }) 450 })
456 .unwrap_or(true) 451 .unwrap_or(true)
457 }; 452 };
458 match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) { 453 match canonicalized.decanonicalize_ty(derefed_ty.value).kind(&Interner) {
459 TyKind::Tuple(_, substs) => { 454 TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| {
460 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()
461 } 456 }),
462 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { 457 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
463 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)?;
464 let field = FieldId { parent: (*s).into(), local_id }; 459 let field = FieldId { parent: (*s).into(), local_id };
@@ -535,17 +530,10 @@ impl<'a> InferenceContext<'a> {
535 Expr::Box { expr } => { 530 Expr::Box { expr } => {
536 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 531 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
537 if let Some(box_) = self.resolve_boxed_box() { 532 if let Some(box_) = self.resolve_boxed_box() {
538 let mut sb = 533 TyBuilder::adt(self.db, box_)
539 Substitution::build_for_generics(&generics(self.db.upcast(), box_.into())); 534 .push(inner_ty)
540 sb = sb.push(inner_ty); 535 .fill_with_defaults(self.db, || self.table.new_type_var())
541 match self.db.generic_defaults(box_.into()).get(1) { 536 .build()
542 Some(alloc_ty) if !alloc_ty.value.is_unknown() && sb.remaining() > 0 => {
543 sb = sb.push(alloc_ty.value.clone());
544 }
545 _ => (),
546 }
547 sb = sb.fill(repeat_with(|| self.table.new_type_var()));
548 Ty::adt_ty(box_, sb.build())
549 } else { 537 } else {
550 self.err_ty() 538 self.err_ty()
551 } 539 }
@@ -573,7 +561,7 @@ impl<'a> InferenceContext<'a> {
573 None => self.err_ty(), 561 None => self.err_ty(),
574 }, 562 },
575 UnaryOp::Neg => { 563 UnaryOp::Neg => {
576 match inner_ty.interned(&Interner) { 564 match inner_ty.kind(&Interner) {
577 // Fast path for builtins 565 // Fast path for builtins
578 TyKind::Scalar(Scalar::Int(_)) 566 TyKind::Scalar(Scalar::Int(_))
579 | TyKind::Scalar(Scalar::Uint(_)) 567 | TyKind::Scalar(Scalar::Uint(_))
@@ -586,7 +574,7 @@ impl<'a> InferenceContext<'a> {
586 } 574 }
587 } 575 }
588 UnaryOp::Not => { 576 UnaryOp::Not => {
589 match inner_ty.interned(&Interner) { 577 match inner_ty.kind(&Interner) {
590 // Fast path for builtins 578 // Fast path for builtins
591 TyKind::Scalar(Scalar::Bool) 579 TyKind::Scalar(Scalar::Bool)
592 | TyKind::Scalar(Scalar::Int(_)) 580 | TyKind::Scalar(Scalar::Int(_))
@@ -635,31 +623,31 @@ impl<'a> InferenceContext<'a> {
635 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));
636 match (range_type, lhs_ty, rhs_ty) { 624 match (range_type, lhs_ty, rhs_ty) {
637 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 625 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
638 Some(adt) => Ty::adt_ty(adt, Substitution::empty()), 626 Some(adt) => TyBuilder::adt(self.db, adt).build(),
639 None => self.err_ty(), 627 None => self.err_ty(),
640 }, 628 },
641 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 629 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
642 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 630 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
643 None => self.err_ty(), 631 None => self.err_ty(),
644 }, 632 },
645 (RangeOp::Inclusive, None, Some(ty)) => { 633 (RangeOp::Inclusive, None, Some(ty)) => {
646 match self.resolve_range_to_inclusive() { 634 match self.resolve_range_to_inclusive() {
647 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 635 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
648 None => self.err_ty(), 636 None => self.err_ty(),
649 } 637 }
650 } 638 }
651 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 639 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
652 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 640 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
653 None => self.err_ty(), 641 None => self.err_ty(),
654 }, 642 },
655 (RangeOp::Inclusive, Some(_), Some(ty)) => { 643 (RangeOp::Inclusive, Some(_), Some(ty)) => {
656 match self.resolve_range_inclusive() { 644 match self.resolve_range_inclusive() {
657 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 645 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
658 None => self.err_ty(), 646 None => self.err_ty(),
659 } 647 }
660 } 648 }
661 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 649 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
662 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 650 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
663 None => self.err_ty(), 651 None => self.err_ty(),
664 }, 652 },
665 (RangeOp::Inclusive, _, None) => self.err_ty(), 653 (RangeOp::Inclusive, _, None) => self.err_ty(),
@@ -692,10 +680,10 @@ impl<'a> InferenceContext<'a> {
692 } 680 }
693 } 681 }
694 Expr::Tuple { exprs } => { 682 Expr::Tuple { exprs } => {
695 let mut tys = match expected.ty.interned(&Interner) { 683 let mut tys = match expected.ty.kind(&Interner) {
696 TyKind::Tuple(_, substs) => substs 684 TyKind::Tuple(_, substs) => substs
697 .iter() 685 .iter(&Interner)
698 .cloned() 686 .map(|a| a.assert_ty_ref(&Interner).clone())
699 .chain(repeat_with(|| self.table.new_type_var())) 687 .chain(repeat_with(|| self.table.new_type_var()))
700 .take(exprs.len()) 688 .take(exprs.len())
701 .collect::<Vec<_>>(), 689 .collect::<Vec<_>>(),
@@ -706,10 +694,10 @@ impl<'a> InferenceContext<'a> {
706 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 694 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
707 } 695 }
708 696
709 TyKind::Tuple(tys.len(), Substitution(tys.into())).intern(&Interner) 697 TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner)
710 } 698 }
711 Expr::Array(array) => { 699 Expr::Array(array) => {
712 let elem_ty = match expected.ty.interned(&Interner) { 700 let elem_ty = match expected.ty.kind(&Interner) {
713 TyKind::Array(st) | TyKind::Slice(st) => st.clone(), 701 TyKind::Array(st) | TyKind::Slice(st) => st.clone(),
714 _ => self.table.new_type_var(), 702 _ => self.table.new_type_var(),
715 }; 703 };
@@ -824,8 +812,8 @@ impl<'a> InferenceContext<'a> {
824 // we don't even make an attempt at coercion 812 // we don't even make an attempt at coercion
825 self.table.new_maybe_never_var() 813 self.table.new_maybe_never_var()
826 } else { 814 } else {
827 self.coerce(&Ty::unit(), &expected.coercion_target()); 815 self.coerce(&TyBuilder::unit(), &expected.coercion_target());
828 Ty::unit() 816 TyBuilder::unit()
829 } 817 }
830 }; 818 };
831 ty 819 ty
@@ -953,18 +941,18 @@ impl<'a> InferenceContext<'a> {
953 substs.push(self.err_ty()); 941 substs.push(self.err_ty());
954 } 942 }
955 assert_eq!(substs.len(), total_len); 943 assert_eq!(substs.len(), total_len);
956 Substitution(substs.into()) 944 Substitution::from_iter(&Interner, substs)
957 } 945 }
958 946
959 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 947 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
960 if let TyKind::FnDef(fn_def, parameters) = callable_ty.interned(&Interner) { 948 if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(&Interner) {
961 let def: CallableDefId = from_chalk(self.db, *fn_def); 949 let def: CallableDefId = from_chalk(self.db, *fn_def);
962 let generic_predicates = self.db.generic_predicates(def.into()); 950 let generic_predicates = self.db.generic_predicates(def.into());
963 for predicate in generic_predicates.iter() { 951 for predicate in generic_predicates.iter() {
964 let (predicate, binders) = 952 let (predicate, binders) =
965 predicate.clone().subst(parameters).into_value_and_skipped_binders(); 953 predicate.clone().subst(parameters).into_value_and_skipped_binders();
966 always!(binders == 0); // quantified where clauses not yet handled 954 always!(binders == 0); // quantified where clauses not yet handled
967 self.obligations.push(predicate.cast(&Interner)); 955 self.push_obligation(predicate.cast(&Interner));
968 } 956 }
969 // add obligation for trait implementation, if this is a trait method 957 // add obligation for trait implementation, if this is a trait method
970 match def { 958 match def {
@@ -974,7 +962,7 @@ impl<'a> InferenceContext<'a> {
974 // construct a TraitRef 962 // construct a TraitRef
975 let substs = 963 let substs =
976 parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); 964 parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
977 self.obligations.push( 965 self.push_obligation(
978 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs } 966 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }
979 .cast(&Interner), 967 .cast(&Interner),
980 ); 968 );
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 474363709..469f37dd9 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 {
@@ -74,7 +73,7 @@ impl<'a> InferenceContext<'a> {
74 73
75 self.unify(&ty, expected); 74 self.unify(&ty, expected);
76 75
77 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 76 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
78 77
79 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 78 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
80 for subpat in subpats { 79 for subpat in subpats {
@@ -124,7 +123,7 @@ impl<'a> InferenceContext<'a> {
124 let ty = match &body[pat] { 123 let ty = match &body[pat] {
125 &Pat::Tuple { ref args, ellipsis } => { 124 &Pat::Tuple { ref args, ellipsis } => {
126 let expectations = match expected.as_tuple() { 125 let expectations = match expected.as_tuple() {
127 Some(parameters) => &*parameters.0, 126 Some(parameters) => &*parameters.interned(),
128 _ => &[], 127 _ => &[],
129 }; 128 };
130 129
@@ -134,7 +133,8 @@ impl<'a> InferenceContext<'a> {
134 }; 133 };
135 let n_uncovered_patterns = expectations.len().saturating_sub(args.len()); 134 let n_uncovered_patterns = expectations.len().saturating_sub(args.len());
136 let err_ty = self.err_ty(); 135 let err_ty = self.err_ty();
137 let mut expectations_iter = expectations.iter().chain(repeat(&err_ty)); 136 let mut expectations_iter =
137 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); 138 let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm);
139 139
140 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len()); 140 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len());
@@ -142,7 +142,8 @@ impl<'a> InferenceContext<'a> {
142 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); 142 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
143 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); 143 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
144 144
145 TyKind::Tuple(inner_tys.len(), Substitution(inner_tys.into())).intern(&Interner) 145 TyKind::Tuple(inner_tys.len(), Substitution::from_iter(&Interner, inner_tys))
146 .intern(&Interner)
146 } 147 }
147 Pat::Or(ref pats) => { 148 Pat::Or(ref pats) => {
148 if let Some((first_pat, rest)) = pats.split_first() { 149 if let Some((first_pat, rest)) = pats.split_first() {
@@ -209,7 +210,7 @@ impl<'a> InferenceContext<'a> {
209 return inner_ty; 210 return inner_ty;
210 } 211 }
211 Pat::Slice { prefix, slice, suffix } => { 212 Pat::Slice { prefix, slice, suffix } => {
212 let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.interned(&Interner) { 213 let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.kind(&Interner) {
213 TyKind::Array(st) => (TyKind::Array, st.clone()), 214 TyKind::Array(st) => (TyKind::Array, st.clone()),
214 TyKind::Slice(st) => (TyKind::Slice, st.clone()), 215 TyKind::Slice(st) => (TyKind::Slice, st.clone()),
215 _ => (TyKind::Slice, self.err_ty()), 216 _ => (TyKind::Slice, self.err_ty()),
@@ -236,30 +237,20 @@ impl<'a> InferenceContext<'a> {
236 Pat::Box { inner } => match self.resolve_boxed_box() { 237 Pat::Box { inner } => match self.resolve_boxed_box() {
237 Some(box_adt) => { 238 Some(box_adt) => {
238 let (inner_ty, alloc_ty) = match expected.as_adt() { 239 let (inner_ty, alloc_ty) = match expected.as_adt() {
239 Some((adt, subst)) if adt == box_adt => { 240 Some((adt, subst)) if adt == box_adt => (
240 (subst[0].clone(), subst.get(1).cloned()) 241 subst.at(&Interner, 0).assert_ty_ref(&Interner).clone(),
241 } 242 subst.interned().get(1).and_then(|a| a.ty(&Interner).cloned()),
243 ),
242 _ => (self.result.standard_types.unknown.clone(), None), 244 _ => (self.result.standard_types.unknown.clone(), None),
243 }; 245 };
244 246
245 let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm); 247 let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm);
246 let mut sb = Substitution::build_for_generics(&generics( 248 let mut b = TyBuilder::adt(self.db, box_adt).push(inner_ty);
247 self.db.upcast(), 249
248 box_adt.into(), 250 if let Some(alloc_ty) = alloc_ty {
249 )); 251 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 } 252 }
262 Ty::adt_ty(box_adt, sb.build()) 253 b.fill_with_defaults(self.db, || self.table.new_type_var()).build()
263 } 254 }
264 None => self.err_ty(), 255 None => self.err_ty(),
265 }, 256 },
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs
index cefa38509..637341b53 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,7 +80,7 @@ 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).subst(&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()).subst(&substs);
@@ -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::Unknown = 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::Unknown = ty.kind(&Interner) {
216 return None; 211 return None;
217 } 212 }
218 213
@@ -245,7 +240,7 @@ 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 = self.db.impl_self_ty(impl_id).subst(&impl_substs);
@@ -254,18 +249,12 @@ impl<'a> InferenceContext<'a> {
254 } 249 }
255 AssocContainerId::TraitId(trait_) => { 250 AssocContainerId::TraitId(trait_) => {
256 // we're picking this method 251 // we're picking this method
257 let trait_substs = Substitution::build_for_def(self.db, trait_) 252 let trait_ref = TyBuilder::trait_ref(self.db, trait_)
258 .push(ty.clone()) 253 .push(ty.clone())
259 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 254 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
260 .build(); 255 .build();
261 self.obligations.push( 256 self.push_obligation(trait_ref.clone().cast(&Interner));
262 TraitRef { 257 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 } 258 }
270 AssocContainerId::ModuleId(_) => None, 259 AssocContainerId::ModuleId(_) => None,
271 }; 260 };
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 6e7b0f5a6..b7bc48569 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) {
@@ -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,
@@ -186,11 +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(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) 191 vars.iter(&Interner)
192 .build(), 192 .map(|v| table.resolve_ty_completely(v.assert_ty_ref(&Interner).clone())),
193 ) 193 ))
194} 194}
195 195
196#[derive(Clone, Debug)] 196#[derive(Clone, Debug)]
@@ -231,6 +231,7 @@ pub(crate) struct TypeVariableData {
231pub(crate) struct InferenceTable { 231pub(crate) struct InferenceTable {
232 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>, 232 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>,
233 pub(super) type_variable_table: TypeVariableTable, 233 pub(super) type_variable_table: TypeVariableTable,
234 pub(super) revision: u32,
234} 235}
235 236
236impl InferenceTable { 237impl InferenceTable {
@@ -238,6 +239,7 @@ impl InferenceTable {
238 InferenceTable { 239 InferenceTable {
239 var_unification_table: InPlaceUnificationTable::new(), 240 var_unification_table: InPlaceUnificationTable::new(),
240 type_variable_table: TypeVariableTable { inner: Vec::new() }, 241 type_variable_table: TypeVariableTable { inner: Vec::new() },
242 revision: 0,
241 } 243 }
242 } 244 }
243 245
@@ -282,7 +284,9 @@ impl InferenceTable {
282 substs2: &Substitution, 284 substs2: &Substitution,
283 depth: usize, 285 depth: usize,
284 ) -> bool { 286 ) -> bool {
285 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth)) 287 substs1.iter(&Interner).zip(substs2.iter(&Interner)).all(|(t1, t2)| {
288 self.unify_inner(t1.assert_ty_ref(&Interner), t2.assert_ty_ref(&Interner), depth)
289 })
286 } 290 }
287 291
288 fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 292 fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {
@@ -297,7 +301,7 @@ impl InferenceTable {
297 let ty1 = self.resolve_ty_shallow(ty1); 301 let ty1 = self.resolve_ty_shallow(ty1);
298 let ty2 = self.resolve_ty_shallow(ty2); 302 let ty2 = self.resolve_ty_shallow(ty2);
299 if ty1.equals_ctor(&ty2) { 303 if ty1.equals_ctor(&ty2) {
300 match (ty1.interned(&Interner), ty2.interned(&Interner)) { 304 match (ty1.kind(&Interner), ty2.kind(&Interner)) {
301 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) 305 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2))
302 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) 306 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2))
303 | ( 307 | (
@@ -322,7 +326,7 @@ impl InferenceTable {
322 } 326 }
323 327
324 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 328 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {
325 match (ty1.interned(&Interner), ty2.interned(&Interner)) { 329 match (ty1.kind(&Interner), ty2.kind(&Interner)) {
326 (TyKind::Unknown, _) | (_, TyKind::Unknown) => true, 330 (TyKind::Unknown, _) | (_, TyKind::Unknown) => true,
327 331
328 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, 332 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true,
@@ -360,7 +364,10 @@ impl InferenceTable {
360 == self.type_variable_table.is_diverging(*tv2) => 364 == self.type_variable_table.is_diverging(*tv2) =>
361 { 365 {
362 // both type vars are unknown since we tried to resolve them 366 // both type vars are unknown since we tried to resolve them
363 self.var_unification_table.union(tv1.to_inner(), tv2.to_inner()); 367 if !self.var_unification_table.unioned(tv1.to_inner(), tv2.to_inner()) {
368 self.var_unification_table.union(tv1.to_inner(), tv2.to_inner());
369 self.revision += 1;
370 }
364 true 371 true
365 } 372 }
366 373
@@ -398,6 +405,7 @@ impl InferenceTable {
398 tv.to_inner(), 405 tv.to_inner(),
399 TypeVarValue::Known(other.clone().intern(&Interner)), 406 TypeVarValue::Known(other.clone().intern(&Interner)),
400 ); 407 );
408 self.revision += 1;
401 true 409 true
402 } 410 }
403 411
@@ -447,7 +455,7 @@ impl InferenceTable {
447 if i > 0 { 455 if i > 0 {
448 cov_mark::hit!(type_var_resolves_to_int_var); 456 cov_mark::hit!(type_var_resolves_to_int_var);
449 } 457 }
450 match ty.interned(&Interner) { 458 match ty.kind(&Interner) {
451 TyKind::InferenceVar(tv, _) => { 459 TyKind::InferenceVar(tv, _) => {
452 let inner = tv.to_inner(); 460 let inner = tv.to_inner();
453 match self.var_unification_table.inlined_probe_value(inner).known() { 461 match self.var_unification_table.inlined_probe_value(inner).known() {
@@ -470,7 +478,7 @@ impl InferenceTable {
470 /// be resolved as far as possible, i.e. contain no type variables with 478 /// be resolved as far as possible, i.e. contain no type variables with
471 /// known type. 479 /// known type.
472 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 480 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) { 481 ty.fold(&mut |ty| match ty.kind(&Interner) {
474 &TyKind::InferenceVar(tv, kind) => { 482 &TyKind::InferenceVar(tv, kind) => {
475 let inner = tv.to_inner(); 483 let inner = tv.to_inner();
476 if tv_stack.contains(&inner) { 484 if tv_stack.contains(&inner) {
@@ -497,7 +505,7 @@ impl InferenceTable {
497 /// Resolves the type completely; type variables without known type are 505 /// Resolves the type completely; type variables without known type are
498 /// replaced by TyKind::Unknown. 506 /// replaced by TyKind::Unknown.
499 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 507 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
500 ty.fold(&mut |ty| match ty.interned(&Interner) { 508 ty.fold(&mut |ty| match ty.kind(&Interner) {
501 &TyKind::InferenceVar(tv, kind) => { 509 &TyKind::InferenceVar(tv, kind) => {
502 let inner = tv.to_inner(); 510 let inner = tv.to_inner();
503 if tv_stack.contains(&inner) { 511 if tv_stack.contains(&inner) {