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.rs29
-rw-r--r--crates/hir_ty/src/infer/expr.rs91
-rw-r--r--crates/hir_ty/src/infer/pat.rs59
-rw-r--r--crates/hir_ty/src/infer/path.rs18
-rw-r--r--crates/hir_ty/src/infer/unify.rs218
5 files changed, 242 insertions, 173 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 028a4d568..1f463a425 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -7,7 +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::{autoderef, traits::Solution, Interner, Ty, TyBuilder, TyKind}; 10use crate::{autoderef, Canonical, Interner, Solution, Ty, TyBuilder, TyExt, TyKind};
11 11
12use super::{InEnvironment, InferenceContext}; 12use super::{InEnvironment, InferenceContext};
13 13
@@ -71,17 +71,19 @@ impl<'a> InferenceContext<'a> {
71 } 71 }
72 72
73 // Pointer weakening and function to pointer 73 // Pointer weakening and function to pointer
74 match (from_ty.interned_mut(), to_ty.kind(&Interner)) { 74 match (from_ty.kind(&Interner), to_ty.kind(&Interner)) {
75 // `*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 }
76 // `&mut T` -> `&T` 79 // `&mut T` -> `&T`
77 (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) 80 (TyKind::Ref(_, lt, inner), TyKind::Ref(m2 @ Mutability::Not, ..)) => {
78 | (TyKind::Ref(m1, ..), TyKind::Ref(m2 @ Mutability::Not, ..)) => { 81 from_ty = TyKind::Ref(*m2, lt.clone(), inner.clone()).intern(&Interner);
79 *m1 = *m2;
80 } 82 }
81 // `&T` -> `*const T` 83 // `&T` -> `*const T`
82 // `&mut T` -> `*mut T`/`*const T` 84 // `&mut T` -> `*mut T`/`*const T`
83 (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..)) 85 (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..))
84 | (TyKind::Ref(Mutability::Mut, substs), &TyKind::Raw(m2, ..)) => { 86 | (TyKind::Ref(Mutability::Mut, _, substs), &TyKind::Raw(m2, ..)) => {
85 from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner); 87 from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner);
86 } 88 }
87 89
@@ -111,7 +113,9 @@ impl<'a> InferenceContext<'a> {
111 // Auto Deref if cannot coerce 113 // Auto Deref if cannot coerce
112 match (from_ty.kind(&Interner), to_ty.kind(&Interner)) { 114 match (from_ty.kind(&Interner), to_ty.kind(&Interner)) {
113 // FIXME: DerefMut 115 // FIXME: DerefMut
114 (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 }
115 119
116 // Otherwise, normal unify 120 // Otherwise, normal unify
117 _ => self.unify(&from_ty, to_ty), 121 _ => self.unify(&from_ty, to_ty),
@@ -137,7 +141,7 @@ impl<'a> InferenceContext<'a> {
137 b.push(from_ty.clone()).push(to_ty.clone()).build() 141 b.push(from_ty.clone()).push(to_ty.clone()).build()
138 }; 142 };
139 143
140 let goal = InEnvironment::new(self.trait_env.env.clone(), trait_ref.cast(&Interner)); 144 let goal = InEnvironment::new(&self.trait_env.env, trait_ref.cast(&Interner));
141 145
142 let canonicalizer = self.canonicalizer(); 146 let canonicalizer = self.canonicalizer();
143 let canonicalized = canonicalizer.canonicalize_obligation(goal); 147 let canonicalized = canonicalizer.canonicalize_obligation(goal);
@@ -146,7 +150,14 @@ impl<'a> InferenceContext<'a> {
146 150
147 match solution { 151 match solution {
148 Solution::Unique(v) => { 152 Solution::Unique(v) => {
149 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 );
150 } 161 }
151 _ => return None, 162 _ => return None,
152 }; 163 };
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index c584a2c08..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_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, FnPointer, FnSig, Interner, Rawness, Scalar, Substitution, 26 AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner,
26 TraitRef, Ty, TyBuilder, TyKind, 27 ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind,
27}; 28};
28 29
29use super::{ 30use super::{
@@ -180,7 +181,8 @@ impl<'a> InferenceContext<'a> {
180 let inner_ty = self.infer_expr(*body, &Expectation::none()); 181 let inner_ty = self.infer_expr(*body, &Expectation::none());
181 let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body); 182 let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body);
182 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();
183 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)
184 } 186 }
185 Expr::Loop { body, label } => { 187 Expr::Loop { body, label } => {
186 self.breakables.push(BreakableContext { 188 self.breakables.push(BreakableContext {
@@ -259,14 +261,17 @@ impl<'a> InferenceContext<'a> {
259 }; 261 };
260 sig_tys.push(ret_ty.clone()); 262 sig_tys.push(ret_ty.clone());
261 let sig_ty = TyKind::Function(FnPointer { 263 let sig_ty = TyKind::Function(FnPointer {
262 num_args: sig_tys.len() - 1, 264 num_binders: 0,
263 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, 265 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
264 substs: Substitution::from_iter(&Interner, sig_tys.clone()), 266 substitution: FnSubst(
267 Substitution::from_iter(&Interner, sig_tys.clone()).shifted_in(&Interner),
268 ),
265 }) 269 })
266 .intern(&Interner); 270 .intern(&Interner);
267 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();
268 let closure_ty = 272 let closure_ty =
269 TyKind::Closure(closure_id, Substitution::single(sig_ty)).intern(&Interner); 273 TyKind::Closure(closure_id, Substitution::from1(&Interner, sig_ty))
274 .intern(&Interner);
270 275
271 // Eagerly try to relate the closure type with the expected 276 // Eagerly try to relate the closure type with the expected
272 // type, otherwise we often won't have enough information to 277 // type, otherwise we often won't have enough information to
@@ -313,7 +318,13 @@ impl<'a> InferenceContext<'a> {
313 self.normalize_associated_types_in(ret_ty) 318 self.normalize_associated_types_in(ret_ty)
314 } 319 }
315 Expr::MethodCall { receiver, args, method_name, generic_args } => self 320 Expr::MethodCall { receiver, args, method_name, generic_args } => self
316 .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 ),
317 Expr::Match { expr, arms } => { 328 Expr::Match { expr, arms } => {
318 let input_ty = self.infer_expr(*expr, &Expectation::none()); 329 let input_ty = self.infer_expr(*expr, &Expectation::none());
319 330
@@ -394,16 +405,19 @@ impl<'a> InferenceContext<'a> {
394 TyKind::Never.intern(&Interner) 405 TyKind::Never.intern(&Interner)
395 } 406 }
396 Expr::RecordLit { path, fields, spread } => { 407 Expr::RecordLit { path, fields, spread } => {
397 let (ty, def_id) = self.resolve_variant(path.as_ref()); 408 let (ty, def_id) = self.resolve_variant(path.as_deref());
398 if let Some(variant) = def_id { 409 if let Some(variant) = def_id {
399 self.write_variant_resolution(tgt_expr.into(), variant); 410 self.write_variant_resolution(tgt_expr.into(), variant);
400 } 411 }
401 412
402 self.unify(&ty, &expected.ty); 413 self.unify(&ty, &expected.ty);
403 414
404 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner)); 415 let substs = ty
416 .as_adt()
417 .map(|(_, s)| s.clone())
418 .unwrap_or_else(|| Substitution::empty(&Interner));
405 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();
406 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()));
407 for field in fields.iter() { 421 for field in fields.iter() {
408 let field_def = 422 let field_def =
409 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) {
@@ -415,11 +429,8 @@ impl<'a> InferenceContext<'a> {
415 None 429 None
416 } 430 }
417 }); 431 });
418 if let Some(field_def) = field_def {
419 self.result.record_field_resolutions.insert(field.expr, field_def);
420 }
421 let field_ty = field_def.map_or(self.err_ty(), |it| { 432 let field_ty = field_def.map_or(self.err_ty(), |it| {
422 field_types[it.local_id].clone().subst(&substs) 433 field_types[it.local_id].clone().substitute(&Interner, &substs)
423 }); 434 });
424 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); 435 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
425 } 436 }
@@ -453,7 +464,7 @@ impl<'a> InferenceContext<'a> {
453 match canonicalized.decanonicalize_ty(derefed_ty.value).kind(&Interner) { 464 match canonicalized.decanonicalize_ty(derefed_ty.value).kind(&Interner) {
454 TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| { 465 TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| {
455 substs 466 substs
456 .interned(&Interner) 467 .as_slice(&Interner)
457 .get(idx) 468 .get(idx)
458 .map(|a| a.assert_ty_ref(&Interner)) 469 .map(|a| a.assert_ty_ref(&Interner))
459 .cloned() 470 .cloned()
@@ -466,7 +477,7 @@ impl<'a> InferenceContext<'a> {
466 Some( 477 Some(
467 self.db.field_types((*s).into())[field.local_id] 478 self.db.field_types((*s).into())[field.local_id]
468 .clone() 479 .clone()
469 .subst(&parameters), 480 .substitute(&Interner, &parameters),
470 ) 481 )
471 } else { 482 } else {
472 None 483 None
@@ -480,7 +491,7 @@ impl<'a> InferenceContext<'a> {
480 Some( 491 Some(
481 self.db.field_types((*u).into())[field.local_id] 492 self.db.field_types((*u).into())[field.local_id]
482 .clone() 493 .clone()
483 .subst(&parameters), 494 .substitute(&Interner, &parameters),
484 ) 495 )
485 } else { 496 } else {
486 None 497 None
@@ -527,7 +538,7 @@ impl<'a> InferenceContext<'a> {
527 let inner_ty = self.infer_expr_inner(*expr, &expectation); 538 let inner_ty = self.infer_expr_inner(*expr, &expectation);
528 match rawness { 539 match rawness {
529 Rawness::RawPtr => TyKind::Raw(mutability, inner_ty), 540 Rawness::RawPtr => TyKind::Raw(mutability, inner_ty),
530 Rawness::Ref => TyKind::Ref(mutability, inner_ty), 541 Rawness::Ref => TyKind::Ref(mutability, static_lifetime(), inner_ty),
531 } 542 }
532 .intern(&Interner) 543 .intern(&Interner)
533 } 544 }
@@ -702,7 +713,7 @@ impl<'a> InferenceContext<'a> {
702 } 713 }
703 Expr::Array(array) => { 714 Expr::Array(array) => {
704 let elem_ty = match expected.ty.kind(&Interner) { 715 let elem_ty = match expected.ty.kind(&Interner) {
705 TyKind::Array(st) | TyKind::Slice(st) => st.clone(), 716 TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(),
706 _ => self.table.new_type_var(), 717 _ => self.table.new_type_var(),
707 }; 718 };
708 719
@@ -726,17 +737,19 @@ impl<'a> InferenceContext<'a> {
726 } 737 }
727 } 738 }
728 739
729 TyKind::Array(elem_ty).intern(&Interner) 740 TyKind::Array(elem_ty, dummy_usize_const()).intern(&Interner)
730 } 741 }
731 Expr::Literal(lit) => match lit { 742 Expr::Literal(lit) => match lit {
732 Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), 743 Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
733 Literal::String(..) => { 744 Literal::String(..) => {
734 TyKind::Ref(Mutability::Not, TyKind::Str.intern(&Interner)).intern(&Interner) 745 TyKind::Ref(Mutability::Not, static_lifetime(), TyKind::Str.intern(&Interner))
746 .intern(&Interner)
735 } 747 }
736 Literal::ByteString(..) => { 748 Literal::ByteString(..) => {
737 let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); 749 let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner);
738 let array_type = TyKind::Array(byte_type).intern(&Interner); 750 let array_type =
739 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)
740 } 753 }
741 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner), 754 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner),
742 Literal::Int(_v, ty) => match ty { 755 Literal::Int(_v, ty) => match ty {
@@ -853,10 +866,10 @@ impl<'a> InferenceContext<'a> {
853 self.write_method_resolution(tgt_expr, func); 866 self.write_method_resolution(tgt_expr, func);
854 (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())))
855 } 868 }
856 None => (receiver_ty, Binders::new(0, self.err_ty()), None), 869 None => (receiver_ty, Binders::empty(&Interner, self.err_ty()), None),
857 }; 870 };
858 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);
859 let method_ty = method_ty.subst(&substs); 872 let method_ty = method_ty.substitute(&Interner, &substs);
860 let method_ty = self.insert_type_vars(method_ty); 873 let method_ty = self.insert_type_vars(method_ty);
861 self.register_obligations_for_call(&method_ty); 874 self.register_obligations_for_call(&method_ty);
862 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) {
@@ -872,7 +885,9 @@ impl<'a> InferenceContext<'a> {
872 // Apply autoref so the below unification works correctly 885 // Apply autoref so the below unification works correctly
873 // FIXME: return correct autorefs from lookup_method 886 // FIXME: return correct autorefs from lookup_method
874 let actual_receiver_ty = match expected_receiver_ty.as_reference() { 887 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
875 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 }
876 _ => derefed_receiver_ty, 891 _ => derefed_receiver_ty,
877 }; 892 };
878 self.unify(&expected_receiver_ty, &actual_receiver_ty); 893 self.unify(&expected_receiver_ty, &actual_receiver_ty);
@@ -953,9 +968,11 @@ impl<'a> InferenceContext<'a> {
953 let def: CallableDefId = from_chalk(self.db, *fn_def); 968 let def: CallableDefId = from_chalk(self.db, *fn_def);
954 let generic_predicates = self.db.generic_predicates(def.into()); 969 let generic_predicates = self.db.generic_predicates(def.into());
955 for predicate in generic_predicates.iter() { 970 for predicate in generic_predicates.iter() {
956 let (predicate, binders) = 971 let (predicate, binders) = predicate
957 predicate.clone().subst(parameters).into_value_and_skipped_binders(); 972 .clone()
958 always!(binders == 0); // quantified where clauses not yet handled 973 .substitute(&Interner, parameters)
974 .into_value_and_skipped_binders();
975 always!(binders.len(&Interner) == 0); // quantified where clauses not yet handled
959 self.push_obligation(predicate.cast(&Interner)); 976 self.push_obligation(predicate.cast(&Interner));
960 } 977 }
961 // add obligation for trait implementation, if this is a trait method 978 // add obligation for trait implementation, if this is a trait method
@@ -964,8 +981,10 @@ impl<'a> InferenceContext<'a> {
964 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container 981 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container
965 { 982 {
966 // construct a TraitRef 983 // construct a TraitRef
967 let substs = 984 let substs = crate::subst_prefix(
968 parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); 985 &*parameters,
986 generics(self.db.upcast(), trait_.into()).len(),
987 );
969 self.push_obligation( 988 self.push_obligation(
970 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs } 989 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }
971 .cast(&Interner), 990 .cast(&Interner),
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 5b70d5e5a..aea354cde 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -7,14 +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, utils::variant_data, Interner, Substitution, Ty, TyBuilder, 15 lower::lower_to_chalk_mutability, static_lifetime, Interner, Substitution, Ty, TyBuilder,
17 TyKind, 16 TyExt, TyKind,
18}; 17};
19 18
20impl<'a> InferenceContext<'a> { 19impl<'a> InferenceContext<'a> {
@@ -28,13 +27,14 @@ impl<'a> InferenceContext<'a> {
28 ellipsis: Option<usize>, 27 ellipsis: Option<usize>,
29 ) -> Ty { 28 ) -> Ty {
30 let (ty, def) = self.resolve_variant(path); 29 let (ty, def) = self.resolve_variant(path);
31 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()));
32 if let Some(variant) = def { 31 if let Some(variant) = def {
33 self.write_variant_resolution(id.into(), variant); 32 self.write_variant_resolution(id.into(), variant);
34 } 33 }
35 self.unify(&ty, expected); 34 self.unify(&ty, expected);
36 35
37 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner)); 36 let substs =
37 ty.as_adt().map(|(_, s)| s.clone()).unwrap_or_else(|| Substitution::empty(&Interner));
38 38
39 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();
40 let (pre, post) = match ellipsis { 40 let (pre, post) = match ellipsis {
@@ -49,7 +49,9 @@ impl<'a> InferenceContext<'a> {
49 let expected_ty = var_data 49 let expected_ty = var_data
50 .as_ref() 50 .as_ref()
51 .and_then(|d| d.field(&Name::new_tuple_field(i))) 51 .and_then(|d| d.field(&Name::new_tuple_field(i)))
52 .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 });
53 let expected_ty = self.normalize_associated_types_in(expected_ty); 55 let expected_ty = self.normalize_associated_types_in(expected_ty);
54 self.infer_pat(subpat, &expected_ty, default_bm); 56 self.infer_pat(subpat, &expected_ty, default_bm);
55 } 57 }
@@ -66,25 +68,22 @@ impl<'a> InferenceContext<'a> {
66 id: PatId, 68 id: PatId,
67 ) -> Ty { 69 ) -> Ty {
68 let (ty, def) = self.resolve_variant(path); 70 let (ty, def) = self.resolve_variant(path);
69 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()));
70 if let Some(variant) = def { 72 if let Some(variant) = def {
71 self.write_variant_resolution(id.into(), variant); 73 self.write_variant_resolution(id.into(), variant);
72 } 74 }
73 75
74 self.unify(&ty, expected); 76 self.unify(&ty, expected);
75 77
76 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner)); 78 let substs =
79 ty.as_adt().map(|(_, s)| s.clone()).unwrap_or_else(|| Substitution::empty(&Interner));
77 80
78 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();
79 for subpat in subpats { 82 for subpat in subpats {
80 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));
81 if let Some(local_id) = matching_field { 84 let expected_ty = matching_field.map_or(self.err_ty(), |field| {
82 let field_def = FieldId { parent: def.unwrap(), local_id }; 85 field_tys[field].clone().substitute(&Interner, &substs)
83 self.result.record_pat_field_resolutions.insert(subpat.pat, field_def); 86 });
84 }
85
86 let expected_ty = matching_field
87 .map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs));
88 let expected_ty = self.normalize_associated_types_in(expected_ty); 87 let expected_ty = self.normalize_associated_types_in(expected_ty);
89 self.infer_pat(subpat.pat, &expected_ty, default_bm); 88 self.infer_pat(subpat.pat, &expected_ty, default_bm);
90 } 89 }
@@ -101,7 +100,7 @@ impl<'a> InferenceContext<'a> {
101 let body = Arc::clone(&self.body); // avoid borrow checker problem 100 let body = Arc::clone(&self.body); // avoid borrow checker problem
102 101
103 if is_non_ref_pat(&body, pat) { 102 if is_non_ref_pat(&body, pat) {
104 while let Some((inner, mutability)) = expected.as_reference() { 103 while let Some((inner, _lifetime, mutability)) = expected.as_reference() {
105 expected = inner; 104 expected = inner;
106 default_bm = match default_bm { 105 default_bm = match default_bm {
107 BindingMode::Move => BindingMode::Ref(mutability), 106 BindingMode::Move => BindingMode::Ref(mutability),
@@ -123,7 +122,7 @@ impl<'a> InferenceContext<'a> {
123 let ty = match &body[pat] { 122 let ty = match &body[pat] {
124 &Pat::Tuple { ref args, ellipsis } => { 123 &Pat::Tuple { ref args, ellipsis } => {
125 let expectations = match expected.as_tuple() { 124 let expectations = match expected.as_tuple() {
126 Some(parameters) => &*parameters.0, 125 Some(parameters) => &*parameters.as_slice(&Interner),
127 _ => &[], 126 _ => &[],
128 }; 127 };
129 128
@@ -159,7 +158,7 @@ impl<'a> InferenceContext<'a> {
159 Pat::Ref { pat, mutability } => { 158 Pat::Ref { pat, mutability } => {
160 let mutability = lower_to_chalk_mutability(*mutability); 159 let mutability = lower_to_chalk_mutability(*mutability);
161 let expectation = match expected.as_reference() { 160 let expectation = match expected.as_reference() {
162 Some((inner_ty, exp_mut)) => { 161 Some((inner_ty, _lifetime, exp_mut)) => {
163 if mutability != exp_mut { 162 if mutability != exp_mut {
164 // FIXME: emit type error? 163 // FIXME: emit type error?
165 } 164 }
@@ -168,10 +167,10 @@ impl<'a> InferenceContext<'a> {
168 _ => self.result.standard_types.unknown.clone(), 167 _ => self.result.standard_types.unknown.clone(),
169 }; 168 };
170 let subty = self.infer_pat(*pat, &expectation, default_bm); 169 let subty = self.infer_pat(*pat, &expectation, default_bm);
171 TyKind::Ref(mutability, subty).intern(&Interner) 170 TyKind::Ref(mutability, static_lifetime(), subty).intern(&Interner)
172 } 171 }
173 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(
174 p.as_ref(), 173 p.as_deref(),
175 subpats, 174 subpats,
176 expected, 175 expected,
177 default_bm, 176 default_bm,
@@ -179,7 +178,7 @@ impl<'a> InferenceContext<'a> {
179 *ellipsis, 178 *ellipsis,
180 ), 179 ),
181 Pat::Record { path: p, args: fields, ellipsis: _ } => { 180 Pat::Record { path: p, args: fields, ellipsis: _ } => {
182 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)
183 } 182 }
184 Pat::Path(path) => { 183 Pat::Path(path) => {
185 // FIXME use correct resolver for the surrounding expression 184 // FIXME use correct resolver for the surrounding expression
@@ -201,7 +200,8 @@ impl<'a> InferenceContext<'a> {
201 200
202 let bound_ty = match mode { 201 let bound_ty = match mode {
203 BindingMode::Ref(mutability) => { 202 BindingMode::Ref(mutability) => {
204 TyKind::Ref(mutability, inner_ty.clone()).intern(&Interner) 203 TyKind::Ref(mutability, static_lifetime(), inner_ty.clone())
204 .intern(&Interner)
205 } 205 }
206 BindingMode::Move => inner_ty.clone(), 206 BindingMode::Move => inner_ty.clone(),
207 }; 207 };
@@ -210,17 +210,20 @@ impl<'a> InferenceContext<'a> {
210 return inner_ty; 210 return inner_ty;
211 } 211 }
212 Pat::Slice { prefix, slice, suffix } => { 212 Pat::Slice { prefix, slice, suffix } => {
213 let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.kind(&Interner) { 213 let elem_ty = match expected.kind(&Interner) {
214 TyKind::Array(st) => (TyKind::Array, st.clone()), 214 TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(),
215 TyKind::Slice(st) => (TyKind::Slice, st.clone()), 215 _ => self.err_ty(),
216 _ => (TyKind::Slice, self.err_ty()),
217 }; 216 };
218 217
219 for pat_id in prefix.iter().chain(suffix) { 218 for pat_id in prefix.iter().chain(suffix) {
220 self.infer_pat(*pat_id, &elem_ty, default_bm); 219 self.infer_pat(*pat_id, &elem_ty, default_bm);
221 } 220 }
222 221
223 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);
224 if let Some(slice_pat_id) = slice { 227 if let Some(slice_pat_id) = slice {
225 self.infer_pat(*slice_pat_id, &pat_ty, default_bm); 228 self.infer_pat(*slice_pat_id, &pat_ty, default_bm);
226 } 229 }
@@ -239,7 +242,7 @@ impl<'a> InferenceContext<'a> {
239 let (inner_ty, alloc_ty) = match expected.as_adt() { 242 let (inner_ty, alloc_ty) = match expected.as_adt() {
240 Some((adt, subst)) if adt == box_adt => ( 243 Some((adt, subst)) if adt == box_adt => (
241 subst.at(&Interner, 0).assert_ty_ref(&Interner).clone(), 244 subst.at(&Interner, 0).assert_ty_ref(&Interner).clone(),
242 subst.interned(&Interner).get(1).and_then(|a| a.ty(&Interner).cloned()), 245 subst.as_slice(&Interner).get(1).and_then(|a| a.ty(&Interner).cloned()),
243 ), 246 ),
244 _ => (self.result.standard_types.unknown.clone(), None), 247 _ => (self.result.standard_types.unknown.clone(), None),
245 }; 248 };
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs
index 671ea355f..495282eba 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -10,7 +10,10 @@ use hir_def::{
10}; 10};
11use hir_expand::name::Name; 11use hir_expand::name::Name;
12 12
13use crate::{method_resolution, Interner, Substitution, Ty, TyBuilder, TyKind, ValueTyDefId}; 13use crate::{
14 method_resolution, Interner, Substitution, TraitRefExt, Ty, TyBuilder, TyExt, TyKind,
15 ValueTyDefId,
16};
14 17
15use super::{ExprOrPatId, InferenceContext, TraitRef}; 18use super::{ExprOrPatId, InferenceContext, TraitRef};
16 19
@@ -81,9 +84,9 @@ impl<'a> InferenceContext<'a> {
81 ValueNs::ImplSelf(impl_id) => { 84 ValueNs::ImplSelf(impl_id) => {
82 let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); 85 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
83 let substs = generics.type_params_subst(self.db); 86 let substs = generics.type_params_subst(self.db);
84 let ty = self.db.impl_self_ty(impl_id).subst(&substs); 87 let ty = self.db.impl_self_ty(impl_id).substitute(&Interner, &substs);
85 if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() { 88 if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() {
86 let ty = self.db.value_ty(struct_id.into()).subst(&substs); 89 let ty = self.db.value_ty(struct_id.into()).substitute(&Interner, &substs);
87 return Some(ty); 90 return Some(ty);
88 } else { 91 } else {
89 // FIXME: diagnostic, invalid Self reference 92 // FIXME: diagnostic, invalid Self reference
@@ -98,7 +101,7 @@ impl<'a> InferenceContext<'a> {
98 let substs = ctx.substs_from_path(path, typable, true); 101 let substs = ctx.substs_from_path(path, typable, true);
99 let ty = TyBuilder::value_ty(self.db, typable) 102 let ty = TyBuilder::value_ty(self.db, typable)
100 .use_parent_substs(&parent_substs) 103 .use_parent_substs(&parent_substs)
101 .fill(substs.interned(&Interner)[parent_substs.len(&Interner)..].iter().cloned()) 104 .fill(substs.as_slice(&Interner)[parent_substs.len(&Interner)..].iter().cloned())
102 .build(); 105 .build();
103 Some(ty) 106 Some(ty)
104 } 107 }
@@ -142,7 +145,7 @@ impl<'a> InferenceContext<'a> {
142 remaining_segments_for_ty, 145 remaining_segments_for_ty,
143 true, 146 true,
144 ); 147 );
145 if let TyKind::Unknown = ty.kind(&Interner) { 148 if let TyKind::Error = ty.kind(&Interner) {
146 return None; 149 return None;
147 } 150 }
148 151
@@ -207,7 +210,7 @@ impl<'a> InferenceContext<'a> {
207 name: &Name, 210 name: &Name,
208 id: ExprOrPatId, 211 id: ExprOrPatId,
209 ) -> Option<(ValueNs, Option<Substitution>)> { 212 ) -> Option<(ValueNs, Option<Substitution>)> {
210 if let TyKind::Unknown = ty.kind(&Interner) { 213 if let TyKind::Error = ty.kind(&Interner) {
211 return None; 214 return None;
212 } 215 }
213 216
@@ -243,7 +246,8 @@ impl<'a> InferenceContext<'a> {
243 let impl_substs = TyBuilder::subst_for_def(self.db, impl_id) 246 let impl_substs = TyBuilder::subst_for_def(self.db, impl_id)
244 .fill(iter::repeat_with(|| self.table.new_type_var())) 247 .fill(iter::repeat_with(|| self.table.new_type_var()))
245 .build(); 248 .build();
246 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);
247 self.unify(&impl_self_ty, &ty); 251 self.unify(&impl_self_ty, &ty);
248 Some(impl_substs) 252 Some(impl_substs)
249 } 253 }
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index a04b935ef..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.kind(&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(
@@ -132,15 +140,17 @@ impl<T> Canonicalized<T> {
132 let new_vars = Substitution::from_iter( 140 let new_vars = Substitution::from_iter(
133 &Interner, 141 &Interner,
134 solution.binders.iter(&Interner).map(|k| match k.kind { 142 solution.binders.iter(&Interner).map(|k| match k.kind {
135 VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(), 143 VariableKind::Ty(TyVariableKind::General) => {
136 VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(), 144 ctx.table.new_type_var().cast(&Interner)
137 VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(), 145 }
138 // HACK: Chalk can sometimes return new lifetime variables. We 146 VariableKind::Ty(TyVariableKind::Integer) => {
139 // want to just skip them, but to not mess up the indices of 147 ctx.table.new_integer_var().cast(&Interner)
140 // other variables, we'll just create a new type variable in 148 }
141 // their place instead. This should not matter (we never see the 149 VariableKind::Ty(TyVariableKind::Float) => {
142 // actual *uses* of the lifetime variable). 150 ctx.table.new_float_var().cast(&Interner)
143 VariableKind::Lifetime => ctx.table.new_type_var(), 151 }
152 // Chalk can sometimes return new lifetime variables. We just use the static lifetime everywhere
153 VariableKind::Lifetime => static_lifetime().cast(&Interner),
144 _ => panic!("const variable in solution"), 154 _ => panic!("const variable in solution"),
145 }), 155 }),
146 ); 156 );
@@ -149,7 +159,7 @@ impl<T> Canonicalized<T> {
149 // eagerly replace projections in the type; we may be getting types 159 // eagerly replace projections in the type; we may be getting types
150 // e.g. from where clauses where this hasn't happened yet 160 // e.g. from where clauses where this hasn't happened yet
151 let ty = ctx.normalize_associated_types_in( 161 let ty = ctx.normalize_associated_types_in(
152 ty.assert_ty_ref(&Interner).clone().subst_bound_vars(&new_vars), 162 new_vars.apply(ty.assert_ty_ref(&Interner).clone(), &Interner),
153 ); 163 );
154 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); 164 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty);
155 } 165 }
@@ -170,8 +180,8 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
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 ); 182 );
173 let ty1_with_vars = tys.value.0.clone().subst_bound_vars(&vars); 183 let ty1_with_vars = vars.apply(tys.value.0.clone(), &Interner);
174 let ty2_with_vars = tys.value.1.clone().subst_bound_vars(&vars); 184 let ty2_with_vars = vars.apply(tys.value.1.clone(), &Interner);
175 if !table.unify(&ty1_with_vars, &ty2_with_vars) { 185 if !table.unify(&ty1_with_vars, &ty2_with_vars) {
176 return None; 186 return None;
177 } 187 }
@@ -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 }
@@ -247,7 +257,7 @@ impl InferenceTable {
247 self.type_variable_table.push(TypeVariableData { diverging }); 257 self.type_variable_table.push(TypeVariableData { diverging });
248 let key = self.var_unification_table.new_key(TypeVarValue::Unknown); 258 let key = self.var_unification_table.new_key(TypeVarValue::Unknown);
249 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);
250 TyKind::InferenceVar(InferenceVar::from_inner(key), kind).intern(&Interner) 260 TyKind::InferenceVar(to_inference_var(key), kind).intern(&Interner)
251 } 261 }
252 262
253 pub(crate) fn new_type_var(&mut self) -> Ty { 263 pub(crate) fn new_type_var(&mut self) -> Ty {
@@ -284,7 +294,7 @@ impl InferenceTable {
284 substs2: &Substitution, 294 substs2: &Substitution,
285 depth: usize, 295 depth: usize,
286 ) -> bool { 296 ) -> bool {
287 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| { 297 substs1.iter(&Interner).zip(substs2.iter(&Interner)).all(|(t1, t2)| {
288 self.unify_inner(t1.assert_ty_ref(&Interner), t2.assert_ty_ref(&Interner), depth) 298 self.unify_inner(t1.assert_ty_ref(&Interner), t2.assert_ty_ref(&Interner), depth)
289 }) 299 })
290 } 300 }
@@ -305,8 +315,8 @@ impl InferenceTable {
305 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) 315 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2))
306 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) 316 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2))
307 | ( 317 | (
308 TyKind::Function(FnPointer { substs: substs1, .. }), 318 TyKind::Function(FnPointer { substitution: FnSubst(substs1), .. }),
309 TyKind::Function(FnPointer { substs: substs2, .. }), 319 TyKind::Function(FnPointer { substitution: FnSubst(substs2), .. }),
310 ) 320 )
311 | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2)) 321 | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2))
312 | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2)) 322 | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2))
@@ -314,9 +324,11 @@ impl InferenceTable {
314 | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => { 324 | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => {
315 self.unify_substs(substs1, substs2, depth + 1) 325 self.unify_substs(substs1, substs2, depth + 1)
316 } 326 }
317 (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))
318 | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2)) 331 | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2))
319 | (TyKind::Array(ty1), TyKind::Array(ty2))
320 | (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),
321 _ => true, /* we checked equals_ctor already */ 333 _ => true, /* we checked equals_ctor already */
322 } 334 }
@@ -327,7 +339,7 @@ impl InferenceTable {
327 339
328 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 {
329 match (ty1.kind(&Interner), ty2.kind(&Interner)) { 341 match (ty1.kind(&Interner), ty2.kind(&Interner)) {
330 (TyKind::Unknown, _) | (_, TyKind::Unknown) => true, 342 (TyKind::Error, _) | (_, TyKind::Error) => true,
331 343
332 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, 344 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true,
333 345
@@ -364,8 +376,12 @@ impl InferenceTable {
364 == self.type_variable_table.is_diverging(*tv2) => 376 == self.type_variable_table.is_diverging(*tv2) =>
365 { 377 {
366 // both type vars are unknown since we tried to resolve them 378 // both type vars are unknown since we tried to resolve them
367 if !self.var_unification_table.unioned(tv1.to_inner(), tv2.to_inner()) { 379 if !self
368 self.var_unification_table.union(tv1.to_inner(), tv2.to_inner()); 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));
369 self.revision += 1; 385 self.revision += 1;
370 } 386 }
371 true 387 true
@@ -402,7 +418,7 @@ impl InferenceTable {
402 ) => { 418 ) => {
403 // the type var is unknown since we tried to resolve it 419 // the type var is unknown since we tried to resolve it
404 self.var_unification_table.union_value( 420 self.var_unification_table.union_value(
405 tv.to_inner(), 421 from_inference_var(*tv),
406 TypeVarValue::Known(other.clone().intern(&Interner)), 422 TypeVarValue::Known(other.clone().intern(&Interner)),
407 ); 423 );
408 self.revision += 1; 424 self.revision += 1;
@@ -457,7 +473,7 @@ impl InferenceTable {
457 } 473 }
458 match ty.kind(&Interner) { 474 match ty.kind(&Interner) {
459 TyKind::InferenceVar(tv, _) => { 475 TyKind::InferenceVar(tv, _) => {
460 let inner = tv.to_inner(); 476 let inner = from_inference_var(*tv);
461 match self.var_unification_table.inlined_probe_value(inner).known() { 477 match self.var_unification_table.inlined_probe_value(inner).known() {
462 Some(known_ty) => { 478 Some(known_ty) => {
463 // The known_ty can't be a type var itself 479 // The known_ty can't be a type var itself
@@ -478,55 +494,63 @@ impl InferenceTable {
478 /// 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
479 /// known type. 495 /// known type.
480 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 {
481 ty.fold(&mut |ty| match ty.kind(&Interner) { 497 fold_tys(
482 &TyKind::InferenceVar(tv, kind) => { 498 ty,
483 let inner = tv.to_inner(); 499 |ty, _| match ty.kind(&Interner) {
484 if tv_stack.contains(&inner) { 500 &TyKind::InferenceVar(tv, kind) => {
485 cov_mark::hit!(type_var_cycles_resolve_as_possible); 501 let inner = from_inference_var(tv);
486 // recursive type 502 if tv_stack.contains(&inner) {
487 return self.type_variable_table.fallback_value(tv, kind); 503 cov_mark::hit!(type_var_cycles_resolve_as_possible);
488 } 504 // recursive type
489 if let Some(known_ty) = 505 return self.type_variable_table.fallback_value(tv, kind);
490 self.var_unification_table.inlined_probe_value(inner).known() 506 }
491 { 507 if let Some(known_ty) =
492 // known_ty may contain other variables that are known by now 508 self.var_unification_table.inlined_probe_value(inner).known()
493 tv_stack.push(inner); 509 {
494 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
495 tv_stack.pop(); 511 tv_stack.push(inner);
496 result 512 let result = self.resolve_ty_as_possible_inner(tv_stack, known_ty.clone());
497 } else { 513 tv_stack.pop();
498 ty 514 result
515 } else {
516 ty
517 }
499 } 518 }
500 } 519 _ => ty,
501 _ => ty, 520 },
502 }) 521 DebruijnIndex::INNERMOST,
522 )
503 } 523 }
504 524
505 /// Resolves the type completely; type variables without known type are 525 /// Resolves the type completely; type variables without known type are
506 /// replaced by TyKind::Unknown. 526 /// replaced by TyKind::Unknown.
507 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 {
508 ty.fold(&mut |ty| match ty.kind(&Interner) { 528 fold_tys(
509 &TyKind::InferenceVar(tv, kind) => { 529 ty,
510 let inner = tv.to_inner(); 530 |ty, _| match ty.kind(&Interner) {
511 if tv_stack.contains(&inner) { 531 &TyKind::InferenceVar(tv, kind) => {
512 cov_mark::hit!(type_var_cycles_resolve_completely); 532 let inner = from_inference_var(tv);
513 // recursive type 533 if tv_stack.contains(&inner) {
514 return self.type_variable_table.fallback_value(tv, kind); 534 cov_mark::hit!(type_var_cycles_resolve_completely);
515 } 535 // recursive type
516 if let Some(known_ty) = 536 return self.type_variable_table.fallback_value(tv, kind);
517 self.var_unification_table.inlined_probe_value(inner).known() 537 }
518 { 538 if let Some(known_ty) =
519 // known_ty may contain other variables that are known by now 539 self.var_unification_table.inlined_probe_value(inner).known()
520 tv_stack.push(inner); 540 {
521 let result = self.resolve_ty_completely_inner(tv_stack, known_ty.clone()); 541 // known_ty may contain other variables that are known by now
522 tv_stack.pop(); 542 tv_stack.push(inner);
523 result 543 let result = self.resolve_ty_completely_inner(tv_stack, known_ty.clone());
524 } else { 544 tv_stack.pop();
525 self.type_variable_table.fallback_value(tv, kind) 545 result
546 } else {
547 self.type_variable_table.fallback_value(tv, kind)
548 }
526 } 549 }
527 } 550 _ => ty,
528 _ => ty, 551 },
529 }) 552 DebruijnIndex::INNERMOST,
553 )
530 } 554 }
531} 555}
532 556
@@ -550,6 +574,14 @@ impl UnifyKey for TypeVarId {
550 } 574 }
551} 575}
552 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
553/// 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
554/// know it yet. 586/// know it yet.
555#[derive(Clone, PartialEq, Eq, Debug)] 587#[derive(Clone, PartialEq, Eq, Debug)]