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.rs64
-rw-r--r--crates/hir_ty/src/infer/expr.rs221
-rw-r--r--crates/hir_ty/src/infer/pat.rs92
-rw-r--r--crates/hir_ty/src/infer/path.rs39
-rw-r--r--crates/hir_ty/src/infer/unify.rs266
5 files changed, 364 insertions, 318 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 9c62932b1..1f463a425 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, Canonical, Interner, Solution, Ty, TyBuilder, TyExt, 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,17 +71,19 @@ 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.kind(&Interner), to_ty.kind(&Interner)) {
77 // `*mut T` -> `*const T` 75 // `*mut T` -> `*const T`
76 (TyKind::Raw(_, inner), TyKind::Raw(m2 @ Mutability::Not, ..)) => {
77 from_ty = TyKind::Raw(*m2, inner.clone()).intern(&Interner);
78 }
78 // `&mut T` -> `&T` 79 // `&mut T` -> `&T`
79 (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) 80 (TyKind::Ref(_, lt, inner), TyKind::Ref(m2 @ Mutability::Not, ..)) => {
80 | (TyKind::Ref(m1, ..), TyKind::Ref(m2 @ Mutability::Not, ..)) => { 81 from_ty = TyKind::Ref(*m2, lt.clone(), inner.clone()).intern(&Interner);
81 *m1 = *m2;
82 } 82 }
83 // `&T` -> `*const T` 83 // `&T` -> `*const T`
84 // `&mut T` -> `*mut T`/`*const T` 84 // `&mut T` -> `*mut T`/`*const T`
85 (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..)) 85 (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..))
86 | (TyKind::Ref(Mutability::Mut, substs), &TyKind::Raw(m2, ..)) => { 86 | (TyKind::Ref(Mutability::Mut, _, substs), &TyKind::Raw(m2, ..)) => {
87 from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner); 87 from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner);
88 } 88 }
89 89
@@ -95,12 +95,12 @@ impl<'a> InferenceContext<'a> {
95 (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) { 95 (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) {
96 None => return false, 96 None => return false,
97 Some(sig) => { 97 Some(sig) => {
98 from_ty = Ty::fn_ptr(sig); 98 from_ty = TyBuilder::fn_ptr(sig);
99 } 99 }
100 }, 100 },
101 101
102 (TyKind::Closure(.., substs), TyKind::Function { .. }) => { 102 (TyKind::Closure(.., substs), TyKind::Function { .. }) => {
103 from_ty = substs[0].clone(); 103 from_ty = substs.at(&Interner, 0).assert_ty_ref(&Interner).clone();
104 } 104 }
105 105
106 _ => {} 106 _ => {}
@@ -111,9 +111,11 @@ impl<'a> InferenceContext<'a> {
111 } 111 }
112 112
113 // Auto Deref if cannot coerce 113 // Auto Deref if cannot coerce
114 match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { 114 match (from_ty.kind(&Interner), to_ty.kind(&Interner)) {
115 // FIXME: DerefMut 115 // FIXME: DerefMut
116 (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => self.unify_autoderef_behind_ref(st1, st2), 116 (TyKind::Ref(.., st1), TyKind::Ref(.., st2)) => {
117 self.unify_autoderef_behind_ref(st1, st2)
118 }
117 119
118 // Otherwise, normal unify 120 // Otherwise, normal unify
119 _ => self.unify(&from_ty, to_ty), 121 _ => self.unify(&from_ty, to_ty),
@@ -130,19 +132,16 @@ impl<'a> InferenceContext<'a> {
130 _ => return None, 132 _ => return None,
131 }; 133 };
132 134
133 let generic_params = crate::utils::generics(self.db.upcast(), coerce_unsized_trait.into()); 135 let trait_ref = {
134 if generic_params.len() != 2 { 136 let b = TyBuilder::trait_ref(self.db, coerce_unsized_trait);
135 // The CoerceUnsized trait should have two generic params: Self and T. 137 if b.remaining() != 2 {
136 return None; 138 // The CoerceUnsized trait should have two generic params: Self and T.
137 } 139 return None;
140 }
141 b.push(from_ty.clone()).push(to_ty.clone()).build()
142 };
138 143
139 let substs = Substitution::build_for_generics(&generic_params) 144 let goal = InEnvironment::new(&self.trait_env.env, trait_ref.cast(&Interner));
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));
146 145
147 let canonicalizer = self.canonicalizer(); 146 let canonicalizer = self.canonicalizer();
148 let canonicalized = canonicalizer.canonicalize_obligation(goal); 147 let canonicalized = canonicalizer.canonicalize_obligation(goal);
@@ -151,7 +150,14 @@ impl<'a> InferenceContext<'a> {
151 150
152 match solution { 151 match solution {
153 Solution::Unique(v) => { 152 Solution::Unique(v) => {
154 canonicalized.apply_solution(self, v.0); 153 canonicalized.apply_solution(
154 self,
155 Canonical {
156 binders: v.binders,
157 // FIXME handle constraints
158 value: v.value.subst,
159 },
160 );
155 } 161 }
156 _ => return None, 162 _ => return None,
157 }; 163 };
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index e6ede05ca..50497eecb 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -3,7 +3,7 @@
3use std::iter::{repeat, repeat_with}; 3use std::iter::{repeat, repeat_with};
4use std::{mem, sync::Arc}; 4use std::{mem, sync::Arc};
5 5
6use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; 6use chalk_ir::{cast::Cast, fold::Shift, Mutability, TyVariableKind};
7use hir_def::{ 7use hir_def::{
8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
9 path::{GenericArg, GenericArgs}, 9 path::{GenericArg, GenericArgs},
@@ -15,15 +15,16 @@ use stdx::always;
15use syntax::ast::RangeOp; 15use syntax::ast::RangeOp;
16 16
17use crate::{ 17use crate::{
18 autoderef, 18 autoderef, dummy_usize_const,
19 lower::lower_to_chalk_mutability, 19 lower::lower_to_chalk_mutability,
20 mapping::from_chalk,
20 method_resolution, op, 21 method_resolution, op,
21 primitive::{self, UintTy}, 22 primitive::{self, UintTy},
22 to_assoc_type_id, to_chalk_trait_id, 23 static_lifetime, to_chalk_trait_id,
23 traits::{chalk::from_chalk, FnTrait, InEnvironment}, 24 traits::FnTrait,
24 utils::{generics, variant_data, Generics}, 25 utils::{generics, Generics},
25 AdtId, Binders, CallableDefId, DomainGoal, FnPointer, FnSig, Interner, Rawness, Scalar, 26 AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner,
26 Substitution, TraitRef, Ty, TyKind, 27 ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind,
27}; 28};
28 29
29use super::{ 30use super::{
@@ -73,38 +74,33 @@ impl<'a> InferenceContext<'a> {
73 let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?; 74 let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?;
74 let output_assoc_type = 75 let output_assoc_type =
75 self.db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?; 76 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 77
81 let mut param_builder = Substitution::builder(num_args);
82 let mut arg_tys = vec![]; 78 let mut arg_tys = vec![];
83 for _ in 0..num_args { 79 let arg_ty = TyBuilder::tuple(num_args)
84 let arg = self.table.new_type_var(); 80 .fill(repeat_with(|| {
85 param_builder = param_builder.push(arg.clone()); 81 let arg = self.table.new_type_var();
86 arg_tys.push(arg); 82 arg_tys.push(arg.clone());
87 } 83 arg
88 let parameters = param_builder.build(); 84 }))
89 let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner); 85 .build();
90 let substs = 86
91 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 87 let projection = {
88 let b = TyBuilder::assoc_type_projection(self.db, output_assoc_type);
89 if b.remaining() != 2 {
90 return None;
91 }
92 b.push(ty.clone()).push(arg_ty).build()
93 };
92 94
93 let trait_env = self.trait_env.env.clone(); 95 let trait_env = self.trait_env.env.clone();
94 let implements_fn_trait: DomainGoal = 96 let obligation = InEnvironment {
95 TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() } 97 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, 98 environment: trait_env,
100 }); 99 };
101 if self.db.trait_solve(krate, goal.value).is_some() { 100 let canonical = self.canonicalizer().canonicalize_obligation(obligation.clone());
102 self.obligations.push(implements_fn_trait); 101 if self.db.trait_solve(krate, canonical.value).is_some() {
103 let output_proj_ty = crate::ProjectionTy { 102 self.push_obligation(obligation.goal);
104 associated_ty_id: to_assoc_type_id(output_assoc_type), 103 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)) 104 Some((arg_tys, return_ty))
109 } else { 105 } else {
110 None 106 None
@@ -119,6 +115,8 @@ impl<'a> InferenceContext<'a> {
119 } 115 }
120 116
121 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { 117 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
118 self.db.check_canceled();
119
122 let body = Arc::clone(&self.body); // avoid borrow checker problem 120 let body = Arc::clone(&self.body); // avoid borrow checker problem
123 let ty = match &body[tgt_expr] { 121 let ty = match &body[tgt_expr] {
124 Expr::Missing => self.err_ty(), 122 Expr::Missing => self.err_ty(),
@@ -136,7 +134,7 @@ impl<'a> InferenceContext<'a> {
136 both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe); 134 both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe);
137 let else_ty = match else_branch { 135 let else_ty = match else_branch {
138 Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), 136 Some(else_branch) => self.infer_expr_inner(*else_branch, &expected),
139 None => Ty::unit(), 137 None => TyBuilder::unit(),
140 }; 138 };
141 both_arms_diverge &= self.diverges; 139 both_arms_diverge &= self.diverges;
142 140
@@ -183,7 +181,8 @@ impl<'a> InferenceContext<'a> {
183 let inner_ty = self.infer_expr(*body, &Expectation::none()); 181 let inner_ty = self.infer_expr(*body, &Expectation::none());
184 let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body); 182 let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body);
185 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into(); 183 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
186 TyKind::OpaqueType(opaque_ty_id, Substitution::single(inner_ty)).intern(&Interner) 184 TyKind::OpaqueType(opaque_ty_id, Substitution::from1(&Interner, inner_ty))
185 .intern(&Interner)
187 } 186 }
188 Expr::Loop { body, label } => { 187 Expr::Loop { body, label } => {
189 self.breakables.push(BreakableContext { 188 self.breakables.push(BreakableContext {
@@ -191,7 +190,7 @@ impl<'a> InferenceContext<'a> {
191 break_ty: self.table.new_type_var(), 190 break_ty: self.table.new_type_var(),
192 label: label.map(|label| self.body[label].name.clone()), 191 label: label.map(|label| self.body[label].name.clone()),
193 }); 192 });
194 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 193 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
195 194
196 let ctxt = self.breakables.pop().expect("breakable stack broken"); 195 let ctxt = self.breakables.pop().expect("breakable stack broken");
197 if ctxt.may_break { 196 if ctxt.may_break {
@@ -215,11 +214,11 @@ impl<'a> InferenceContext<'a> {
215 *condition, 214 *condition,
216 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), 215 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)),
217 ); 216 );
218 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 217 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
219 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 218 let _ctxt = self.breakables.pop().expect("breakable stack broken");
220 // the body may not run, so it diverging doesn't mean we diverge 219 // the body may not run, so it diverging doesn't mean we diverge
221 self.diverges = Diverges::Maybe; 220 self.diverges = Diverges::Maybe;
222 Ty::unit() 221 TyBuilder::unit()
223 } 222 }
224 Expr::For { iterable, body, pat, label } => { 223 Expr::For { iterable, body, pat, label } => {
225 let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); 224 let iterable_ty = self.infer_expr(*iterable, &Expectation::none());
@@ -234,11 +233,11 @@ impl<'a> InferenceContext<'a> {
234 233
235 self.infer_pat(*pat, &pat_ty, BindingMode::default()); 234 self.infer_pat(*pat, &pat_ty, BindingMode::default());
236 235
237 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 236 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
238 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 237 let _ctxt = self.breakables.pop().expect("breakable stack broken");
239 // the body may not run, so it diverging doesn't mean we diverge 238 // the body may not run, so it diverging doesn't mean we diverge
240 self.diverges = Diverges::Maybe; 239 self.diverges = Diverges::Maybe;
241 Ty::unit() 240 TyBuilder::unit()
242 } 241 }
243 Expr::Lambda { body, args, ret_type, arg_types } => { 242 Expr::Lambda { body, args, ret_type, arg_types } => {
244 assert_eq!(args.len(), arg_types.len()); 243 assert_eq!(args.len(), arg_types.len());
@@ -262,14 +261,17 @@ impl<'a> InferenceContext<'a> {
262 }; 261 };
263 sig_tys.push(ret_ty.clone()); 262 sig_tys.push(ret_ty.clone());
264 let sig_ty = TyKind::Function(FnPointer { 263 let sig_ty = TyKind::Function(FnPointer {
265 num_args: sig_tys.len() - 1, 264 num_binders: 0,
266 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, 265 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
267 substs: Substitution(sig_tys.clone().into()), 266 substitution: FnSubst(
267 Substitution::from_iter(&Interner, sig_tys.clone()).shifted_in(&Interner),
268 ),
268 }) 269 })
269 .intern(&Interner); 270 .intern(&Interner);
270 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); 271 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();
271 let closure_ty = 272 let closure_ty =
272 TyKind::Closure(closure_id, Substitution::single(sig_ty)).intern(&Interner); 273 TyKind::Closure(closure_id, Substitution::from1(&Interner, sig_ty))
274 .intern(&Interner);
273 275
274 // Eagerly try to relate the closure type with the expected 276 // Eagerly try to relate the closure type with the expected
275 // type, otherwise we often won't have enough information to 277 // type, otherwise we often won't have enough information to
@@ -316,7 +318,13 @@ impl<'a> InferenceContext<'a> {
316 self.normalize_associated_types_in(ret_ty) 318 self.normalize_associated_types_in(ret_ty)
317 } 319 }
318 Expr::MethodCall { receiver, args, method_name, generic_args } => self 320 Expr::MethodCall { receiver, args, method_name, generic_args } => self
319 .infer_method_call(tgt_expr, *receiver, &args, &method_name, generic_args.as_ref()), 321 .infer_method_call(
322 tgt_expr,
323 *receiver,
324 &args,
325 &method_name,
326 generic_args.as_deref(),
327 ),
320 Expr::Match { expr, arms } => { 328 Expr::Match { expr, arms } => {
321 let input_ty = self.infer_expr(*expr, &Expectation::none()); 329 let input_ty = self.infer_expr(*expr, &Expectation::none());
322 330
@@ -358,7 +366,7 @@ impl<'a> InferenceContext<'a> {
358 let val_ty = if let Some(expr) = expr { 366 let val_ty = if let Some(expr) = expr {
359 self.infer_expr(*expr, &Expectation::none()) 367 self.infer_expr(*expr, &Expectation::none())
360 } else { 368 } else {
361 Ty::unit() 369 TyBuilder::unit()
362 }; 370 };
363 371
364 let last_ty = 372 let last_ty =
@@ -384,7 +392,7 @@ impl<'a> InferenceContext<'a> {
384 if let Some(expr) = expr { 392 if let Some(expr) = expr {
385 self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone())); 393 self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone()));
386 } else { 394 } else {
387 let unit = Ty::unit(); 395 let unit = TyBuilder::unit();
388 self.coerce(&unit, &self.return_ty.clone()); 396 self.coerce(&unit, &self.return_ty.clone());
389 } 397 }
390 TyKind::Never.intern(&Interner) 398 TyKind::Never.intern(&Interner)
@@ -397,16 +405,19 @@ impl<'a> InferenceContext<'a> {
397 TyKind::Never.intern(&Interner) 405 TyKind::Never.intern(&Interner)
398 } 406 }
399 Expr::RecordLit { path, fields, spread } => { 407 Expr::RecordLit { path, fields, spread } => {
400 let (ty, def_id) = self.resolve_variant(path.as_ref()); 408 let (ty, def_id) = self.resolve_variant(path.as_deref());
401 if let Some(variant) = def_id { 409 if let Some(variant) = def_id {
402 self.write_variant_resolution(tgt_expr.into(), variant); 410 self.write_variant_resolution(tgt_expr.into(), variant);
403 } 411 }
404 412
405 self.unify(&ty, &expected.ty); 413 self.unify(&ty, &expected.ty);
406 414
407 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 415 let substs = ty
416 .as_adt()
417 .map(|(_, s)| s.clone())
418 .unwrap_or_else(|| Substitution::empty(&Interner));
408 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); 419 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)); 420 let variant_data = def_id.map(|it| it.variant_data(self.db.upcast()));
410 for field in fields.iter() { 421 for field in fields.iter() {
411 let field_def = 422 let field_def =
412 variant_data.as_ref().and_then(|it| match it.field(&field.name) { 423 variant_data.as_ref().and_then(|it| match it.field(&field.name) {
@@ -418,11 +429,8 @@ impl<'a> InferenceContext<'a> {
418 None 429 None
419 } 430 }
420 }); 431 });
421 if let Some(field_def) = field_def {
422 self.result.record_field_resolutions.insert(field.expr, field_def);
423 }
424 let field_ty = field_def.map_or(self.err_ty(), |it| { 432 let field_ty = field_def.map_or(self.err_ty(), |it| {
425 field_types[it.local_id].clone().subst(&substs) 433 field_types[it.local_id].clone().substitute(&Interner, &substs)
426 }); 434 });
427 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); 435 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
428 } 436 }
@@ -453,10 +461,14 @@ impl<'a> InferenceContext<'a> {
453 }) 461 })
454 .unwrap_or(true) 462 .unwrap_or(true)
455 }; 463 };
456 match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) { 464 match canonicalized.decanonicalize_ty(derefed_ty.value).kind(&Interner) {
457 TyKind::Tuple(_, substs) => { 465 TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| {
458 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) 466 substs
459 } 467 .as_slice(&Interner)
468 .get(idx)
469 .map(|a| a.assert_ty_ref(&Interner))
470 .cloned()
471 }),
460 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { 472 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
461 let local_id = self.db.struct_data(*s).variant_data.field(name)?; 473 let local_id = self.db.struct_data(*s).variant_data.field(name)?;
462 let field = FieldId { parent: (*s).into(), local_id }; 474 let field = FieldId { parent: (*s).into(), local_id };
@@ -465,7 +477,7 @@ impl<'a> InferenceContext<'a> {
465 Some( 477 Some(
466 self.db.field_types((*s).into())[field.local_id] 478 self.db.field_types((*s).into())[field.local_id]
467 .clone() 479 .clone()
468 .subst(&parameters), 480 .substitute(&Interner, &parameters),
469 ) 481 )
470 } else { 482 } else {
471 None 483 None
@@ -479,7 +491,7 @@ impl<'a> InferenceContext<'a> {
479 Some( 491 Some(
480 self.db.field_types((*u).into())[field.local_id] 492 self.db.field_types((*u).into())[field.local_id]
481 .clone() 493 .clone()
482 .subst(&parameters), 494 .substitute(&Interner, &parameters),
483 ) 495 )
484 } else { 496 } else {
485 None 497 None
@@ -526,24 +538,17 @@ impl<'a> InferenceContext<'a> {
526 let inner_ty = self.infer_expr_inner(*expr, &expectation); 538 let inner_ty = self.infer_expr_inner(*expr, &expectation);
527 match rawness { 539 match rawness {
528 Rawness::RawPtr => TyKind::Raw(mutability, inner_ty), 540 Rawness::RawPtr => TyKind::Raw(mutability, inner_ty),
529 Rawness::Ref => TyKind::Ref(mutability, inner_ty), 541 Rawness::Ref => TyKind::Ref(mutability, static_lifetime(), inner_ty),
530 } 542 }
531 .intern(&Interner) 543 .intern(&Interner)
532 } 544 }
533 Expr::Box { expr } => { 545 Expr::Box { expr } => {
534 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 546 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
535 if let Some(box_) = self.resolve_boxed_box() { 547 if let Some(box_) = self.resolve_boxed_box() {
536 let mut sb = 548 TyBuilder::adt(self.db, box_)
537 Substitution::build_for_generics(&generics(self.db.upcast(), box_.into())); 549 .push(inner_ty)
538 sb = sb.push(inner_ty); 550 .fill_with_defaults(self.db, || self.table.new_type_var())
539 match self.db.generic_defaults(box_.into()).get(1) { 551 .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 { 552 } else {
548 self.err_ty() 553 self.err_ty()
549 } 554 }
@@ -571,7 +576,7 @@ impl<'a> InferenceContext<'a> {
571 None => self.err_ty(), 576 None => self.err_ty(),
572 }, 577 },
573 UnaryOp::Neg => { 578 UnaryOp::Neg => {
574 match inner_ty.interned(&Interner) { 579 match inner_ty.kind(&Interner) {
575 // Fast path for builtins 580 // Fast path for builtins
576 TyKind::Scalar(Scalar::Int(_)) 581 TyKind::Scalar(Scalar::Int(_))
577 | TyKind::Scalar(Scalar::Uint(_)) 582 | TyKind::Scalar(Scalar::Uint(_))
@@ -584,7 +589,7 @@ impl<'a> InferenceContext<'a> {
584 } 589 }
585 } 590 }
586 UnaryOp::Not => { 591 UnaryOp::Not => {
587 match inner_ty.interned(&Interner) { 592 match inner_ty.kind(&Interner) {
588 // Fast path for builtins 593 // Fast path for builtins
589 TyKind::Scalar(Scalar::Bool) 594 TyKind::Scalar(Scalar::Bool)
590 | TyKind::Scalar(Scalar::Int(_)) 595 | TyKind::Scalar(Scalar::Int(_))
@@ -633,31 +638,31 @@ impl<'a> InferenceContext<'a> {
633 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); 638 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
634 match (range_type, lhs_ty, rhs_ty) { 639 match (range_type, lhs_ty, rhs_ty) {
635 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 640 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
636 Some(adt) => Ty::adt_ty(adt, Substitution::empty()), 641 Some(adt) => TyBuilder::adt(self.db, adt).build(),
637 None => self.err_ty(), 642 None => self.err_ty(),
638 }, 643 },
639 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 644 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
640 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 645 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
641 None => self.err_ty(), 646 None => self.err_ty(),
642 }, 647 },
643 (RangeOp::Inclusive, None, Some(ty)) => { 648 (RangeOp::Inclusive, None, Some(ty)) => {
644 match self.resolve_range_to_inclusive() { 649 match self.resolve_range_to_inclusive() {
645 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 650 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
646 None => self.err_ty(), 651 None => self.err_ty(),
647 } 652 }
648 } 653 }
649 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 654 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
650 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 655 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
651 None => self.err_ty(), 656 None => self.err_ty(),
652 }, 657 },
653 (RangeOp::Inclusive, Some(_), Some(ty)) => { 658 (RangeOp::Inclusive, Some(_), Some(ty)) => {
654 match self.resolve_range_inclusive() { 659 match self.resolve_range_inclusive() {
655 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 660 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
656 None => self.err_ty(), 661 None => self.err_ty(),
657 } 662 }
658 } 663 }
659 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 664 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
660 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 665 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
661 None => self.err_ty(), 666 None => self.err_ty(),
662 }, 667 },
663 (RangeOp::Inclusive, _, None) => self.err_ty(), 668 (RangeOp::Inclusive, _, None) => self.err_ty(),
@@ -690,10 +695,10 @@ impl<'a> InferenceContext<'a> {
690 } 695 }
691 } 696 }
692 Expr::Tuple { exprs } => { 697 Expr::Tuple { exprs } => {
693 let mut tys = match expected.ty.interned(&Interner) { 698 let mut tys = match expected.ty.kind(&Interner) {
694 TyKind::Tuple(_, substs) => substs 699 TyKind::Tuple(_, substs) => substs
695 .iter() 700 .iter(&Interner)
696 .cloned() 701 .map(|a| a.assert_ty_ref(&Interner).clone())
697 .chain(repeat_with(|| self.table.new_type_var())) 702 .chain(repeat_with(|| self.table.new_type_var()))
698 .take(exprs.len()) 703 .take(exprs.len())
699 .collect::<Vec<_>>(), 704 .collect::<Vec<_>>(),
@@ -704,11 +709,11 @@ impl<'a> InferenceContext<'a> {
704 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 709 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
705 } 710 }
706 711
707 TyKind::Tuple(tys.len(), Substitution(tys.into())).intern(&Interner) 712 TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner)
708 } 713 }
709 Expr::Array(array) => { 714 Expr::Array(array) => {
710 let elem_ty = match expected.ty.interned(&Interner) { 715 let elem_ty = match expected.ty.kind(&Interner) {
711 TyKind::Array(st) | TyKind::Slice(st) => st.clone(), 716 TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(),
712 _ => self.table.new_type_var(), 717 _ => self.table.new_type_var(),
713 }; 718 };
714 719
@@ -732,17 +737,19 @@ impl<'a> InferenceContext<'a> {
732 } 737 }
733 } 738 }
734 739
735 TyKind::Array(elem_ty).intern(&Interner) 740 TyKind::Array(elem_ty, dummy_usize_const()).intern(&Interner)
736 } 741 }
737 Expr::Literal(lit) => match lit { 742 Expr::Literal(lit) => match lit {
738 Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), 743 Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
739 Literal::String(..) => { 744 Literal::String(..) => {
740 TyKind::Ref(Mutability::Not, TyKind::Str.intern(&Interner)).intern(&Interner) 745 TyKind::Ref(Mutability::Not, static_lifetime(), TyKind::Str.intern(&Interner))
746 .intern(&Interner)
741 } 747 }
742 Literal::ByteString(..) => { 748 Literal::ByteString(..) => {
743 let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); 749 let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner);
744 let array_type = TyKind::Array(byte_type).intern(&Interner); 750 let array_type =
745 TyKind::Ref(Mutability::Not, array_type).intern(&Interner) 751 TyKind::Array(byte_type, dummy_usize_const()).intern(&Interner);
752 TyKind::Ref(Mutability::Not, static_lifetime(), array_type).intern(&Interner)
746 } 753 }
747 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner), 754 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner),
748 Literal::Int(_v, ty) => match ty { 755 Literal::Int(_v, ty) => match ty {
@@ -822,8 +829,8 @@ impl<'a> InferenceContext<'a> {
822 // we don't even make an attempt at coercion 829 // we don't even make an attempt at coercion
823 self.table.new_maybe_never_var() 830 self.table.new_maybe_never_var()
824 } else { 831 } else {
825 self.coerce(&Ty::unit(), &expected.coercion_target()); 832 self.coerce(&TyBuilder::unit(), &expected.coercion_target());
826 Ty::unit() 833 TyBuilder::unit()
827 } 834 }
828 }; 835 };
829 ty 836 ty
@@ -859,10 +866,10 @@ impl<'a> InferenceContext<'a> {
859 self.write_method_resolution(tgt_expr, func); 866 self.write_method_resolution(tgt_expr, func);
860 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) 867 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into())))
861 } 868 }
862 None => (receiver_ty, Binders::new(0, self.err_ty()), None), 869 None => (receiver_ty, Binders::empty(&Interner, self.err_ty()), None),
863 }; 870 };
864 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); 871 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty);
865 let method_ty = method_ty.subst(&substs); 872 let method_ty = method_ty.substitute(&Interner, &substs);
866 let method_ty = self.insert_type_vars(method_ty); 873 let method_ty = self.insert_type_vars(method_ty);
867 self.register_obligations_for_call(&method_ty); 874 self.register_obligations_for_call(&method_ty);
868 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) { 875 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) {
@@ -878,7 +885,9 @@ impl<'a> InferenceContext<'a> {
878 // Apply autoref so the below unification works correctly 885 // Apply autoref so the below unification works correctly
879 // FIXME: return correct autorefs from lookup_method 886 // FIXME: return correct autorefs from lookup_method
880 let actual_receiver_ty = match expected_receiver_ty.as_reference() { 887 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
881 Some((_, mutability)) => TyKind::Ref(mutability, derefed_receiver_ty).intern(&Interner), 888 Some((_, lifetime, mutability)) => {
889 TyKind::Ref(mutability, lifetime, derefed_receiver_ty).intern(&Interner)
890 }
882 _ => derefed_receiver_ty, 891 _ => derefed_receiver_ty,
883 }; 892 };
884 self.unify(&expected_receiver_ty, &actual_receiver_ty); 893 self.unify(&expected_receiver_ty, &actual_receiver_ty);
@@ -951,18 +960,20 @@ impl<'a> InferenceContext<'a> {
951 substs.push(self.err_ty()); 960 substs.push(self.err_ty());
952 } 961 }
953 assert_eq!(substs.len(), total_len); 962 assert_eq!(substs.len(), total_len);
954 Substitution(substs.into()) 963 Substitution::from_iter(&Interner, substs)
955 } 964 }
956 965
957 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 966 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
958 if let TyKind::FnDef(fn_def, parameters) = callable_ty.interned(&Interner) { 967 if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(&Interner) {
959 let def: CallableDefId = from_chalk(self.db, *fn_def); 968 let def: CallableDefId = from_chalk(self.db, *fn_def);
960 let generic_predicates = self.db.generic_predicates(def.into()); 969 let generic_predicates = self.db.generic_predicates(def.into());
961 for predicate in generic_predicates.iter() { 970 for predicate in generic_predicates.iter() {
962 let (predicate, binders) = 971 let (predicate, binders) = predicate
963 predicate.clone().subst(parameters).into_value_and_skipped_binders(); 972 .clone()
964 always!(binders == 0); // quantified where clauses not yet handled 973 .substitute(&Interner, parameters)
965 self.obligations.push(predicate.cast(&Interner)); 974 .into_value_and_skipped_binders();
975 always!(binders.len(&Interner) == 0); // quantified where clauses not yet handled
976 self.push_obligation(predicate.cast(&Interner));
966 } 977 }
967 // add obligation for trait implementation, if this is a trait method 978 // add obligation for trait implementation, if this is a trait method
968 match def { 979 match def {
@@ -970,9 +981,11 @@ impl<'a> InferenceContext<'a> {
970 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container 981 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container
971 { 982 {
972 // construct a TraitRef 983 // construct a TraitRef
973 let substs = 984 let substs = crate::subst_prefix(
974 parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); 985 &*parameters,
975 self.obligations.push( 986 generics(self.db.upcast(), trait_.into()).len(),
987 );
988 self.push_obligation(
976 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs } 989 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }
977 .cast(&Interner), 990 .cast(&Interner),
978 ); 991 );
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 474363709..aea354cde 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -7,15 +7,13 @@ use chalk_ir::Mutability;
7use hir_def::{ 7use hir_def::{
8 expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat}, 8 expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat},
9 path::Path, 9 path::Path,
10 FieldId,
11}; 10};
12use hir_expand::name::Name; 11use hir_expand::name::Name;
13 12
14use super::{BindingMode, Expectation, InferenceContext}; 13use super::{BindingMode, Expectation, InferenceContext};
15use crate::{ 14use crate::{
16 lower::lower_to_chalk_mutability, 15 lower::lower_to_chalk_mutability, static_lifetime, Interner, Substitution, Ty, TyBuilder,
17 utils::{generics, variant_data}, 16 TyExt, TyKind,
18 Interner, Substitution, Ty, TyKind,
19}; 17};
20 18
21impl<'a> InferenceContext<'a> { 19impl<'a> InferenceContext<'a> {
@@ -29,13 +27,14 @@ impl<'a> InferenceContext<'a> {
29 ellipsis: Option<usize>, 27 ellipsis: Option<usize>,
30 ) -> Ty { 28 ) -> Ty {
31 let (ty, def) = self.resolve_variant(path); 29 let (ty, def) = self.resolve_variant(path);
32 let var_data = def.map(|it| variant_data(self.db.upcast(), it)); 30 let var_data = def.map(|it| it.variant_data(self.db.upcast()));
33 if let Some(variant) = def { 31 if let Some(variant) = def {
34 self.write_variant_resolution(id.into(), variant); 32 self.write_variant_resolution(id.into(), variant);
35 } 33 }
36 self.unify(&ty, expected); 34 self.unify(&ty, expected);
37 35
38 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 36 let substs =
37 ty.as_adt().map(|(_, s)| s.clone()).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 }
@@ -67,25 +68,22 @@ impl<'a> InferenceContext<'a> {
67 id: PatId, 68 id: PatId,
68 ) -> Ty { 69 ) -> Ty {
69 let (ty, def) = self.resolve_variant(path); 70 let (ty, def) = self.resolve_variant(path);
70 let var_data = def.map(|it| variant_data(self.db.upcast(), it)); 71 let var_data = def.map(|it| it.variant_data(self.db.upcast()));
71 if let Some(variant) = def { 72 if let Some(variant) = def {
72 self.write_variant_resolution(id.into(), variant); 73 self.write_variant_resolution(id.into(), variant);
73 } 74 }
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 =
79 ty.as_adt().map(|(_, s)| s.clone()).unwrap_or_else(|| Substitution::empty(&Interner));
78 80
79 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 81 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
80 for subpat in subpats { 82 for subpat in subpats {
81 let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name)); 83 let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name));
82 if let Some(local_id) = matching_field { 84 let expected_ty = matching_field.map_or(self.err_ty(), |field| {
83 let field_def = FieldId { parent: def.unwrap(), local_id }; 85 field_tys[field].clone().substitute(&Interner, &substs)
84 self.result.record_pat_field_resolutions.insert(subpat.pat, field_def); 86 });
85 }
86
87 let expected_ty = matching_field
88 .map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs));
89 let expected_ty = self.normalize_associated_types_in(expected_ty); 87 let expected_ty = self.normalize_associated_types_in(expected_ty);
90 self.infer_pat(subpat.pat, &expected_ty, default_bm); 88 self.infer_pat(subpat.pat, &expected_ty, default_bm);
91 } 89 }
@@ -102,7 +100,7 @@ impl<'a> InferenceContext<'a> {
102 let body = Arc::clone(&self.body); // avoid borrow checker problem 100 let body = Arc::clone(&self.body); // avoid borrow checker problem
103 101
104 if is_non_ref_pat(&body, pat) { 102 if is_non_ref_pat(&body, pat) {
105 while let Some((inner, mutability)) = expected.as_reference() { 103 while let Some((inner, _lifetime, mutability)) = expected.as_reference() {
106 expected = inner; 104 expected = inner;
107 default_bm = match default_bm { 105 default_bm = match default_bm {
108 BindingMode::Move => BindingMode::Ref(mutability), 106 BindingMode::Move => BindingMode::Ref(mutability),
@@ -124,7 +122,7 @@ impl<'a> InferenceContext<'a> {
124 let ty = match &body[pat] { 122 let ty = match &body[pat] {
125 &Pat::Tuple { ref args, ellipsis } => { 123 &Pat::Tuple { ref args, ellipsis } => {
126 let expectations = match expected.as_tuple() { 124 let expectations = match expected.as_tuple() {
127 Some(parameters) => &*parameters.0, 125 Some(parameters) => &*parameters.as_slice(&Interner),
128 _ => &[], 126 _ => &[],
129 }; 127 };
130 128
@@ -134,7 +132,8 @@ impl<'a> InferenceContext<'a> {
134 }; 132 };
135 let n_uncovered_patterns = expectations.len().saturating_sub(args.len()); 133 let n_uncovered_patterns = expectations.len().saturating_sub(args.len());
136 let err_ty = self.err_ty(); 134 let err_ty = self.err_ty();
137 let mut expectations_iter = expectations.iter().chain(repeat(&err_ty)); 135 let mut expectations_iter =
136 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); 137 let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm);
139 138
140 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len()); 139 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len());
@@ -142,7 +141,8 @@ impl<'a> InferenceContext<'a> {
142 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); 141 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
143 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); 142 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
144 143
145 TyKind::Tuple(inner_tys.len(), Substitution(inner_tys.into())).intern(&Interner) 144 TyKind::Tuple(inner_tys.len(), Substitution::from_iter(&Interner, inner_tys))
145 .intern(&Interner)
146 } 146 }
147 Pat::Or(ref pats) => { 147 Pat::Or(ref pats) => {
148 if let Some((first_pat, rest)) = pats.split_first() { 148 if let Some((first_pat, rest)) = pats.split_first() {
@@ -158,7 +158,7 @@ impl<'a> InferenceContext<'a> {
158 Pat::Ref { pat, mutability } => { 158 Pat::Ref { pat, mutability } => {
159 let mutability = lower_to_chalk_mutability(*mutability); 159 let mutability = lower_to_chalk_mutability(*mutability);
160 let expectation = match expected.as_reference() { 160 let expectation = match expected.as_reference() {
161 Some((inner_ty, exp_mut)) => { 161 Some((inner_ty, _lifetime, exp_mut)) => {
162 if mutability != exp_mut { 162 if mutability != exp_mut {
163 // FIXME: emit type error? 163 // FIXME: emit type error?
164 } 164 }
@@ -167,10 +167,10 @@ impl<'a> InferenceContext<'a> {
167 _ => self.result.standard_types.unknown.clone(), 167 _ => self.result.standard_types.unknown.clone(),
168 }; 168 };
169 let subty = self.infer_pat(*pat, &expectation, default_bm); 169 let subty = self.infer_pat(*pat, &expectation, default_bm);
170 TyKind::Ref(mutability, subty).intern(&Interner) 170 TyKind::Ref(mutability, static_lifetime(), subty).intern(&Interner)
171 } 171 }
172 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( 172 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat(
173 p.as_ref(), 173 p.as_deref(),
174 subpats, 174 subpats,
175 expected, 175 expected,
176 default_bm, 176 default_bm,
@@ -178,7 +178,7 @@ impl<'a> InferenceContext<'a> {
178 *ellipsis, 178 *ellipsis,
179 ), 179 ),
180 Pat::Record { path: p, args: fields, ellipsis: _ } => { 180 Pat::Record { path: p, args: fields, ellipsis: _ } => {
181 self.infer_record_pat(p.as_ref(), fields, expected, default_bm, pat) 181 self.infer_record_pat(p.as_deref(), fields, expected, default_bm, pat)
182 } 182 }
183 Pat::Path(path) => { 183 Pat::Path(path) => {
184 // FIXME use correct resolver for the surrounding expression 184 // FIXME use correct resolver for the surrounding expression
@@ -200,7 +200,8 @@ impl<'a> InferenceContext<'a> {
200 200
201 let bound_ty = match mode { 201 let bound_ty = match mode {
202 BindingMode::Ref(mutability) => { 202 BindingMode::Ref(mutability) => {
203 TyKind::Ref(mutability, inner_ty.clone()).intern(&Interner) 203 TyKind::Ref(mutability, static_lifetime(), inner_ty.clone())
204 .intern(&Interner)
204 } 205 }
205 BindingMode::Move => inner_ty.clone(), 206 BindingMode::Move => inner_ty.clone(),
206 }; 207 };
@@ -209,17 +210,20 @@ 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 elem_ty = match expected.kind(&Interner) {
213 TyKind::Array(st) => (TyKind::Array, st.clone()), 214 TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(),
214 TyKind::Slice(st) => (TyKind::Slice, st.clone()), 215 _ => self.err_ty(),
215 _ => (TyKind::Slice, self.err_ty()),
216 }; 216 };
217 217
218 for pat_id in prefix.iter().chain(suffix) { 218 for pat_id in prefix.iter().chain(suffix) {
219 self.infer_pat(*pat_id, &elem_ty, default_bm); 219 self.infer_pat(*pat_id, &elem_ty, default_bm);
220 } 220 }
221 221
222 let pat_ty = container_ty(elem_ty).intern(&Interner); 222 let pat_ty = match expected.kind(&Interner) {
223 TyKind::Array(_, const_) => TyKind::Array(elem_ty, const_.clone()),
224 _ => TyKind::Slice(elem_ty),
225 }
226 .intern(&Interner);
223 if let Some(slice_pat_id) = slice { 227 if let Some(slice_pat_id) = slice {
224 self.infer_pat(*slice_pat_id, &pat_ty, default_bm); 228 self.infer_pat(*slice_pat_id, &pat_ty, default_bm);
225 } 229 }
@@ -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.as_slice(&Interner).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..495282eba 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -11,7 +11,8 @@ use hir_def::{
11use hir_expand::name::Name; 11use hir_expand::name::Name;
12 12
13use crate::{ 13use crate::{
14 method_resolution, to_chalk_trait_id, Interner, Substitution, Ty, TyKind, ValueTyDefId, 14 method_resolution, Interner, Substitution, TraitRefExt, Ty, TyBuilder, TyExt, TyKind,
15 ValueTyDefId,
15}; 16};
16 17
17use super::{ExprOrPatId, InferenceContext, TraitRef}; 18use super::{ExprOrPatId, InferenceContext, TraitRef};
@@ -82,10 +83,10 @@ impl<'a> InferenceContext<'a> {
82 } 83 }
83 ValueNs::ImplSelf(impl_id) => { 84 ValueNs::ImplSelf(impl_id) => {
84 let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); 85 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
85 let substs = Substitution::type_params_for_generics(self.db, &generics); 86 let substs = generics.type_params_subst(self.db);
86 let ty = self.db.impl_self_ty(impl_id).subst(&substs); 87 let ty = self.db.impl_self_ty(impl_id).substitute(&Interner, &substs);
87 if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() { 88 if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() {
88 let ty = self.db.value_ty(struct_id.into()).subst(&substs); 89 let ty = self.db.value_ty(struct_id.into()).substitute(&Interner, &substs);
89 return Some(ty); 90 return Some(ty);
90 } else { 91 } else {
91 // FIXME: diagnostic, invalid Self reference 92 // FIXME: diagnostic, invalid Self reference
@@ -95,16 +96,13 @@ impl<'a> InferenceContext<'a> {
95 ValueNs::GenericParam(it) => return Some(self.db.const_param_ty(it)), 96 ValueNs::GenericParam(it) => return Some(self.db.const_param_ty(it)),
96 }; 97 };
97 98
98 let ty = self.db.value_ty(typable); 99 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); 100 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
102 let substs = ctx.substs_from_path(path, typable, true); 101 let substs = ctx.substs_from_path(path, typable, true);
103 let full_substs = Substitution::builder(substs.len()) 102 let ty = TyBuilder::value_ty(self.db, typable)
104 .use_parent_substs(&parent_substs) 103 .use_parent_substs(&parent_substs)
105 .fill(substs.0[parent_substs.len()..].iter().cloned()) 104 .fill(substs.as_slice(&Interner)[parent_substs.len(&Interner)..].iter().cloned())
106 .build(); 105 .build();
107 let ty = ty.subst(&full_substs);
108 Some(ty) 106 Some(ty)
109 } 107 }
110 108
@@ -147,7 +145,7 @@ impl<'a> InferenceContext<'a> {
147 remaining_segments_for_ty, 145 remaining_segments_for_ty,
148 true, 146 true,
149 ); 147 );
150 if let TyKind::Unknown = ty.interned(&Interner) { 148 if let TyKind::Error = ty.kind(&Interner) {
151 return None; 149 return None;
152 } 150 }
153 151
@@ -212,7 +210,7 @@ impl<'a> InferenceContext<'a> {
212 name: &Name, 210 name: &Name,
213 id: ExprOrPatId, 211 id: ExprOrPatId,
214 ) -> Option<(ValueNs, Option<Substitution>)> { 212 ) -> Option<(ValueNs, Option<Substitution>)> {
215 if let TyKind::Unknown = ty.interned(&Interner) { 213 if let TyKind::Error = ty.kind(&Interner) {
216 return None; 214 return None;
217 } 215 }
218 216
@@ -245,27 +243,22 @@ impl<'a> InferenceContext<'a> {
245 }; 243 };
246 let substs = match container { 244 let substs = match container {
247 AssocContainerId::ImplId(impl_id) => { 245 AssocContainerId::ImplId(impl_id) => {
248 let impl_substs = Substitution::build_for_def(self.db, impl_id) 246 let impl_substs = TyBuilder::subst_for_def(self.db, impl_id)
249 .fill(iter::repeat_with(|| self.table.new_type_var())) 247 .fill(iter::repeat_with(|| self.table.new_type_var()))
250 .build(); 248 .build();
251 let impl_self_ty = self.db.impl_self_ty(impl_id).subst(&impl_substs); 249 let impl_self_ty =
250 self.db.impl_self_ty(impl_id).substitute(&Interner, &impl_substs);
252 self.unify(&impl_self_ty, &ty); 251 self.unify(&impl_self_ty, &ty);
253 Some(impl_substs) 252 Some(impl_substs)
254 } 253 }
255 AssocContainerId::TraitId(trait_) => { 254 AssocContainerId::TraitId(trait_) => {
256 // we're picking this method 255 // we're picking this method
257 let trait_substs = Substitution::build_for_def(self.db, trait_) 256 let trait_ref = TyBuilder::trait_ref(self.db, trait_)
258 .push(ty.clone()) 257 .push(ty.clone())
259 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 258 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
260 .build(); 259 .build();
261 self.obligations.push( 260 self.push_obligation(trait_ref.clone().cast(&Interner));
262 TraitRef { 261 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 } 262 }
270 AssocContainerId::ModuleId(_) => None, 263 AssocContainerId::ModuleId(_) => None,
271 }; 264 };
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 6e7b0f5a6..a887e20b0 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -2,13 +2,17 @@
2 2
3use std::borrow::Cow; 3use std::borrow::Cow;
4 4
5use chalk_ir::{FloatTy, IntTy, TyVariableKind, UniverseIndex, VariableKind}; 5use chalk_ir::{
6 cast::Cast, fold::Fold, interner::HasInterner, FloatTy, IntTy, TyVariableKind, UniverseIndex,
7 VariableKind,
8};
6use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; 9use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
7 10
8use super::{DomainGoal, InferenceContext}; 11use super::{DomainGoal, InferenceContext};
9use crate::{ 12use crate::{
10 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, 13 fold_tys, static_lifetime, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds,
11 InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause, 14 DebruijnIndex, FnPointer, FnSubst, InEnvironment, InferenceVar, Interner, Scalar, Substitution,
15 Ty, TyExt, TyKind, WhereClause,
12}; 16};
13 17
14impl<'a> InferenceContext<'a> { 18impl<'a> InferenceContext<'a> {
@@ -33,7 +37,10 @@ where
33} 37}
34 38
35#[derive(Debug)] 39#[derive(Debug)]
36pub(super) struct Canonicalized<T> { 40pub(super) struct Canonicalized<T>
41where
42 T: HasInterner<Interner = Interner>,
43{
37 pub(super) value: Canonical<T>, 44 pub(super) value: Canonical<T>,
38 free_vars: Vec<(InferenceVar, TyVariableKind)>, 45 free_vars: Vec<(InferenceVar, TyVariableKind)>,
39} 46}
@@ -47,11 +54,16 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
47 }) 54 })
48 } 55 }
49 56
50 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { 57 fn do_canonicalize<T: Fold<Interner, Result = T> + HasInterner<Interner = Interner>>(
51 t.fold_binders( 58 &mut self,
52 &mut |ty, binders| match ty.interned(&Interner) { 59 t: T,
60 binders: DebruijnIndex,
61 ) -> T {
62 fold_tys(
63 t,
64 |ty, binders| match ty.kind(&Interner) {
53 &TyKind::InferenceVar(var, kind) => { 65 &TyKind::InferenceVar(var, kind) => {
54 let inner = var.to_inner(); 66 let inner = from_inference_var(var);
55 if self.var_stack.contains(&inner) { 67 if self.var_stack.contains(&inner) {
56 // recursive type 68 // recursive type
57 return self.ctx.table.type_variable_table.fallback_value(var, kind); 69 return self.ctx.table.type_variable_table.fallback_value(var, kind);
@@ -65,7 +77,7 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
65 result 77 result
66 } else { 78 } else {
67 let root = self.ctx.table.var_unification_table.find(inner); 79 let root = self.ctx.table.var_unification_table.find(inner);
68 let position = self.add(InferenceVar::from_inner(root), kind); 80 let position = self.add(to_inference_var(root), kind);
69 TyKind::BoundVar(BoundVar::new(binders, position)).intern(&Interner) 81 TyKind::BoundVar(BoundVar::new(binders, position)).intern(&Interner)
70 } 82 }
71 } 83 }
@@ -75,7 +87,10 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
75 ) 87 )
76 } 88 }
77 89
78 fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> { 90 fn into_canonicalized<T: HasInterner<Interner = Interner>>(
91 self,
92 result: T,
93 ) -> Canonicalized<T> {
79 let kinds = self 94 let kinds = self
80 .free_vars 95 .free_vars
81 .iter() 96 .iter()
@@ -102,25 +117,18 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
102 DomainGoal::Holds(wc) => { 117 DomainGoal::Holds(wc) => {
103 DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST)) 118 DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST))
104 } 119 }
120 _ => unimplemented!(),
105 }; 121 };
106 self.into_canonicalized(InEnvironment { goal: result, environment: obligation.environment }) 122 self.into_canonicalized(InEnvironment { goal: result, environment: obligation.environment })
107 } 123 }
108} 124}
109 125
110impl<T> Canonicalized<T> { 126impl<T: HasInterner<Interner = Interner>> Canonicalized<T> {
111 pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { 127 pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty {
112 ty.walk_mut_binders( 128 crate::fold_free_vars(ty, |bound, _binders| {
113 &mut |ty, binders| { 129 let (v, k) = self.free_vars[bound.index];
114 if let &mut TyKind::BoundVar(bound) = ty.interned_mut() { 130 TyKind::InferenceVar(v, k).intern(&Interner)
115 if bound.debruijn >= binders { 131 })
116 let (v, k) = self.free_vars[bound.index];
117 *ty = TyKind::InferenceVar(v, k).intern(&Interner);
118 }
119 }
120 },
121 DebruijnIndex::INNERMOST,
122 );
123 ty
124 } 132 }
125 133
126 pub(super) fn apply_solution( 134 pub(super) fn apply_solution(
@@ -129,29 +137,30 @@ impl<T> Canonicalized<T> {
129 solution: Canonical<Substitution>, 137 solution: Canonical<Substitution>,
130 ) { 138 ) {
131 // the solution may contain new variables, which we need to convert to new inference vars 139 // the solution may contain new variables, which we need to convert to new inference vars
132 let new_vars = Substitution( 140 let new_vars = Substitution::from_iter(
133 solution 141 &Interner,
134 .binders 142 solution.binders.iter(&Interner).map(|k| match k.kind {
135 .iter(&Interner) 143 VariableKind::Ty(TyVariableKind::General) => {
136 .map(|k| match k.kind { 144 ctx.table.new_type_var().cast(&Interner)
137 VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(), 145 }
138 VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(), 146 VariableKind::Ty(TyVariableKind::Integer) => {
139 VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(), 147 ctx.table.new_integer_var().cast(&Interner)
140 // HACK: Chalk can sometimes return new lifetime variables. We 148 }
141 // want to just skip them, but to not mess up the indices of 149 VariableKind::Ty(TyVariableKind::Float) => {
142 // other variables, we'll just create a new type variable in 150 ctx.table.new_float_var().cast(&Interner)
143 // their place instead. This should not matter (we never see the 151 }
144 // actual *uses* of the lifetime variable). 152 // Chalk can sometimes return new lifetime variables. We just use the static lifetime everywhere
145 VariableKind::Lifetime => ctx.table.new_type_var(), 153 VariableKind::Lifetime => static_lifetime().cast(&Interner),
146 _ => panic!("const variable in solution"), 154 _ => panic!("const variable in solution"),
147 }) 155 }),
148 .collect(),
149 ); 156 );
150 for (i, ty) in solution.value.into_iter().enumerate() { 157 for (i, ty) in solution.value.iter(&Interner).enumerate() {
151 let (v, k) = self.free_vars[i]; 158 let (v, k) = self.free_vars[i];
152 // eagerly replace projections in the type; we may be getting types 159 // eagerly replace projections in the type; we may be getting types
153 // e.g. from where clauses where this hasn't happened yet 160 // 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)); 161 let ty = ctx.normalize_associated_types_in(
162 new_vars.apply(ty.assert_ty_ref(&Interner).clone(), &Interner),
163 );
155 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); 164 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty);
156 } 165 }
157 } 166 }
@@ -163,22 +172,23 @@ pub fn could_unify(t1: &Ty, t2: &Ty) -> bool {
163 172
164pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { 173pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
165 let mut table = InferenceTable::new(); 174 let mut table = InferenceTable::new();
166 let vars = Substitution( 175 let vars = Substitution::from_iter(
176 &Interner,
167 tys.binders 177 tys.binders
168 .iter(&Interner) 178 .iter(&Interner)
169 // we always use type vars here because we want everything to 179 // we always use type vars here because we want everything to
170 // fallback to Unknown in the end (kind of hacky, as below) 180 // fallback to Unknown in the end (kind of hacky, as below)
171 .map(|_| table.new_type_var()) 181 .map(|_| table.new_type_var()),
172 .collect(),
173 ); 182 );
174 let ty1_with_vars = tys.value.0.clone().subst_bound_vars(&vars); 183 let ty1_with_vars = vars.apply(tys.value.0.clone(), &Interner);
175 let ty2_with_vars = tys.value.1.clone().subst_bound_vars(&vars); 184 let ty2_with_vars = vars.apply(tys.value.1.clone(), &Interner);
176 if !table.unify(&ty1_with_vars, &ty2_with_vars) { 185 if !table.unify(&ty1_with_vars, &ty2_with_vars) {
177 return None; 186 return None;
178 } 187 }
179 // default any type vars that weren't unified back to their original bound vars 188 // default any type vars that weren't unified back to their original bound vars
180 // (kind of hacky) 189 // (kind of hacky)
181 for (i, var) in vars.iter().enumerate() { 190 for (i, var) in vars.iter(&Interner).enumerate() {
191 let var = var.assert_ty_ref(&Interner);
182 if &*table.resolve_ty_shallow(var) == var { 192 if &*table.resolve_ty_shallow(var) == var {
183 table.unify( 193 table.unify(
184 var, 194 var,
@@ -186,11 +196,11 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
186 ); 196 );
187 } 197 }
188 } 198 }
189 Some( 199 Some(Substitution::from_iter(
190 Substitution::builder(tys.binders.len(&Interner)) 200 &Interner,
191 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) 201 vars.iter(&Interner)
192 .build(), 202 .map(|v| table.resolve_ty_completely(v.assert_ty_ref(&Interner).clone())),
193 ) 203 ))
194} 204}
195 205
196#[derive(Clone, Debug)] 206#[derive(Clone, Debug)]
@@ -204,17 +214,17 @@ impl TypeVariableTable {
204 } 214 }
205 215
206 pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) { 216 pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) {
207 self.inner[iv.to_inner().0 as usize].diverging = diverging; 217 self.inner[from_inference_var(iv).0 as usize].diverging = diverging;
208 } 218 }
209 219
210 fn is_diverging(&mut self, iv: InferenceVar) -> bool { 220 fn is_diverging(&mut self, iv: InferenceVar) -> bool {
211 self.inner[iv.to_inner().0 as usize].diverging 221 self.inner[from_inference_var(iv).0 as usize].diverging
212 } 222 }
213 223
214 fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { 224 fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty {
215 match kind { 225 match kind {
216 _ if self.inner[iv.to_inner().0 as usize].diverging => TyKind::Never, 226 _ if self.inner[from_inference_var(iv).0 as usize].diverging => TyKind::Never,
217 TyVariableKind::General => TyKind::Unknown, 227 TyVariableKind::General => TyKind::Error,
218 TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)), 228 TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)),
219 TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)), 229 TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)),
220 } 230 }
@@ -231,6 +241,7 @@ pub(crate) struct TypeVariableData {
231pub(crate) struct InferenceTable { 241pub(crate) struct InferenceTable {
232 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>, 242 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>,
233 pub(super) type_variable_table: TypeVariableTable, 243 pub(super) type_variable_table: TypeVariableTable,
244 pub(super) revision: u32,
234} 245}
235 246
236impl InferenceTable { 247impl InferenceTable {
@@ -238,6 +249,7 @@ impl InferenceTable {
238 InferenceTable { 249 InferenceTable {
239 var_unification_table: InPlaceUnificationTable::new(), 250 var_unification_table: InPlaceUnificationTable::new(),
240 type_variable_table: TypeVariableTable { inner: Vec::new() }, 251 type_variable_table: TypeVariableTable { inner: Vec::new() },
252 revision: 0,
241 } 253 }
242 } 254 }
243 255
@@ -245,7 +257,7 @@ impl InferenceTable {
245 self.type_variable_table.push(TypeVariableData { diverging }); 257 self.type_variable_table.push(TypeVariableData { diverging });
246 let key = self.var_unification_table.new_key(TypeVarValue::Unknown); 258 let key = self.var_unification_table.new_key(TypeVarValue::Unknown);
247 assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1); 259 assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1);
248 TyKind::InferenceVar(InferenceVar::from_inner(key), kind).intern(&Interner) 260 TyKind::InferenceVar(to_inference_var(key), kind).intern(&Interner)
249 } 261 }
250 262
251 pub(crate) fn new_type_var(&mut self) -> Ty { 263 pub(crate) fn new_type_var(&mut self) -> Ty {
@@ -282,7 +294,9 @@ impl InferenceTable {
282 substs2: &Substitution, 294 substs2: &Substitution,
283 depth: usize, 295 depth: usize,
284 ) -> bool { 296 ) -> bool {
285 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth)) 297 substs1.iter(&Interner).zip(substs2.iter(&Interner)).all(|(t1, t2)| {
298 self.unify_inner(t1.assert_ty_ref(&Interner), t2.assert_ty_ref(&Interner), depth)
299 })
286 } 300 }
287 301
288 fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 302 fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {
@@ -297,12 +311,12 @@ impl InferenceTable {
297 let ty1 = self.resolve_ty_shallow(ty1); 311 let ty1 = self.resolve_ty_shallow(ty1);
298 let ty2 = self.resolve_ty_shallow(ty2); 312 let ty2 = self.resolve_ty_shallow(ty2);
299 if ty1.equals_ctor(&ty2) { 313 if ty1.equals_ctor(&ty2) {
300 match (ty1.interned(&Interner), ty2.interned(&Interner)) { 314 match (ty1.kind(&Interner), ty2.kind(&Interner)) {
301 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) 315 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2))
302 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) 316 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2))
303 | ( 317 | (
304 TyKind::Function(FnPointer { substs: substs1, .. }), 318 TyKind::Function(FnPointer { substitution: FnSubst(substs1), .. }),
305 TyKind::Function(FnPointer { substs: substs2, .. }), 319 TyKind::Function(FnPointer { substitution: FnSubst(substs2), .. }),
306 ) 320 )
307 | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2)) 321 | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2))
308 | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2)) 322 | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2))
@@ -310,9 +324,11 @@ impl InferenceTable {
310 | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => { 324 | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => {
311 self.unify_substs(substs1, substs2, depth + 1) 325 self.unify_substs(substs1, substs2, depth + 1)
312 } 326 }
313 (TyKind::Ref(_, ty1), TyKind::Ref(_, ty2)) 327 (TyKind::Array(ty1, c1), TyKind::Array(ty2, c2)) if c1 == c2 => {
328 self.unify_inner(ty1, ty2, depth + 1)
329 }
330 (TyKind::Ref(_, _, ty1), TyKind::Ref(_, _, ty2))
314 | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2)) 331 | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2))
315 | (TyKind::Array(ty1), TyKind::Array(ty2))
316 | (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1), 332 | (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1),
317 _ => true, /* we checked equals_ctor already */ 333 _ => true, /* we checked equals_ctor already */
318 } 334 }
@@ -322,8 +338,8 @@ impl InferenceTable {
322 } 338 }
323 339
324 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 340 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {
325 match (ty1.interned(&Interner), ty2.interned(&Interner)) { 341 match (ty1.kind(&Interner), ty2.kind(&Interner)) {
326 (TyKind::Unknown, _) | (_, TyKind::Unknown) => true, 342 (TyKind::Error, _) | (_, TyKind::Error) => true,
327 343
328 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, 344 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true,
329 345
@@ -360,7 +376,14 @@ impl InferenceTable {
360 == self.type_variable_table.is_diverging(*tv2) => 376 == self.type_variable_table.is_diverging(*tv2) =>
361 { 377 {
362 // both type vars are unknown since we tried to resolve them 378 // both type vars are unknown since we tried to resolve them
363 self.var_unification_table.union(tv1.to_inner(), tv2.to_inner()); 379 if !self
380 .var_unification_table
381 .unioned(from_inference_var(*tv1), from_inference_var(*tv2))
382 {
383 self.var_unification_table
384 .union(from_inference_var(*tv1), from_inference_var(*tv2));
385 self.revision += 1;
386 }
364 true 387 true
365 } 388 }
366 389
@@ -395,9 +418,10 @@ impl InferenceTable {
395 ) => { 418 ) => {
396 // the type var is unknown since we tried to resolve it 419 // the type var is unknown since we tried to resolve it
397 self.var_unification_table.union_value( 420 self.var_unification_table.union_value(
398 tv.to_inner(), 421 from_inference_var(*tv),
399 TypeVarValue::Known(other.clone().intern(&Interner)), 422 TypeVarValue::Known(other.clone().intern(&Interner)),
400 ); 423 );
424 self.revision += 1;
401 true 425 true
402 } 426 }
403 427
@@ -447,9 +471,9 @@ impl InferenceTable {
447 if i > 0 { 471 if i > 0 {
448 cov_mark::hit!(type_var_resolves_to_int_var); 472 cov_mark::hit!(type_var_resolves_to_int_var);
449 } 473 }
450 match ty.interned(&Interner) { 474 match ty.kind(&Interner) {
451 TyKind::InferenceVar(tv, _) => { 475 TyKind::InferenceVar(tv, _) => {
452 let inner = tv.to_inner(); 476 let inner = from_inference_var(*tv);
453 match self.var_unification_table.inlined_probe_value(inner).known() { 477 match self.var_unification_table.inlined_probe_value(inner).known() {
454 Some(known_ty) => { 478 Some(known_ty) => {
455 // The known_ty can't be a type var itself 479 // The known_ty can't be a type var itself
@@ -470,55 +494,63 @@ impl InferenceTable {
470 /// be resolved as far as possible, i.e. contain no type variables with 494 /// be resolved as far as possible, i.e. contain no type variables with
471 /// known type. 495 /// known type.
472 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 496 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) { 497 fold_tys(
474 &TyKind::InferenceVar(tv, kind) => { 498 ty,
475 let inner = tv.to_inner(); 499 |ty, _| match ty.kind(&Interner) {
476 if tv_stack.contains(&inner) { 500 &TyKind::InferenceVar(tv, kind) => {
477 cov_mark::hit!(type_var_cycles_resolve_as_possible); 501 let inner = from_inference_var(tv);
478 // recursive type 502 if tv_stack.contains(&inner) {
479 return self.type_variable_table.fallback_value(tv, kind); 503 cov_mark::hit!(type_var_cycles_resolve_as_possible);
480 } 504 // recursive type
481 if let Some(known_ty) = 505 return self.type_variable_table.fallback_value(tv, kind);
482 self.var_unification_table.inlined_probe_value(inner).known() 506 }
483 { 507 if let Some(known_ty) =
484 // known_ty may contain other variables that are known by now 508 self.var_unification_table.inlined_probe_value(inner).known()
485 tv_stack.push(inner); 509 {
486 let result = self.resolve_ty_as_possible_inner(tv_stack, known_ty.clone()); 510 // known_ty may contain other variables that are known by now
487 tv_stack.pop(); 511 tv_stack.push(inner);
488 result 512 let result = self.resolve_ty_as_possible_inner(tv_stack, known_ty.clone());
489 } else { 513 tv_stack.pop();
490 ty 514 result
515 } else {
516 ty
517 }
491 } 518 }
492 } 519 _ => ty,
493 _ => ty, 520 },
494 }) 521 DebruijnIndex::INNERMOST,
522 )
495 } 523 }
496 524
497 /// Resolves the type completely; type variables without known type are 525 /// Resolves the type completely; type variables without known type are
498 /// replaced by TyKind::Unknown. 526 /// replaced by TyKind::Unknown.
499 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 527 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
500 ty.fold(&mut |ty| match ty.interned(&Interner) { 528 fold_tys(
501 &TyKind::InferenceVar(tv, kind) => { 529 ty,
502 let inner = tv.to_inner(); 530 |ty, _| match ty.kind(&Interner) {
503 if tv_stack.contains(&inner) { 531 &TyKind::InferenceVar(tv, kind) => {
504 cov_mark::hit!(type_var_cycles_resolve_completely); 532 let inner = from_inference_var(tv);
505 // recursive type 533 if tv_stack.contains(&inner) {
506 return self.type_variable_table.fallback_value(tv, kind); 534 cov_mark::hit!(type_var_cycles_resolve_completely);
507 } 535 // recursive type
508 if let Some(known_ty) = 536 return self.type_variable_table.fallback_value(tv, kind);
509 self.var_unification_table.inlined_probe_value(inner).known() 537 }
510 { 538 if let Some(known_ty) =
511 // known_ty may contain other variables that are known by now 539 self.var_unification_table.inlined_probe_value(inner).known()
512 tv_stack.push(inner); 540 {
513 let result = self.resolve_ty_completely_inner(tv_stack, known_ty.clone()); 541 // known_ty may contain other variables that are known by now
514 tv_stack.pop(); 542 tv_stack.push(inner);
515 result 543 let result = self.resolve_ty_completely_inner(tv_stack, known_ty.clone());
516 } else { 544 tv_stack.pop();
517 self.type_variable_table.fallback_value(tv, kind) 545 result
546 } else {
547 self.type_variable_table.fallback_value(tv, kind)
548 }
518 } 549 }
519 } 550 _ => ty,
520 _ => ty, 551 },
521 }) 552 DebruijnIndex::INNERMOST,
553 )
522 } 554 }
523} 555}
524 556
@@ -542,6 +574,14 @@ impl UnifyKey for TypeVarId {
542 } 574 }
543} 575}
544 576
577fn from_inference_var(var: InferenceVar) -> TypeVarId {
578 TypeVarId(var.index())
579}
580
581fn to_inference_var(TypeVarId(index): TypeVarId) -> InferenceVar {
582 index.into()
583}
584
545/// The value of a type variable: either we already know the type, or we don't 585/// The value of a type variable: either we already know the type, or we don't
546/// know it yet. 586/// know it yet.
547#[derive(Clone, PartialEq, Eq, Debug)] 587#[derive(Clone, PartialEq, Eq, Debug)]