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.rs85
-rw-r--r--crates/hir_ty/src/infer/expr.rs229
-rw-r--r--crates/hir_ty/src/infer/pat.rs27
-rw-r--r--crates/hir_ty/src/infer/unify.rs200
4 files changed, 281 insertions, 260 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 32c7c57cd..c33d8c61e 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -4,12 +4,13 @@
4//! 4//!
5//! See: https://doc.rust-lang.org/nomicon/coercions.html 5//! See: https://doc.rust-lang.org/nomicon/coercions.html
6 6
7use chalk_ir::TyVariableKind;
7use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; 8use hir_def::{lang_item::LangItemTarget, type_ref::Mutability};
8use test_utils::mark; 9use test_utils::mark;
9 10
10use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty, TypeCtor}; 11use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty};
11 12
12use super::{unify::TypeVarValue, InEnvironment, InferTy, InferenceContext}; 13use super::{InEnvironment, InferenceContext};
13 14
14impl<'a> InferenceContext<'a> { 15impl<'a> InferenceContext<'a> {
15 /// Unify two types, but may coerce the first one to the second one 16 /// Unify two types, but may coerce the first one to the second one
@@ -33,7 +34,7 @@ impl<'a> InferenceContext<'a> {
33 } else if self.coerce(ty2, ty1) { 34 } else if self.coerce(ty2, ty1) {
34 ty1.clone() 35 ty1.clone()
35 } else { 36 } else {
36 if let (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnDef(_))) = (ty1, ty2) { 37 if let (Ty::FnDef(..), Ty::FnDef(..)) = (ty1, ty2) {
37 mark::hit!(coerce_fn_reification); 38 mark::hit!(coerce_fn_reification);
38 // Special case: two function types. Try to coerce both to 39 // Special case: two function types. Try to coerce both to
39 // pointers to have a chance at getting a match. See 40 // pointers to have a chance at getting a match. See
@@ -53,12 +54,11 @@ impl<'a> InferenceContext<'a> {
53 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { 54 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool {
54 match (&from_ty, to_ty) { 55 match (&from_ty, to_ty) {
55 // Never type will make type variable to fallback to Never Type instead of Unknown. 56 // Never type will make type variable to fallback to Never Type instead of Unknown.
56 (ty_app!(TypeCtor::Never), Ty::Infer(InferTy::TypeVar(tv))) => { 57 (Ty::Never, Ty::InferenceVar(tv, TyVariableKind::General)) => {
57 let var = self.table.new_maybe_never_type_var(); 58 self.table.type_variable_table.set_diverging(*tv, true);
58 self.table.var_unification_table.union_value(*tv, TypeVarValue::Known(var));
59 return true; 59 return true;
60 } 60 }
61 (ty_app!(TypeCtor::Never), _) => return true, 61 (Ty::Never, _) => return true,
62 62
63 // Trivial cases, this should go after `never` check to 63 // Trivial cases, this should go after `never` check to
64 // avoid infer result type to be never 64 // avoid infer result type to be never
@@ -71,38 +71,33 @@ impl<'a> InferenceContext<'a> {
71 71
72 // Pointer weakening and function to pointer 72 // Pointer weakening and function to pointer
73 match (&mut from_ty, to_ty) { 73 match (&mut from_ty, to_ty) {
74 // `*mut T`, `&mut T, `&T`` -> `*const T` 74 // `*mut T` -> `*const T`
75 // `&mut T` -> `&T` 75 // `&mut T` -> `&T`
76 // `&mut T` -> `*mut T` 76 (Ty::Raw(m1, ..), Ty::Raw(m2 @ Mutability::Shared, ..))
77 (ty_app!(c1@TypeCtor::RawPtr(_)), ty_app!(c2@TypeCtor::RawPtr(Mutability::Shared))) 77 | (Ty::Ref(m1, ..), Ty::Ref(m2 @ Mutability::Shared, ..)) => {
78 | (ty_app!(c1@TypeCtor::Ref(_)), ty_app!(c2@TypeCtor::RawPtr(Mutability::Shared))) 78 *m1 = *m2;
79 | (ty_app!(c1@TypeCtor::Ref(_)), ty_app!(c2@TypeCtor::Ref(Mutability::Shared))) 79 }
80 | (ty_app!(c1@TypeCtor::Ref(Mutability::Mut)), ty_app!(c2@TypeCtor::RawPtr(_))) => { 80 // `&T` -> `*const T`
81 *c1 = *c2; 81 // `&mut T` -> `*mut T`/`*const T`
82 (Ty::Ref(.., substs), &Ty::Raw(m2 @ Mutability::Shared, ..))
83 | (Ty::Ref(Mutability::Mut, substs), &Ty::Raw(m2, ..)) => {
84 from_ty = Ty::Raw(m2, substs.clone());
82 } 85 }
83 86
84 // Illegal mutablity conversion 87 // Illegal mutability conversion
85 ( 88 (Ty::Raw(Mutability::Shared, ..), Ty::Raw(Mutability::Mut, ..))
86 ty_app!(TypeCtor::RawPtr(Mutability::Shared)), 89 | (Ty::Ref(Mutability::Shared, ..), Ty::Ref(Mutability::Mut, ..)) => return false,
87 ty_app!(TypeCtor::RawPtr(Mutability::Mut)),
88 )
89 | (
90 ty_app!(TypeCtor::Ref(Mutability::Shared)),
91 ty_app!(TypeCtor::Ref(Mutability::Mut)),
92 ) => return false,
93 90
94 // `{function_type}` -> `fn()` 91 // `{function_type}` -> `fn()`
95 (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnPtr { .. })) => { 92 (Ty::FnDef(..), Ty::Function { .. }) => match from_ty.callable_sig(self.db) {
96 match from_ty.callable_sig(self.db) { 93 None => return false,
97 None => return false, 94 Some(sig) => {
98 Some(sig) => { 95 from_ty = Ty::fn_ptr(sig);
99 from_ty = Ty::fn_ptr(sig);
100 }
101 } 96 }
102 } 97 },
103 98
104 (ty_app!(TypeCtor::Closure { .. }, params), ty_app!(TypeCtor::FnPtr { .. })) => { 99 (Ty::Closure(.., substs), Ty::Function { .. }) => {
105 from_ty = params[0].clone(); 100 from_ty = substs[0].clone();
106 } 101 }
107 102
108 _ => {} 103 _ => {}
@@ -115,9 +110,7 @@ impl<'a> InferenceContext<'a> {
115 // Auto Deref if cannot coerce 110 // Auto Deref if cannot coerce
116 match (&from_ty, to_ty) { 111 match (&from_ty, to_ty) {
117 // FIXME: DerefMut 112 // FIXME: DerefMut
118 (ty_app!(TypeCtor::Ref(_), st1), ty_app!(TypeCtor::Ref(_), st2)) => { 113 (Ty::Ref(_, st1), Ty::Ref(_, st2)) => self.unify_autoderef_behind_ref(&st1[0], &st2[0]),
119 self.unify_autoderef_behind_ref(&st1[0], &st2[0])
120 }
121 114
122 // Otherwise, normal unify 115 // Otherwise, normal unify
123 _ => self.unify(&from_ty, to_ty), 116 _ => self.unify(&from_ty, to_ty),
@@ -178,17 +171,17 @@ impl<'a> InferenceContext<'a> {
178 }, 171 },
179 ) { 172 ) {
180 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); 173 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value);
181 match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) { 174 let from_ty = self.resolve_ty_shallow(&derefed_ty);
182 // Stop when constructor matches. 175 // Stop when constructor matches.
183 (ty_app!(from_ctor, st1), ty_app!(to_ctor, st2)) if from_ctor == to_ctor => { 176 if from_ty.equals_ctor(&to_ty) {
184 // It will not recurse to `coerce`. 177 // It will not recurse to `coerce`.
185 return self.table.unify_substs(st1, st2, 0); 178 return match (from_ty.substs(), to_ty.substs()) {
186 } 179 (Some(st1), Some(st2)) => self.table.unify_substs(st1, st2, 0),
187 _ => { 180 (None, None) => true,
188 if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { 181 _ => false,
189 return true; 182 };
190 } 183 } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) {
191 } 184 return true;
192 } 185 }
193 } 186 }
194 187
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index cb59a6937..7852b3d23 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -3,8 +3,8 @@
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::TyVariableKind;
6use hir_def::{ 7use hir_def::{
7 builtin_type::Signedness,
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},
10 resolver::resolver_for_expr, 10 resolver::resolver_for_expr,
@@ -16,10 +16,11 @@ use test_utils::mark;
16 16
17use crate::{ 17use crate::{
18 autoderef, method_resolution, op, 18 autoderef, method_resolution, op,
19 primitive::{self, UintTy},
19 traits::{FnTrait, InEnvironment}, 20 traits::{FnTrait, InEnvironment},
20 utils::{generics, variant_data, Generics}, 21 utils::{generics, variant_data, Generics},
21 ApplicationTy, Binders, CallableDefId, InferTy, IntTy, Mutability, Obligation, OpaqueTyId, 22 Binders, CallableDefId, FnPointer, FnSig, Mutability, Obligation, OpaqueTyId, Rawness, Scalar,
22 Rawness, Substs, TraitRef, Ty, TypeCtor, 23 Substs, TraitRef, Ty,
23}; 24};
24 25
25use super::{ 26use super::{
@@ -82,10 +83,7 @@ impl<'a> InferenceContext<'a> {
82 arg_tys.push(arg); 83 arg_tys.push(arg);
83 } 84 }
84 let parameters = param_builder.build(); 85 let parameters = param_builder.build();
85 let arg_ty = Ty::Apply(ApplicationTy { 86 let arg_ty = Ty::Tuple(num_args, parameters);
86 ctor: TypeCtor::Tuple { cardinality: num_args as u16 },
87 parameters,
88 });
89 let substs = 87 let substs =
90 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 88 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
91 89
@@ -120,7 +118,7 @@ impl<'a> InferenceContext<'a> {
120 Expr::Missing => Ty::Unknown, 118 Expr::Missing => Ty::Unknown,
121 Expr::If { condition, then_branch, else_branch } => { 119 Expr::If { condition, then_branch, else_branch } => {
122 // if let is desugared to match, so this is always simple if 120 // if let is desugared to match, so this is always simple if
123 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); 121 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool)));
124 122
125 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); 123 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
126 let mut both_arms_diverge = Diverges::Always; 124 let mut both_arms_diverge = Diverges::Always;
@@ -175,7 +173,7 @@ impl<'a> InferenceContext<'a> {
175 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> 173 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
176 let inner_ty = self.infer_expr(*body, &Expectation::none()); 174 let inner_ty = self.infer_expr(*body, &Expectation::none());
177 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); 175 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body);
178 Ty::apply_one(TypeCtor::OpaqueType(opaque_ty_id), inner_ty) 176 Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty))
179 } 177 }
180 Expr::Loop { body, label } => { 178 Expr::Loop { body, label } => {
181 self.breakables.push(BreakableContext { 179 self.breakables.push(BreakableContext {
@@ -193,7 +191,7 @@ impl<'a> InferenceContext<'a> {
193 if ctxt.may_break { 191 if ctxt.may_break {
194 ctxt.break_ty 192 ctxt.break_ty
195 } else { 193 } else {
196 Ty::simple(TypeCtor::Never) 194 Ty::Never
197 } 195 }
198 } 196 }
199 Expr::While { condition, body, label } => { 197 Expr::While { condition, body, label } => {
@@ -203,7 +201,7 @@ impl<'a> InferenceContext<'a> {
203 label: label.map(|label| self.body[label].name.clone()), 201 label: label.map(|label| self.body[label].name.clone()),
204 }); 202 });
205 // while let is desugared to a match loop, so this is always simple while 203 // while let is desugared to a match loop, so this is always simple while
206 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); 204 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool)));
207 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 205 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
208 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 206 let _ctxt = self.breakables.pop().expect("breakable stack broken");
209 // the body may not run, so it diverging doesn't mean we diverge 207 // the body may not run, so it diverging doesn't mean we diverge
@@ -250,12 +248,12 @@ impl<'a> InferenceContext<'a> {
250 None => self.table.new_type_var(), 248 None => self.table.new_type_var(),
251 }; 249 };
252 sig_tys.push(ret_ty.clone()); 250 sig_tys.push(ret_ty.clone());
253 let sig_ty = Ty::apply( 251 let sig_ty = Ty::Function(FnPointer {
254 TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1, is_varargs: false }, 252 num_args: sig_tys.len() - 1,
255 Substs(sig_tys.clone().into()), 253 sig: FnSig { variadic: false },
256 ); 254 substs: Substs(sig_tys.clone().into()),
257 let closure_ty = 255 });
258 Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); 256 let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty));
259 257
260 // Eagerly try to relate the closure type with the expected 258 // Eagerly try to relate the closure type with the expected
261 // type, otherwise we often won't have enough information to 259 // type, otherwise we often won't have enough information to
@@ -306,11 +304,8 @@ impl<'a> InferenceContext<'a> {
306 Expr::Match { expr, arms } => { 304 Expr::Match { expr, arms } => {
307 let input_ty = self.infer_expr(*expr, &Expectation::none()); 305 let input_ty = self.infer_expr(*expr, &Expectation::none());
308 306
309 let mut result_ty = if arms.is_empty() { 307 let mut result_ty =
310 Ty::simple(TypeCtor::Never) 308 if arms.is_empty() { Ty::Never } else { self.table.new_type_var() };
311 } else {
312 self.table.new_type_var()
313 };
314 309
315 let matchee_diverges = self.diverges; 310 let matchee_diverges = self.diverges;
316 let mut all_arms_diverge = Diverges::Always; 311 let mut all_arms_diverge = Diverges::Always;
@@ -321,7 +316,7 @@ impl<'a> InferenceContext<'a> {
321 if let Some(guard_expr) = arm.guard { 316 if let Some(guard_expr) = arm.guard {
322 self.infer_expr( 317 self.infer_expr(
323 guard_expr, 318 guard_expr,
324 &Expectation::has_type(Ty::simple(TypeCtor::Bool)), 319 &Expectation::has_type(Ty::Scalar(Scalar::Bool)),
325 ); 320 );
326 } 321 }
327 322
@@ -339,7 +334,7 @@ impl<'a> InferenceContext<'a> {
339 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); 334 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
340 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) 335 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown)
341 } 336 }
342 Expr::Continue { .. } => Ty::simple(TypeCtor::Never), 337 Expr::Continue { .. } => Ty::Never,
343 Expr::Break { expr, label } => { 338 Expr::Break { expr, label } => {
344 let val_ty = if let Some(expr) = expr { 339 let val_ty = if let Some(expr) = expr {
345 self.infer_expr(*expr, &Expectation::none()) 340 self.infer_expr(*expr, &Expectation::none())
@@ -364,8 +359,7 @@ impl<'a> InferenceContext<'a> {
364 expr: tgt_expr, 359 expr: tgt_expr,
365 }); 360 });
366 } 361 }
367 362 Ty::Never
368 Ty::simple(TypeCtor::Never)
369 } 363 }
370 Expr::Return { expr } => { 364 Expr::Return { expr } => {
371 if let Some(expr) = expr { 365 if let Some(expr) = expr {
@@ -374,14 +368,14 @@ impl<'a> InferenceContext<'a> {
374 let unit = Ty::unit(); 368 let unit = Ty::unit();
375 self.coerce(&unit, &self.return_ty.clone()); 369 self.coerce(&unit, &self.return_ty.clone());
376 } 370 }
377 Ty::simple(TypeCtor::Never) 371 Ty::Never
378 } 372 }
379 Expr::Yield { expr } => { 373 Expr::Yield { expr } => {
380 // FIXME: track yield type for coercion 374 // FIXME: track yield type for coercion
381 if let Some(expr) = expr { 375 if let Some(expr) = expr {
382 self.infer_expr(*expr, &Expectation::none()); 376 self.infer_expr(*expr, &Expectation::none());
383 } 377 }
384 Ty::simple(TypeCtor::Never) 378 Ty::Never
385 } 379 }
386 Expr::RecordLit { path, fields, spread } => { 380 Expr::RecordLit { path, fields, spread } => {
387 let (ty, def_id) = self.resolve_variant(path.as_ref()); 381 let (ty, def_id) = self.resolve_variant(path.as_ref());
@@ -391,7 +385,7 @@ impl<'a> InferenceContext<'a> {
391 385
392 self.unify(&ty, &expected.ty); 386 self.unify(&ty, &expected.ty);
393 387
394 let substs = ty.substs().unwrap_or_else(Substs::empty); 388 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
395 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); 389 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
396 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); 390 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
397 for (field_idx, field) in fields.iter().enumerate() { 391 for (field_idx, field) in fields.iter().enumerate() {
@@ -430,30 +424,23 @@ impl<'a> InferenceContext<'a> {
430 }, 424 },
431 ) 425 )
432 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { 426 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) {
433 Ty::Apply(a_ty) => match a_ty.ctor { 427 Ty::Tuple(_, substs) => {
434 TypeCtor::Tuple { .. } => name 428 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned())
435 .as_tuple_index() 429 }
436 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), 430 Ty::Adt(AdtId::StructId(s), parameters) => {
437 TypeCtor::Adt(AdtId::StructId(s)) => { 431 self.db.struct_data(s).variant_data.field(name).map(|local_id| {
438 self.db.struct_data(s).variant_data.field(name).map(|local_id| { 432 let field = FieldId { parent: s.into(), local_id };
439 let field = FieldId { parent: s.into(), local_id }; 433 self.write_field_resolution(tgt_expr, field);
440 self.write_field_resolution(tgt_expr, field); 434 self.db.field_types(s.into())[field.local_id].clone().subst(&parameters)
441 self.db.field_types(s.into())[field.local_id] 435 })
442 .clone() 436 }
443 .subst(&a_ty.parameters) 437 Ty::Adt(AdtId::UnionId(u), parameters) => {
444 }) 438 self.db.union_data(u).variant_data.field(name).map(|local_id| {
445 } 439 let field = FieldId { parent: u.into(), local_id };
446 TypeCtor::Adt(AdtId::UnionId(u)) => { 440 self.write_field_resolution(tgt_expr, field);
447 self.db.union_data(u).variant_data.field(name).map(|local_id| { 441 self.db.field_types(u.into())[field.local_id].clone().subst(&parameters)
448 let field = FieldId { parent: u.into(), local_id }; 442 })
449 self.write_field_resolution(tgt_expr, field); 443 }
450 self.db.field_types(u.into())[field.local_id]
451 .clone()
452 .subst(&a_ty.parameters)
453 })
454 }
455 _ => None,
456 },
457 _ => None, 444 _ => None,
458 }) 445 })
459 .unwrap_or(Ty::Unknown); 446 .unwrap_or(Ty::Unknown);
@@ -491,19 +478,24 @@ impl<'a> InferenceContext<'a> {
491 Expectation::none() 478 Expectation::none()
492 }; 479 };
493 let inner_ty = self.infer_expr_inner(*expr, &expectation); 480 let inner_ty = self.infer_expr_inner(*expr, &expectation);
494 let ty = match rawness { 481 match rawness {
495 Rawness::RawPtr => TypeCtor::RawPtr(*mutability), 482 Rawness::RawPtr => Ty::Raw(*mutability, Substs::single(inner_ty)),
496 Rawness::Ref => TypeCtor::Ref(*mutability), 483 Rawness::Ref => Ty::Ref(*mutability, Substs::single(inner_ty)),
497 }; 484 }
498 Ty::apply_one(ty, inner_ty)
499 } 485 }
500 Expr::Box { expr } => { 486 Expr::Box { expr } => {
501 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 487 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
502 if let Some(box_) = self.resolve_boxed_box() { 488 if let Some(box_) = self.resolve_boxed_box() {
503 let mut sb = Substs::build_for_type_ctor(self.db, TypeCtor::Adt(box_)); 489 let mut sb = Substs::builder(generics(self.db.upcast(), box_.into()).len());
504 sb = sb.push(inner_ty); 490 sb = sb.push(inner_ty);
491 match self.db.generic_defaults(box_.into()).as_ref() {
492 [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => {
493 sb = sb.push(alloc_ty.value.clone());
494 }
495 _ => (),
496 }
505 sb = sb.fill(repeat_with(|| self.table.new_type_var())); 497 sb = sb.fill(repeat_with(|| self.table.new_type_var()));
506 Ty::apply(TypeCtor::Adt(box_), sb.build()) 498 Ty::Adt(box_, sb.build())
507 } else { 499 } else {
508 Ty::Unknown 500 Ty::Unknown
509 } 501 }
@@ -533,13 +525,11 @@ impl<'a> InferenceContext<'a> {
533 UnaryOp::Neg => { 525 UnaryOp::Neg => {
534 match &inner_ty { 526 match &inner_ty {
535 // Fast path for builtins 527 // Fast path for builtins
536 Ty::Apply(ApplicationTy { 528 Ty::Scalar(Scalar::Int(_))
537 ctor: TypeCtor::Int(IntTy { signedness: Signedness::Signed, .. }), 529 | Ty::Scalar(Scalar::Uint(_))
538 .. 530 | Ty::Scalar(Scalar::Float(_))
539 }) 531 | Ty::InferenceVar(_, TyVariableKind::Integer)
540 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. }) 532 | Ty::InferenceVar(_, TyVariableKind::Float) => inner_ty,
541 | Ty::Infer(InferTy::IntVar(..))
542 | Ty::Infer(InferTy::FloatVar(..)) => inner_ty,
543 // Otherwise we resolve via the std::ops::Neg trait 533 // Otherwise we resolve via the std::ops::Neg trait
544 _ => self 534 _ => self
545 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), 535 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()),
@@ -548,9 +538,10 @@ impl<'a> InferenceContext<'a> {
548 UnaryOp::Not => { 538 UnaryOp::Not => {
549 match &inner_ty { 539 match &inner_ty {
550 // Fast path for builtins 540 // Fast path for builtins
551 Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }) 541 Ty::Scalar(Scalar::Bool)
552 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(_), .. }) 542 | Ty::Scalar(Scalar::Int(_))
553 | Ty::Infer(InferTy::IntVar(..)) => inner_ty, 543 | Ty::Scalar(Scalar::Uint(_))
544 | Ty::InferenceVar(_, TyVariableKind::Integer) => inner_ty,
554 // Otherwise we resolve via the std::ops::Not trait 545 // Otherwise we resolve via the std::ops::Not trait
555 _ => self 546 _ => self
556 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), 547 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()),
@@ -561,7 +552,7 @@ impl<'a> InferenceContext<'a> {
561 Expr::BinaryOp { lhs, rhs, op } => match op { 552 Expr::BinaryOp { lhs, rhs, op } => match op {
562 Some(op) => { 553 Some(op) => {
563 let lhs_expectation = match op { 554 let lhs_expectation = match op {
564 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::simple(TypeCtor::Bool)), 555 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)),
565 _ => Expectation::none(), 556 _ => Expectation::none(),
566 }; 557 };
567 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); 558 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
@@ -592,31 +583,31 @@ impl<'a> InferenceContext<'a> {
592 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); 583 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
593 match (range_type, lhs_ty, rhs_ty) { 584 match (range_type, lhs_ty, rhs_ty) {
594 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 585 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
595 Some(adt) => Ty::simple(TypeCtor::Adt(adt)), 586 Some(adt) => Ty::Adt(adt, Substs::empty()),
596 None => Ty::Unknown, 587 None => Ty::Unknown,
597 }, 588 },
598 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 589 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
599 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 590 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
600 None => Ty::Unknown, 591 None => Ty::Unknown,
601 }, 592 },
602 (RangeOp::Inclusive, None, Some(ty)) => { 593 (RangeOp::Inclusive, None, Some(ty)) => {
603 match self.resolve_range_to_inclusive() { 594 match self.resolve_range_to_inclusive() {
604 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 595 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
605 None => Ty::Unknown, 596 None => Ty::Unknown,
606 } 597 }
607 } 598 }
608 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 599 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
609 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 600 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
610 None => Ty::Unknown, 601 None => Ty::Unknown,
611 }, 602 },
612 (RangeOp::Inclusive, Some(_), Some(ty)) => { 603 (RangeOp::Inclusive, Some(_), Some(ty)) => {
613 match self.resolve_range_inclusive() { 604 match self.resolve_range_inclusive() {
614 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 605 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
615 None => Ty::Unknown, 606 None => Ty::Unknown,
616 } 607 }
617 } 608 }
618 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 609 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
619 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 610 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
620 None => Ty::Unknown, 611 None => Ty::Unknown,
621 }, 612 },
622 (RangeOp::Inclusive, _, None) => Ty::Unknown, 613 (RangeOp::Inclusive, _, None) => Ty::Unknown,
@@ -650,7 +641,7 @@ impl<'a> InferenceContext<'a> {
650 } 641 }
651 Expr::Tuple { exprs } => { 642 Expr::Tuple { exprs } => {
652 let mut tys = match &expected.ty { 643 let mut tys = match &expected.ty {
653 ty_app!(TypeCtor::Tuple { .. }, st) => st 644 Ty::Tuple(_, substs) => substs
654 .iter() 645 .iter()
655 .cloned() 646 .cloned()
656 .chain(repeat_with(|| self.table.new_type_var())) 647 .chain(repeat_with(|| self.table.new_type_var()))
@@ -663,15 +654,11 @@ impl<'a> InferenceContext<'a> {
663 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 654 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
664 } 655 }
665 656
666 Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into())) 657 Ty::Tuple(tys.len(), Substs(tys.into()))
667 } 658 }
668 Expr::Array(array) => { 659 Expr::Array(array) => {
669 let elem_ty = match &expected.ty { 660 let elem_ty = match &expected.ty {
670 // FIXME: remove when https://github.com/rust-lang/rust/issues/80501 is fixed 661 Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(),
671 #[allow(unreachable_patterns)]
672 ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => {
673 st.as_single().clone()
674 }
675 _ => self.table.new_type_var(), 662 _ => self.table.new_type_var(),
676 }; 663 };
677 664
@@ -688,30 +675,38 @@ impl<'a> InferenceContext<'a> {
688 ); 675 );
689 self.infer_expr( 676 self.infer_expr(
690 *repeat, 677 *repeat,
691 &Expectation::has_type(Ty::simple(TypeCtor::Int(IntTy::usize()))), 678 &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))),
692 ); 679 );
693 } 680 }
694 } 681 }
695 682
696 Ty::apply_one(TypeCtor::Array, elem_ty) 683 Ty::Array(Substs::single(elem_ty))
697 } 684 }
698 Expr::Literal(lit) => match lit { 685 Expr::Literal(lit) => match lit {
699 Literal::Bool(..) => Ty::simple(TypeCtor::Bool), 686 Literal::Bool(..) => Ty::Scalar(Scalar::Bool),
700 Literal::String(..) => { 687 Literal::String(..) => Ty::Ref(Mutability::Shared, Substs::single(Ty::Str)),
701 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str))
702 }
703 Literal::ByteString(..) => { 688 Literal::ByteString(..) => {
704 let byte_type = Ty::simple(TypeCtor::Int(IntTy::u8())); 689 let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8));
705 let array_type = Ty::apply_one(TypeCtor::Array, byte_type); 690 let array_type = Ty::Array(Substs::single(byte_type));
706 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) 691 Ty::Ref(Mutability::Shared, Substs::single(array_type))
707 } 692 }
708 Literal::Char(..) => Ty::simple(TypeCtor::Char), 693 Literal::Char(..) => Ty::Scalar(Scalar::Char),
709 Literal::Int(_v, ty) => match ty { 694 Literal::Int(_v, ty) => match ty {
710 Some(int_ty) => Ty::simple(TypeCtor::Int((*int_ty).into())), 695 Some(int_ty) => {
696 Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty)))
697 }
698 None => self.table.new_integer_var(),
699 },
700 Literal::Uint(_v, ty) => match ty {
701 Some(int_ty) => {
702 Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty)))
703 }
711 None => self.table.new_integer_var(), 704 None => self.table.new_integer_var(),
712 }, 705 },
713 Literal::Float(_v, ty) => match ty { 706 Literal::Float(_v, ty) => match ty {
714 Some(float_ty) => Ty::simple(TypeCtor::Float((*float_ty).into())), 707 Some(float_ty) => {
708 Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty)))
709 }
715 None => self.table.new_float_var(), 710 None => self.table.new_float_var(),
716 }, 711 },
717 }, 712 },
@@ -767,7 +762,7 @@ impl<'a> InferenceContext<'a> {
767 // `!`). 762 // `!`).
768 if self.diverges.is_always() { 763 if self.diverges.is_always() {
769 // we don't even make an attempt at coercion 764 // we don't even make an attempt at coercion
770 self.table.new_maybe_never_type_var() 765 self.table.new_maybe_never_var()
771 } else { 766 } else {
772 self.coerce(&Ty::unit(), expected.coercion_target()); 767 self.coerce(&Ty::unit(), expected.coercion_target());
773 Ty::unit() 768 Ty::unit()
@@ -824,7 +819,7 @@ impl<'a> InferenceContext<'a> {
824 // Apply autoref so the below unification works correctly 819 // Apply autoref so the below unification works correctly
825 // FIXME: return correct autorefs from lookup_method 820 // FIXME: return correct autorefs from lookup_method
826 let actual_receiver_ty = match expected_receiver_ty.as_reference() { 821 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
827 Some((_, mutability)) => Ty::apply_one(TypeCtor::Ref(mutability), derefed_receiver_ty), 822 Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)),
828 _ => derefed_receiver_ty, 823 _ => derefed_receiver_ty,
829 }; 824 };
830 self.unify(&expected_receiver_ty, &actual_receiver_ty); 825 self.unify(&expected_receiver_ty, &actual_receiver_ty);
@@ -901,30 +896,26 @@ impl<'a> InferenceContext<'a> {
901 } 896 }
902 897
903 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 898 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
904 if let Ty::Apply(a_ty) = callable_ty { 899 if let &Ty::FnDef(def, ref parameters) = callable_ty {
905 if let TypeCtor::FnDef(def) = a_ty.ctor { 900 let generic_predicates = self.db.generic_predicates(def.into());
906 let generic_predicates = self.db.generic_predicates(def.into()); 901 for predicate in generic_predicates.iter() {
907 for predicate in generic_predicates.iter() { 902 let predicate = predicate.clone().subst(parameters);
908 let predicate = predicate.clone().subst(&a_ty.parameters); 903 if let Some(obligation) = Obligation::from_predicate(predicate) {
909 if let Some(obligation) = Obligation::from_predicate(predicate) { 904 self.obligations.push(obligation);
910 self.obligations.push(obligation);
911 }
912 } 905 }
913 // add obligation for trait implementation, if this is a trait method 906 }
914 match def { 907 // add obligation for trait implementation, if this is a trait method
915 CallableDefId::FunctionId(f) => { 908 match def {
916 if let AssocContainerId::TraitId(trait_) = 909 CallableDefId::FunctionId(f) => {
917 f.lookup(self.db.upcast()).container 910 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container
918 { 911 {
919 // construct a TraitDef 912 // construct a TraitDef
920 let substs = a_ty 913 let substs =
921 .parameters 914 parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
922 .prefix(generics(self.db.upcast(), trait_.into()).len()); 915 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
923 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
924 }
925 } 916 }
926 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
927 } 917 }
918 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
928 } 919 }
929 } 920 }
930 } 921 }
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index d974f805b..a318e47f3 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -13,7 +13,7 @@ use hir_expand::name::Name;
13use test_utils::mark; 13use test_utils::mark;
14 14
15use super::{BindingMode, Expectation, InferenceContext}; 15use super::{BindingMode, Expectation, InferenceContext};
16use crate::{utils::variant_data, Substs, Ty, TypeCtor}; 16use crate::{utils::variant_data, Substs, Ty};
17 17
18impl<'a> InferenceContext<'a> { 18impl<'a> InferenceContext<'a> {
19 fn infer_tuple_struct_pat( 19 fn infer_tuple_struct_pat(
@@ -32,7 +32,7 @@ impl<'a> InferenceContext<'a> {
32 } 32 }
33 self.unify(&ty, expected); 33 self.unify(&ty, expected);
34 34
35 let substs = ty.substs().unwrap_or_else(Substs::empty); 35 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
36 36
37 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 37 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
38 let (pre, post) = match ellipsis { 38 let (pre, post) = match ellipsis {
@@ -71,7 +71,7 @@ impl<'a> InferenceContext<'a> {
71 71
72 self.unify(&ty, expected); 72 self.unify(&ty, expected);
73 73
74 let substs = ty.substs().unwrap_or_else(Substs::empty); 74 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
75 75
76 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 76 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
77 for subpat in subpats { 77 for subpat in subpats {
@@ -138,10 +138,7 @@ impl<'a> InferenceContext<'a> {
138 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); 138 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
139 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); 139 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
140 140
141 Ty::apply( 141 Ty::Tuple(inner_tys.len(), Substs(inner_tys.into()))
142 TypeCtor::Tuple { cardinality: inner_tys.len() as u16 },
143 Substs(inner_tys.into()),
144 )
145 } 142 }
146 Pat::Or(ref pats) => { 143 Pat::Or(ref pats) => {
147 if let Some((first_pat, rest)) = pats.split_first() { 144 if let Some((first_pat, rest)) = pats.split_first() {
@@ -165,7 +162,7 @@ impl<'a> InferenceContext<'a> {
165 _ => &Ty::Unknown, 162 _ => &Ty::Unknown,
166 }; 163 };
167 let subty = self.infer_pat(*pat, expectation, default_bm); 164 let subty = self.infer_pat(*pat, expectation, default_bm);
168 Ty::apply_one(TypeCtor::Ref(*mutability), subty) 165 Ty::Ref(*mutability, Substs::single(subty))
169 } 166 }
170 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( 167 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat(
171 p.as_ref(), 168 p.as_ref(),
@@ -198,7 +195,7 @@ impl<'a> InferenceContext<'a> {
198 195
199 let bound_ty = match mode { 196 let bound_ty = match mode {
200 BindingMode::Ref(mutability) => { 197 BindingMode::Ref(mutability) => {
201 Ty::apply_one(TypeCtor::Ref(mutability), inner_ty.clone()) 198 Ty::Ref(mutability, Substs::single(inner_ty.clone()))
202 } 199 }
203 BindingMode::Move => inner_ty.clone(), 200 BindingMode::Move => inner_ty.clone(),
204 }; 201 };
@@ -207,17 +204,17 @@ impl<'a> InferenceContext<'a> {
207 return inner_ty; 204 return inner_ty;
208 } 205 }
209 Pat::Slice { prefix, slice, suffix } => { 206 Pat::Slice { prefix, slice, suffix } => {
210 let (container_ty, elem_ty) = match &expected { 207 let (container_ty, elem_ty): (fn(_) -> _, _) = match &expected {
211 ty_app!(TypeCtor::Array, st) => (TypeCtor::Array, st.as_single().clone()), 208 Ty::Array(st) => (Ty::Array, st.as_single().clone()),
212 ty_app!(TypeCtor::Slice, st) => (TypeCtor::Slice, st.as_single().clone()), 209 Ty::Slice(st) => (Ty::Slice, st.as_single().clone()),
213 _ => (TypeCtor::Slice, Ty::Unknown), 210 _ => (Ty::Slice, Ty::Unknown),
214 }; 211 };
215 212
216 for pat_id in prefix.iter().chain(suffix) { 213 for pat_id in prefix.iter().chain(suffix) {
217 self.infer_pat(*pat_id, &elem_ty, default_bm); 214 self.infer_pat(*pat_id, &elem_ty, default_bm);
218 } 215 }
219 216
220 let pat_ty = Ty::apply_one(container_ty, elem_ty); 217 let pat_ty = container_ty(Substs::single(elem_ty));
221 if let Some(slice_pat_id) = slice { 218 if let Some(slice_pat_id) = slice {
222 self.infer_pat(*slice_pat_id, &pat_ty, default_bm); 219 self.infer_pat(*slice_pat_id, &pat_ty, default_bm);
223 } 220 }
@@ -239,7 +236,7 @@ impl<'a> InferenceContext<'a> {
239 }; 236 };
240 237
241 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); 238 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm);
242 Ty::apply_one(TypeCtor::Adt(box_adt), inner_ty) 239 Ty::Adt(box_adt, Substs::single(inner_ty))
243 } 240 }
244 None => Ty::Unknown, 241 None => Ty::Unknown,
245 }, 242 },
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 76984242e..99a89a7f3 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -2,14 +2,15 @@
2 2
3use std::borrow::Cow; 3use std::borrow::Cow;
4 4
5use chalk_ir::{FloatTy, IntTy, TyVariableKind};
5use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; 6use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
6 7
7use test_utils::mark; 8use test_utils::mark;
8 9
9use super::{InferenceContext, Obligation}; 10use super::{InferenceContext, Obligation};
10use crate::{ 11use crate::{
11 BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Substs, Ty, 12 BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferenceVar, Scalar,
12 TyKind, TypeCtor, TypeWalk, 13 Substs, Ty, TypeWalk,
13}; 14};
14 15
15impl<'a> InferenceContext<'a> { 16impl<'a> InferenceContext<'a> {
@@ -26,7 +27,7 @@ where
26 'a: 'b, 27 'a: 'b,
27{ 28{
28 ctx: &'b mut InferenceContext<'a>, 29 ctx: &'b mut InferenceContext<'a>,
29 free_vars: Vec<InferTy>, 30 free_vars: Vec<(InferenceVar, TyVariableKind)>,
30 /// A stack of type variables that is used to detect recursive types (which 31 /// A stack of type variables that is used to detect recursive types (which
31 /// are an error, but we need to protect against them to avoid stack 32 /// are an error, but we need to protect against them to avoid stack
32 /// overflows). 33 /// overflows).
@@ -36,17 +37,14 @@ where
36#[derive(Debug)] 37#[derive(Debug)]
37pub(super) struct Canonicalized<T> { 38pub(super) struct Canonicalized<T> {
38 pub(super) value: Canonical<T>, 39 pub(super) value: Canonical<T>,
39 free_vars: Vec<InferTy>, 40 free_vars: Vec<(InferenceVar, TyVariableKind)>,
40} 41}
41 42
42impl<'a, 'b> Canonicalizer<'a, 'b> 43impl<'a, 'b> Canonicalizer<'a, 'b> {
43where 44 fn add(&mut self, free_var: InferenceVar, kind: TyVariableKind) -> usize {
44 'a: 'b, 45 self.free_vars.iter().position(|&(v, _)| v == free_var).unwrap_or_else(|| {
45{
46 fn add(&mut self, free_var: InferTy) -> usize {
47 self.free_vars.iter().position(|&v| v == free_var).unwrap_or_else(|| {
48 let next_index = self.free_vars.len(); 46 let next_index = self.free_vars.len();
49 self.free_vars.push(free_var); 47 self.free_vars.push((free_var, kind));
50 next_index 48 next_index
51 }) 49 })
52 } 50 }
@@ -54,11 +52,11 @@ where
54 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { 52 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T {
55 t.fold_binders( 53 t.fold_binders(
56 &mut |ty, binders| match ty { 54 &mut |ty, binders| match ty {
57 Ty::Infer(tv) => { 55 Ty::InferenceVar(var, kind) => {
58 let inner = tv.to_inner(); 56 let inner = var.to_inner();
59 if self.var_stack.contains(&inner) { 57 if self.var_stack.contains(&inner) {
60 // recursive type 58 // recursive type
61 return tv.fallback_value(); 59 return self.ctx.table.type_variable_table.fallback_value(var, kind);
62 } 60 }
63 if let Some(known_ty) = 61 if let Some(known_ty) =
64 self.ctx.table.var_unification_table.inlined_probe_value(inner).known() 62 self.ctx.table.var_unification_table.inlined_probe_value(inner).known()
@@ -69,14 +67,8 @@ where
69 result 67 result
70 } else { 68 } else {
71 let root = self.ctx.table.var_unification_table.find(inner); 69 let root = self.ctx.table.var_unification_table.find(inner);
72 let free_var = match tv { 70 let position = self.add(InferenceVar::from_inner(root), kind);
73 InferTy::TypeVar(_) => InferTy::TypeVar(root), 71 Ty::BoundVar(BoundVar::new(binders, position))
74 InferTy::IntVar(_) => InferTy::IntVar(root),
75 InferTy::FloatVar(_) => InferTy::FloatVar(root),
76 InferTy::MaybeNeverTypeVar(_) => InferTy::MaybeNeverTypeVar(root),
77 };
78 let position = self.add(free_var);
79 Ty::Bound(BoundVar::new(binders, position))
80 } 72 }
81 } 73 }
82 _ => ty, 74 _ => ty,
@@ -86,19 +78,7 @@ where
86 } 78 }
87 79
88 fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> { 80 fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> {
89 let kinds = self 81 let kinds = self.free_vars.iter().map(|&(_, k)| k).collect();
90 .free_vars
91 .iter()
92 .map(|v| match v {
93 // mapping MaybeNeverTypeVar to the same kind as general ones
94 // should be fine, because as opposed to int or float type vars,
95 // they don't restrict what kind of type can go into them, they
96 // just affect fallback.
97 InferTy::TypeVar(_) | InferTy::MaybeNeverTypeVar(_) => TyKind::General,
98 InferTy::IntVar(_) => TyKind::Integer,
99 InferTy::FloatVar(_) => TyKind::Float,
100 })
101 .collect();
102 Canonicalized { value: Canonical { value: result, kinds }, free_vars: self.free_vars } 82 Canonicalized { value: Canonical { value: result, kinds }, free_vars: self.free_vars }
103 } 83 }
104 84
@@ -130,9 +110,10 @@ impl<T> Canonicalized<T> {
130 pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { 110 pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty {
131 ty.walk_mut_binders( 111 ty.walk_mut_binders(
132 &mut |ty, binders| { 112 &mut |ty, binders| {
133 if let &mut Ty::Bound(bound) = ty { 113 if let &mut Ty::BoundVar(bound) = ty {
134 if bound.debruijn >= binders { 114 if bound.debruijn >= binders {
135 *ty = Ty::Infer(self.free_vars[bound.index]); 115 let (v, k) = self.free_vars[bound.index];
116 *ty = Ty::InferenceVar(v, k);
136 } 117 }
137 } 118 }
138 }, 119 },
@@ -152,18 +133,18 @@ impl<T> Canonicalized<T> {
152 .kinds 133 .kinds
153 .iter() 134 .iter()
154 .map(|k| match k { 135 .map(|k| match k {
155 TyKind::General => ctx.table.new_type_var(), 136 TyVariableKind::General => ctx.table.new_type_var(),
156 TyKind::Integer => ctx.table.new_integer_var(), 137 TyVariableKind::Integer => ctx.table.new_integer_var(),
157 TyKind::Float => ctx.table.new_float_var(), 138 TyVariableKind::Float => ctx.table.new_float_var(),
158 }) 139 })
159 .collect(), 140 .collect(),
160 ); 141 );
161 for (i, ty) in solution.value.into_iter().enumerate() { 142 for (i, ty) in solution.value.into_iter().enumerate() {
162 let var = self.free_vars[i]; 143 let (v, k) = self.free_vars[i];
163 // eagerly replace projections in the type; we may be getting types 144 // eagerly replace projections in the type; we may be getting types
164 // e.g. from where clauses where this hasn't happened yet 145 // e.g. from where clauses where this hasn't happened yet
165 let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); 146 let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars));
166 ctx.table.unify(&Ty::Infer(var), &ty); 147 ctx.table.unify(&Ty::InferenceVar(v, k), &ty);
167 } 148 }
168 } 149 }
169} 150}
@@ -187,7 +168,7 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> {
187 // (kind of hacky) 168 // (kind of hacky)
188 for (i, var) in vars.iter().enumerate() { 169 for (i, var) in vars.iter().enumerate() {
189 if &*table.resolve_ty_shallow(var) == var { 170 if &*table.resolve_ty_shallow(var) == var {
190 table.unify(var, &Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i))); 171 table.unify(var, &Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i)));
191 } 172 }
192 } 173 }
193 Some( 174 Some(
@@ -198,31 +179,73 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> {
198} 179}
199 180
200#[derive(Clone, Debug)] 181#[derive(Clone, Debug)]
182pub(super) struct TypeVariableTable {
183 inner: Vec<TypeVariableData>,
184}
185
186impl TypeVariableTable {
187 fn push(&mut self, data: TypeVariableData) {
188 self.inner.push(data);
189 }
190
191 pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) {
192 self.inner[iv.to_inner().0 as usize].diverging = diverging;
193 }
194
195 fn is_diverging(&mut self, iv: InferenceVar) -> bool {
196 self.inner[iv.to_inner().0 as usize].diverging
197 }
198
199 fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty {
200 match kind {
201 _ if self.inner[iv.to_inner().0 as usize].diverging => Ty::Never,
202 TyVariableKind::General => Ty::Unknown,
203 TyVariableKind::Integer => Ty::Scalar(Scalar::Int(IntTy::I32)),
204 TyVariableKind::Float => Ty::Scalar(Scalar::Float(FloatTy::F64)),
205 }
206 }
207}
208
209#[derive(Copy, Clone, Debug)]
210pub(crate) struct TypeVariableData {
211 diverging: bool,
212}
213
214#[derive(Clone, Debug)]
201pub(crate) struct InferenceTable { 215pub(crate) struct InferenceTable {
202 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>, 216 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>,
217 pub(super) type_variable_table: TypeVariableTable,
203} 218}
204 219
205impl InferenceTable { 220impl InferenceTable {
206 pub(crate) fn new() -> Self { 221 pub(crate) fn new() -> Self {
207 InferenceTable { var_unification_table: InPlaceUnificationTable::new() } 222 InferenceTable {
223 var_unification_table: InPlaceUnificationTable::new(),
224 type_variable_table: TypeVariableTable { inner: Vec::new() },
225 }
226 }
227
228 fn new_var(&mut self, kind: TyVariableKind, diverging: bool) -> Ty {
229 self.type_variable_table.push(TypeVariableData { diverging });
230 let key = self.var_unification_table.new_key(TypeVarValue::Unknown);
231 assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1);
232 Ty::InferenceVar(InferenceVar::from_inner(key), kind)
208 } 233 }
209 234
210 pub(crate) fn new_type_var(&mut self) -> Ty { 235 pub(crate) fn new_type_var(&mut self) -> Ty {
211 Ty::Infer(InferTy::TypeVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) 236 self.new_var(TyVariableKind::General, false)
212 } 237 }
213 238
214 pub(crate) fn new_integer_var(&mut self) -> Ty { 239 pub(crate) fn new_integer_var(&mut self) -> Ty {
215 Ty::Infer(InferTy::IntVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) 240 self.new_var(TyVariableKind::Integer, false)
216 } 241 }
217 242
218 pub(crate) fn new_float_var(&mut self) -> Ty { 243 pub(crate) fn new_float_var(&mut self) -> Ty {
219 Ty::Infer(InferTy::FloatVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) 244 self.new_var(TyVariableKind::Float, false)
220 } 245 }
221 246
222 pub(crate) fn new_maybe_never_type_var(&mut self) -> Ty { 247 pub(crate) fn new_maybe_never_var(&mut self) -> Ty {
223 Ty::Infer(InferTy::MaybeNeverTypeVar( 248 self.new_var(TyVariableKind::General, true)
224 self.var_unification_table.new_key(TypeVarValue::Unknown),
225 ))
226 } 249 }
227 250
228 pub(crate) fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { 251 pub(crate) fn resolve_ty_completely(&mut self, ty: Ty) -> Ty {
@@ -257,12 +280,14 @@ impl InferenceTable {
257 // try to resolve type vars first 280 // try to resolve type vars first
258 let ty1 = self.resolve_ty_shallow(ty1); 281 let ty1 = self.resolve_ty_shallow(ty1);
259 let ty2 = self.resolve_ty_shallow(ty2); 282 let ty2 = self.resolve_ty_shallow(ty2);
260 match (&*ty1, &*ty2) { 283 if ty1.equals_ctor(&ty2) {
261 (Ty::Apply(a_ty1), Ty::Apply(a_ty2)) if a_ty1.ctor == a_ty2.ctor => { 284 match (ty1.substs(), ty2.substs()) {
262 self.unify_substs(&a_ty1.parameters, &a_ty2.parameters, depth + 1) 285 (Some(st1), Some(st2)) => self.unify_substs(st1, st2, depth + 1),
286 (None, None) => true,
287 _ => false,
263 } 288 }
264 289 } else {
265 _ => self.unify_inner_trivial(&ty1, &ty2, depth), 290 self.unify_inner_trivial(&ty1, &ty2, depth)
266 } 291 }
267 } 292 }
268 293
@@ -281,31 +306,46 @@ impl InferenceTable {
281 true 306 true
282 } 307 }
283 308
284 (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) 309 (
285 | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) 310 Ty::InferenceVar(tv1, TyVariableKind::General),
286 | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) 311 Ty::InferenceVar(tv2, TyVariableKind::General),
312 )
287 | ( 313 | (
288 Ty::Infer(InferTy::MaybeNeverTypeVar(tv1)), 314 Ty::InferenceVar(tv1, TyVariableKind::Integer),
289 Ty::Infer(InferTy::MaybeNeverTypeVar(tv2)), 315 Ty::InferenceVar(tv2, TyVariableKind::Integer),
290 ) => { 316 )
317 | (
318 Ty::InferenceVar(tv1, TyVariableKind::Float),
319 Ty::InferenceVar(tv2, TyVariableKind::Float),
320 ) if self.type_variable_table.is_diverging(*tv1)
321 == self.type_variable_table.is_diverging(*tv2) =>
322 {
291 // both type vars are unknown since we tried to resolve them 323 // both type vars are unknown since we tried to resolve them
292 self.var_unification_table.union(*tv1, *tv2); 324 self.var_unification_table.union(tv1.to_inner(), tv2.to_inner());
293 true 325 true
294 } 326 }
295 327
296 // The order of MaybeNeverTypeVar matters here. 328 // The order of MaybeNeverTypeVar matters here.
297 // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. 329 // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar.
298 // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. 330 // Unifying MaybeNeverTypeVar and other concrete type will let the former become it.
299 (Ty::Infer(InferTy::TypeVar(tv)), other) 331 (Ty::InferenceVar(tv, TyVariableKind::General), other)
300 | (other, Ty::Infer(InferTy::TypeVar(tv))) 332 | (other, Ty::InferenceVar(tv, TyVariableKind::General))
301 | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other) 333 | (Ty::InferenceVar(tv, TyVariableKind::Integer), other @ Ty::Scalar(Scalar::Int(_)))
302 | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv))) 334 | (other @ Ty::Scalar(Scalar::Int(_)), Ty::InferenceVar(tv, TyVariableKind::Integer))
303 | (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Int(_))) 335 | (
304 | (other @ ty_app!(TypeCtor::Int(_)), Ty::Infer(InferTy::IntVar(tv))) 336 Ty::InferenceVar(tv, TyVariableKind::Integer),
305 | (Ty::Infer(InferTy::FloatVar(tv)), other @ ty_app!(TypeCtor::Float(_))) 337 other @ Ty::Scalar(Scalar::Uint(_)),
306 | (other @ ty_app!(TypeCtor::Float(_)), Ty::Infer(InferTy::FloatVar(tv))) => { 338 )
339 | (
340 other @ Ty::Scalar(Scalar::Uint(_)),
341 Ty::InferenceVar(tv, TyVariableKind::Integer),
342 )
343 | (Ty::InferenceVar(tv, TyVariableKind::Float), other @ Ty::Scalar(Scalar::Float(_)))
344 | (other @ Ty::Scalar(Scalar::Float(_)), Ty::InferenceVar(tv, TyVariableKind::Float)) =>
345 {
307 // the type var is unknown since we tried to resolve it 346 // the type var is unknown since we tried to resolve it
308 self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); 347 self.var_unification_table
348 .union_value(tv.to_inner(), TypeVarValue::Known(other.clone()));
309 true 349 true
310 } 350 }
311 351
@@ -350,7 +390,7 @@ impl InferenceTable {
350 mark::hit!(type_var_resolves_to_int_var); 390 mark::hit!(type_var_resolves_to_int_var);
351 } 391 }
352 match &*ty { 392 match &*ty {
353 Ty::Infer(tv) => { 393 Ty::InferenceVar(tv, _) => {
354 let inner = tv.to_inner(); 394 let inner = tv.to_inner();
355 match self.var_unification_table.inlined_probe_value(inner).known() { 395 match self.var_unification_table.inlined_probe_value(inner).known() {
356 Some(known_ty) => { 396 Some(known_ty) => {
@@ -373,12 +413,12 @@ impl InferenceTable {
373 /// known type. 413 /// known type.
374 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 414 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
375 ty.fold(&mut |ty| match ty { 415 ty.fold(&mut |ty| match ty {
376 Ty::Infer(tv) => { 416 Ty::InferenceVar(tv, kind) => {
377 let inner = tv.to_inner(); 417 let inner = tv.to_inner();
378 if tv_stack.contains(&inner) { 418 if tv_stack.contains(&inner) {
379 mark::hit!(type_var_cycles_resolve_as_possible); 419 mark::hit!(type_var_cycles_resolve_as_possible);
380 // recursive type 420 // recursive type
381 return tv.fallback_value(); 421 return self.type_variable_table.fallback_value(tv, kind);
382 } 422 }
383 if let Some(known_ty) = 423 if let Some(known_ty) =
384 self.var_unification_table.inlined_probe_value(inner).known() 424 self.var_unification_table.inlined_probe_value(inner).known()
@@ -400,12 +440,12 @@ impl InferenceTable {
400 /// replaced by Ty::Unknown. 440 /// replaced by Ty::Unknown.
401 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 441 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
402 ty.fold(&mut |ty| match ty { 442 ty.fold(&mut |ty| match ty {
403 Ty::Infer(tv) => { 443 Ty::InferenceVar(tv, kind) => {
404 let inner = tv.to_inner(); 444 let inner = tv.to_inner();
405 if tv_stack.contains(&inner) { 445 if tv_stack.contains(&inner) {
406 mark::hit!(type_var_cycles_resolve_completely); 446 mark::hit!(type_var_cycles_resolve_completely);
407 // recursive type 447 // recursive type
408 return tv.fallback_value(); 448 return self.type_variable_table.fallback_value(tv, kind);
409 } 449 }
410 if let Some(known_ty) = 450 if let Some(known_ty) =
411 self.var_unification_table.inlined_probe_value(inner).known() 451 self.var_unification_table.inlined_probe_value(inner).known()
@@ -416,7 +456,7 @@ impl InferenceTable {
416 tv_stack.pop(); 456 tv_stack.pop();
417 result 457 result
418 } else { 458 } else {
419 tv.fallback_value() 459 self.type_variable_table.fallback_value(tv, kind)
420 } 460 }
421 } 461 }
422 _ => ty, 462 _ => ty,
@@ -426,7 +466,7 @@ impl InferenceTable {
426 466
427/// The ID of a type variable. 467/// The ID of a type variable.
428#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] 468#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
429pub struct TypeVarId(pub(super) u32); 469pub(super) struct TypeVarId(pub(super) u32);
430 470
431impl UnifyKey for TypeVarId { 471impl UnifyKey for TypeVarId {
432 type Value = TypeVarValue; 472 type Value = TypeVarValue;
@@ -447,7 +487,7 @@ impl UnifyKey for TypeVarId {
447/// The value of a type variable: either we already know the type, or we don't 487/// The value of a type variable: either we already know the type, or we don't
448/// know it yet. 488/// know it yet.
449#[derive(Clone, PartialEq, Eq, Debug)] 489#[derive(Clone, PartialEq, Eq, Debug)]
450pub enum TypeVarValue { 490pub(super) enum TypeVarValue {
451 Known(Ty), 491 Known(Ty),
452 Unknown, 492 Unknown,
453} 493}