diff options
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 29 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 77 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 50 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/path.rs | 7 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 207 |
5 files changed, 217 insertions, 153 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 32c273afc..1f463a425 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs | |||
@@ -7,7 +7,7 @@ | |||
7 | use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; | 7 | use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; |
8 | use hir_def::lang_item::LangItemTarget; | 8 | use hir_def::lang_item::LangItemTarget; |
9 | 9 | ||
10 | use crate::{autoderef, Interner, Solution, Ty, TyBuilder, TyKind}; | 10 | use crate::{autoderef, Canonical, Interner, Solution, Ty, TyBuilder, TyExt, TyKind}; |
11 | 11 | ||
12 | use super::{InEnvironment, InferenceContext}; | 12 | use 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 6966d26e7..50497eecb 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | use std::iter::{repeat, repeat_with}; | 3 | use std::iter::{repeat, repeat_with}; |
4 | use std::{mem, sync::Arc}; | 4 | use std::{mem, sync::Arc}; |
5 | 5 | ||
6 | use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; | 6 | use chalk_ir::{cast::Cast, fold::Shift, Mutability, TyVariableKind}; |
7 | use hir_def::{ | 7 | use 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; | |||
15 | use syntax::ast::RangeOp; | 15 | use syntax::ast::RangeOp; |
16 | 16 | ||
17 | use crate::{ | 17 | use 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}, | 24 | traits::FnTrait, |
24 | utils::{generics, variant_data, Generics}, | 25 | utils::{generics, Generics}, |
25 | AdtId, Binders, CallableDefId, FnPointer, FnSig, InEnvironment, Interner, Rawness, Scalar, | 26 | AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner, |
26 | Substitution, TraitRef, Ty, TyBuilder, TyKind, | 27 | ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind, |
27 | }; | 28 | }; |
28 | 29 | ||
29 | use super::{ | 30 | use 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,9 +429,6 @@ 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().substitute(&Interner, &substs) | 433 | field_types[it.local_id].clone().substitute(&Interner, &substs) |
423 | }); | 434 | }); |
@@ -452,7 +463,11 @@ impl<'a> InferenceContext<'a> { | |||
452 | }; | 463 | }; |
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.interned().get(idx).map(|a| a.assert_ty_ref(&Interner)).cloned() | 466 | substs |
467 | .as_slice(&Interner) | ||
468 | .get(idx) | ||
469 | .map(|a| a.assert_ty_ref(&Interner)) | ||
470 | .cloned() | ||
456 | }), | 471 | }), |
457 | TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { | 472 | TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { |
458 | let local_id = self.db.struct_data(*s).variant_data.field(name)?; | 473 | let local_id = self.db.struct_data(*s).variant_data.field(name)?; |
@@ -523,7 +538,7 @@ impl<'a> InferenceContext<'a> { | |||
523 | let inner_ty = self.infer_expr_inner(*expr, &expectation); | 538 | let inner_ty = self.infer_expr_inner(*expr, &expectation); |
524 | match rawness { | 539 | match rawness { |
525 | Rawness::RawPtr => TyKind::Raw(mutability, inner_ty), | 540 | Rawness::RawPtr => TyKind::Raw(mutability, inner_ty), |
526 | Rawness::Ref => TyKind::Ref(mutability, inner_ty), | 541 | Rawness::Ref => TyKind::Ref(mutability, static_lifetime(), inner_ty), |
527 | } | 542 | } |
528 | .intern(&Interner) | 543 | .intern(&Interner) |
529 | } | 544 | } |
@@ -698,7 +713,7 @@ impl<'a> InferenceContext<'a> { | |||
698 | } | 713 | } |
699 | Expr::Array(array) => { | 714 | Expr::Array(array) => { |
700 | let elem_ty = match expected.ty.kind(&Interner) { | 715 | let elem_ty = match expected.ty.kind(&Interner) { |
701 | TyKind::Array(st) | TyKind::Slice(st) => st.clone(), | 716 | TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(), |
702 | _ => self.table.new_type_var(), | 717 | _ => self.table.new_type_var(), |
703 | }; | 718 | }; |
704 | 719 | ||
@@ -722,17 +737,19 @@ impl<'a> InferenceContext<'a> { | |||
722 | } | 737 | } |
723 | } | 738 | } |
724 | 739 | ||
725 | TyKind::Array(elem_ty).intern(&Interner) | 740 | TyKind::Array(elem_ty, dummy_usize_const()).intern(&Interner) |
726 | } | 741 | } |
727 | Expr::Literal(lit) => match lit { | 742 | Expr::Literal(lit) => match lit { |
728 | Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), | 743 | Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), |
729 | Literal::String(..) => { | 744 | Literal::String(..) => { |
730 | TyKind::Ref(Mutability::Not, TyKind::Str.intern(&Interner)).intern(&Interner) | 745 | TyKind::Ref(Mutability::Not, static_lifetime(), TyKind::Str.intern(&Interner)) |
746 | .intern(&Interner) | ||
731 | } | 747 | } |
732 | Literal::ByteString(..) => { | 748 | Literal::ByteString(..) => { |
733 | let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); | 749 | let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); |
734 | let array_type = TyKind::Array(byte_type).intern(&Interner); | 750 | let array_type = |
735 | 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) | ||
736 | } | 753 | } |
737 | Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner), | 754 | Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner), |
738 | Literal::Int(_v, ty) => match ty { | 755 | Literal::Int(_v, ty) => match ty { |
@@ -868,7 +885,9 @@ impl<'a> InferenceContext<'a> { | |||
868 | // Apply autoref so the below unification works correctly | 885 | // Apply autoref so the below unification works correctly |
869 | // FIXME: return correct autorefs from lookup_method | 886 | // FIXME: return correct autorefs from lookup_method |
870 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { | 887 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { |
871 | 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 | } | ||
872 | _ => derefed_receiver_ty, | 891 | _ => derefed_receiver_ty, |
873 | }; | 892 | }; |
874 | self.unify(&expected_receiver_ty, &actual_receiver_ty); | 893 | self.unify(&expected_receiver_ty, &actual_receiver_ty); |
@@ -962,8 +981,10 @@ impl<'a> InferenceContext<'a> { | |||
962 | if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container | 981 | if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container |
963 | { | 982 | { |
964 | // construct a TraitRef | 983 | // construct a TraitRef |
965 | let substs = | 984 | let substs = crate::subst_prefix( |
966 | parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); | 985 | &*parameters, |
986 | generics(self.db.upcast(), trait_.into()).len(), | ||
987 | ); | ||
967 | self.push_obligation( | 988 | self.push_obligation( |
968 | TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs } | 989 | TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs } |
969 | .cast(&Interner), | 990 | .cast(&Interner), |
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index 252ae914a..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; | |||
7 | use hir_def::{ | 7 | use 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 | }; |
12 | use hir_expand::name::Name; | 11 | use hir_expand::name::Name; |
13 | 12 | ||
14 | use super::{BindingMode, Expectation, InferenceContext}; | 13 | use super::{BindingMode, Expectation, InferenceContext}; |
15 | use crate::{ | 14 | use 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 | ||
20 | impl<'a> InferenceContext<'a> { | 19 | impl<'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 { |
@@ -68,23 +68,19 @@ impl<'a> InferenceContext<'a> { | |||
68 | id: PatId, | 68 | id: PatId, |
69 | ) -> Ty { | 69 | ) -> Ty { |
70 | let (ty, def) = self.resolve_variant(path); | 70 | let (ty, def) = self.resolve_variant(path); |
71 | 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())); |
72 | if let Some(variant) = def { | 72 | if let Some(variant) = def { |
73 | self.write_variant_resolution(id.into(), variant); | 73 | self.write_variant_resolution(id.into(), variant); |
74 | } | 74 | } |
75 | 75 | ||
76 | self.unify(&ty, expected); | 76 | self.unify(&ty, expected); |
77 | 77 | ||
78 | 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)); | ||
79 | 80 | ||
80 | 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(); |
81 | for subpat in subpats { | 82 | for subpat in subpats { |
82 | 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)); |
83 | if let Some(local_id) = matching_field { | ||
84 | let field_def = FieldId { parent: def.unwrap(), local_id }; | ||
85 | self.result.record_pat_field_resolutions.insert(subpat.pat, field_def); | ||
86 | } | ||
87 | |||
88 | let expected_ty = matching_field.map_or(self.err_ty(), |field| { | 84 | let expected_ty = matching_field.map_or(self.err_ty(), |field| { |
89 | field_tys[field].clone().substitute(&Interner, &substs) | 85 | field_tys[field].clone().substitute(&Interner, &substs) |
90 | }); | 86 | }); |
@@ -104,7 +100,7 @@ impl<'a> InferenceContext<'a> { | |||
104 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 100 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
105 | 101 | ||
106 | if is_non_ref_pat(&body, pat) { | 102 | if is_non_ref_pat(&body, pat) { |
107 | while let Some((inner, mutability)) = expected.as_reference() { | 103 | while let Some((inner, _lifetime, mutability)) = expected.as_reference() { |
108 | expected = inner; | 104 | expected = inner; |
109 | default_bm = match default_bm { | 105 | default_bm = match default_bm { |
110 | BindingMode::Move => BindingMode::Ref(mutability), | 106 | BindingMode::Move => BindingMode::Ref(mutability), |
@@ -126,7 +122,7 @@ impl<'a> InferenceContext<'a> { | |||
126 | let ty = match &body[pat] { | 122 | let ty = match &body[pat] { |
127 | &Pat::Tuple { ref args, ellipsis } => { | 123 | &Pat::Tuple { ref args, ellipsis } => { |
128 | let expectations = match expected.as_tuple() { | 124 | let expectations = match expected.as_tuple() { |
129 | Some(parameters) => &*parameters.interned(), | 125 | Some(parameters) => &*parameters.as_slice(&Interner), |
130 | _ => &[], | 126 | _ => &[], |
131 | }; | 127 | }; |
132 | 128 | ||
@@ -162,7 +158,7 @@ impl<'a> InferenceContext<'a> { | |||
162 | Pat::Ref { pat, mutability } => { | 158 | Pat::Ref { pat, mutability } => { |
163 | let mutability = lower_to_chalk_mutability(*mutability); | 159 | let mutability = lower_to_chalk_mutability(*mutability); |
164 | let expectation = match expected.as_reference() { | 160 | let expectation = match expected.as_reference() { |
165 | Some((inner_ty, exp_mut)) => { | 161 | Some((inner_ty, _lifetime, exp_mut)) => { |
166 | if mutability != exp_mut { | 162 | if mutability != exp_mut { |
167 | // FIXME: emit type error? | 163 | // FIXME: emit type error? |
168 | } | 164 | } |
@@ -171,10 +167,10 @@ impl<'a> InferenceContext<'a> { | |||
171 | _ => self.result.standard_types.unknown.clone(), | 167 | _ => self.result.standard_types.unknown.clone(), |
172 | }; | 168 | }; |
173 | let subty = self.infer_pat(*pat, &expectation, default_bm); | 169 | let subty = self.infer_pat(*pat, &expectation, default_bm); |
174 | TyKind::Ref(mutability, subty).intern(&Interner) | 170 | TyKind::Ref(mutability, static_lifetime(), subty).intern(&Interner) |
175 | } | 171 | } |
176 | 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( |
177 | p.as_ref(), | 173 | p.as_deref(), |
178 | subpats, | 174 | subpats, |
179 | expected, | 175 | expected, |
180 | default_bm, | 176 | default_bm, |
@@ -182,7 +178,7 @@ impl<'a> InferenceContext<'a> { | |||
182 | *ellipsis, | 178 | *ellipsis, |
183 | ), | 179 | ), |
184 | Pat::Record { path: p, args: fields, ellipsis: _ } => { | 180 | Pat::Record { path: p, args: fields, ellipsis: _ } => { |
185 | 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) |
186 | } | 182 | } |
187 | Pat::Path(path) => { | 183 | Pat::Path(path) => { |
188 | // FIXME use correct resolver for the surrounding expression | 184 | // FIXME use correct resolver for the surrounding expression |
@@ -204,7 +200,8 @@ impl<'a> InferenceContext<'a> { | |||
204 | 200 | ||
205 | let bound_ty = match mode { | 201 | let bound_ty = match mode { |
206 | BindingMode::Ref(mutability) => { | 202 | BindingMode::Ref(mutability) => { |
207 | TyKind::Ref(mutability, inner_ty.clone()).intern(&Interner) | 203 | TyKind::Ref(mutability, static_lifetime(), inner_ty.clone()) |
204 | .intern(&Interner) | ||
208 | } | 205 | } |
209 | BindingMode::Move => inner_ty.clone(), | 206 | BindingMode::Move => inner_ty.clone(), |
210 | }; | 207 | }; |
@@ -213,17 +210,20 @@ impl<'a> InferenceContext<'a> { | |||
213 | return inner_ty; | 210 | return inner_ty; |
214 | } | 211 | } |
215 | Pat::Slice { prefix, slice, suffix } => { | 212 | Pat::Slice { prefix, slice, suffix } => { |
216 | let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.kind(&Interner) { | 213 | let elem_ty = match expected.kind(&Interner) { |
217 | TyKind::Array(st) => (TyKind::Array, st.clone()), | 214 | TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(), |
218 | TyKind::Slice(st) => (TyKind::Slice, st.clone()), | 215 | _ => self.err_ty(), |
219 | _ => (TyKind::Slice, self.err_ty()), | ||
220 | }; | 216 | }; |
221 | 217 | ||
222 | for pat_id in prefix.iter().chain(suffix) { | 218 | for pat_id in prefix.iter().chain(suffix) { |
223 | self.infer_pat(*pat_id, &elem_ty, default_bm); | 219 | self.infer_pat(*pat_id, &elem_ty, default_bm); |
224 | } | 220 | } |
225 | 221 | ||
226 | 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); | ||
227 | if let Some(slice_pat_id) = slice { | 227 | if let Some(slice_pat_id) = slice { |
228 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); | 228 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); |
229 | } | 229 | } |
@@ -242,7 +242,7 @@ impl<'a> InferenceContext<'a> { | |||
242 | let (inner_ty, alloc_ty) = match expected.as_adt() { | 242 | let (inner_ty, alloc_ty) = match expected.as_adt() { |
243 | Some((adt, subst)) if adt == box_adt => ( | 243 | Some((adt, subst)) if adt == box_adt => ( |
244 | subst.at(&Interner, 0).assert_ty_ref(&Interner).clone(), | 244 | subst.at(&Interner, 0).assert_ty_ref(&Interner).clone(), |
245 | subst.interned().get(1).and_then(|a| a.ty(&Interner).cloned()), | 245 | subst.as_slice(&Interner).get(1).and_then(|a| a.ty(&Interner).cloned()), |
246 | ), | 246 | ), |
247 | _ => (self.result.standard_types.unknown.clone(), None), | 247 | _ => (self.result.standard_types.unknown.clone(), None), |
248 | }; | 248 | }; |
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs index 14f705173..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 | }; |
11 | use hir_expand::name::Name; | 11 | use hir_expand::name::Name; |
12 | 12 | ||
13 | use crate::{method_resolution, Interner, Substitution, Ty, TyBuilder, TyKind, ValueTyDefId}; | 13 | use crate::{ |
14 | method_resolution, Interner, Substitution, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, | ||
15 | ValueTyDefId, | ||
16 | }; | ||
14 | 17 | ||
15 | use super::{ExprOrPatId, InferenceContext, TraitRef}; | 18 | use super::{ExprOrPatId, InferenceContext, TraitRef}; |
16 | 19 | ||
@@ -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()[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 | } |
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index c90a16720..a887e20b0 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -2,13 +2,17 @@ | |||
2 | 2 | ||
3 | use std::borrow::Cow; | 3 | use std::borrow::Cow; |
4 | 4 | ||
5 | use chalk_ir::{FloatTy, IntTy, TyVariableKind, UniverseIndex, VariableKind}; | 5 | use chalk_ir::{ |
6 | cast::Cast, fold::Fold, interner::HasInterner, FloatTy, IntTy, TyVariableKind, UniverseIndex, | ||
7 | VariableKind, | ||
8 | }; | ||
6 | use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; | 9 | use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; |
7 | 10 | ||
8 | use super::{DomainGoal, InferenceContext}; | 11 | use super::{DomainGoal, InferenceContext}; |
9 | use crate::{ | 12 | use 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 | ||
14 | impl<'a> InferenceContext<'a> { | 18 | impl<'a> InferenceContext<'a> { |
@@ -33,7 +37,10 @@ where | |||
33 | } | 37 | } |
34 | 38 | ||
35 | #[derive(Debug)] | 39 | #[derive(Debug)] |
36 | pub(super) struct Canonicalized<T> { | 40 | pub(super) struct Canonicalized<T> |
41 | where | ||
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,28 +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 | ||
110 | impl<T> Canonicalized<T> { | 126 | impl<T: HasInterner<Interner = Interner>> Canonicalized<T> { |
111 | pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty { | 127 | pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty { |
112 | ty.fold_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 TyKind::BoundVar(bound) = ty.kind(&Interner) { | 130 | TyKind::InferenceVar(v, k).intern(&Interner) |
115 | if bound.debruijn >= binders { | 131 | }) |
116 | let (v, k) = self.free_vars[bound.index]; | ||
117 | TyKind::InferenceVar(v, k).intern(&Interner) | ||
118 | } else { | ||
119 | ty | ||
120 | } | ||
121 | } else { | ||
122 | ty | ||
123 | } | ||
124 | }, | ||
125 | DebruijnIndex::INNERMOST, | ||
126 | ) | ||
127 | } | 132 | } |
128 | 133 | ||
129 | pub(super) fn apply_solution( | 134 | pub(super) fn apply_solution( |
@@ -135,15 +140,17 @@ impl<T> Canonicalized<T> { | |||
135 | let new_vars = Substitution::from_iter( | 140 | let new_vars = Substitution::from_iter( |
136 | &Interner, | 141 | &Interner, |
137 | solution.binders.iter(&Interner).map(|k| match k.kind { | 142 | solution.binders.iter(&Interner).map(|k| match k.kind { |
138 | VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(), | 143 | VariableKind::Ty(TyVariableKind::General) => { |
139 | VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(), | 144 | ctx.table.new_type_var().cast(&Interner) |
140 | VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(), | 145 | } |
141 | // HACK: Chalk can sometimes return new lifetime variables. We | 146 | VariableKind::Ty(TyVariableKind::Integer) => { |
142 | // want to just skip them, but to not mess up the indices of | 147 | ctx.table.new_integer_var().cast(&Interner) |
143 | // other variables, we'll just create a new type variable in | 148 | } |
144 | // their place instead. This should not matter (we never see the | 149 | VariableKind::Ty(TyVariableKind::Float) => { |
145 | // actual *uses* of the lifetime variable). | 150 | ctx.table.new_float_var().cast(&Interner) |
146 | 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), | ||
147 | _ => panic!("const variable in solution"), | 154 | _ => panic!("const variable in solution"), |
148 | }), | 155 | }), |
149 | ); | 156 | ); |
@@ -207,16 +214,16 @@ impl TypeVariableTable { | |||
207 | } | 214 | } |
208 | 215 | ||
209 | pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) { | 216 | pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) { |
210 | self.inner[iv.to_inner().0 as usize].diverging = diverging; | 217 | self.inner[from_inference_var(iv).0 as usize].diverging = diverging; |
211 | } | 218 | } |
212 | 219 | ||
213 | fn is_diverging(&mut self, iv: InferenceVar) -> bool { | 220 | fn is_diverging(&mut self, iv: InferenceVar) -> bool { |
214 | self.inner[iv.to_inner().0 as usize].diverging | 221 | self.inner[from_inference_var(iv).0 as usize].diverging |
215 | } | 222 | } |
216 | 223 | ||
217 | fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { | 224 | fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { |
218 | match kind { | 225 | match kind { |
219 | _ 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, |
220 | TyVariableKind::General => TyKind::Error, | 227 | TyVariableKind::General => TyKind::Error, |
221 | TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)), | 228 | TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)), |
222 | TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)), | 229 | TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)), |
@@ -250,7 +257,7 @@ impl InferenceTable { | |||
250 | self.type_variable_table.push(TypeVariableData { diverging }); | 257 | self.type_variable_table.push(TypeVariableData { diverging }); |
251 | let key = self.var_unification_table.new_key(TypeVarValue::Unknown); | 258 | let key = self.var_unification_table.new_key(TypeVarValue::Unknown); |
252 | 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); |
253 | TyKind::InferenceVar(InferenceVar::from_inner(key), kind).intern(&Interner) | 260 | TyKind::InferenceVar(to_inference_var(key), kind).intern(&Interner) |
254 | } | 261 | } |
255 | 262 | ||
256 | pub(crate) fn new_type_var(&mut self) -> Ty { | 263 | pub(crate) fn new_type_var(&mut self) -> Ty { |
@@ -308,8 +315,8 @@ impl InferenceTable { | |||
308 | (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) | 315 | (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) |
309 | | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) | 316 | | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) |
310 | | ( | 317 | | ( |
311 | TyKind::Function(FnPointer { substs: substs1, .. }), | 318 | TyKind::Function(FnPointer { substitution: FnSubst(substs1), .. }), |
312 | TyKind::Function(FnPointer { substs: substs2, .. }), | 319 | TyKind::Function(FnPointer { substitution: FnSubst(substs2), .. }), |
313 | ) | 320 | ) |
314 | | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2)) | 321 | | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2)) |
315 | | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2)) | 322 | | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2)) |
@@ -317,9 +324,11 @@ impl InferenceTable { | |||
317 | | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => { | 324 | | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => { |
318 | self.unify_substs(substs1, substs2, depth + 1) | 325 | self.unify_substs(substs1, substs2, depth + 1) |
319 | } | 326 | } |
320 | (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)) | ||
321 | | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2)) | 331 | | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2)) |
322 | | (TyKind::Array(ty1), TyKind::Array(ty2)) | ||
323 | | (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), |
324 | _ => true, /* we checked equals_ctor already */ | 333 | _ => true, /* we checked equals_ctor already */ |
325 | } | 334 | } |
@@ -367,8 +376,12 @@ impl InferenceTable { | |||
367 | == self.type_variable_table.is_diverging(*tv2) => | 376 | == self.type_variable_table.is_diverging(*tv2) => |
368 | { | 377 | { |
369 | // both type vars are unknown since we tried to resolve them | 378 | // both type vars are unknown since we tried to resolve them |
370 | if !self.var_unification_table.unioned(tv1.to_inner(), tv2.to_inner()) { | 379 | if !self |
371 | 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)); | ||
372 | self.revision += 1; | 385 | self.revision += 1; |
373 | } | 386 | } |
374 | true | 387 | true |
@@ -405,7 +418,7 @@ impl InferenceTable { | |||
405 | ) => { | 418 | ) => { |
406 | // the type var is unknown since we tried to resolve it | 419 | // the type var is unknown since we tried to resolve it |
407 | self.var_unification_table.union_value( | 420 | self.var_unification_table.union_value( |
408 | tv.to_inner(), | 421 | from_inference_var(*tv), |
409 | TypeVarValue::Known(other.clone().intern(&Interner)), | 422 | TypeVarValue::Known(other.clone().intern(&Interner)), |
410 | ); | 423 | ); |
411 | self.revision += 1; | 424 | self.revision += 1; |
@@ -460,7 +473,7 @@ impl InferenceTable { | |||
460 | } | 473 | } |
461 | match ty.kind(&Interner) { | 474 | match ty.kind(&Interner) { |
462 | TyKind::InferenceVar(tv, _) => { | 475 | TyKind::InferenceVar(tv, _) => { |
463 | let inner = tv.to_inner(); | 476 | let inner = from_inference_var(*tv); |
464 | match self.var_unification_table.inlined_probe_value(inner).known() { | 477 | match self.var_unification_table.inlined_probe_value(inner).known() { |
465 | Some(known_ty) => { | 478 | Some(known_ty) => { |
466 | // The known_ty can't be a type var itself | 479 | // The known_ty can't be a type var itself |
@@ -481,55 +494,63 @@ impl InferenceTable { | |||
481 | /// 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 |
482 | /// known type. | 495 | /// known type. |
483 | 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 { |
484 | ty.fold(&mut |ty| match ty.kind(&Interner) { | 497 | fold_tys( |
485 | &TyKind::InferenceVar(tv, kind) => { | 498 | ty, |
486 | let inner = tv.to_inner(); | 499 | |ty, _| match ty.kind(&Interner) { |
487 | if tv_stack.contains(&inner) { | 500 | &TyKind::InferenceVar(tv, kind) => { |
488 | cov_mark::hit!(type_var_cycles_resolve_as_possible); | 501 | let inner = from_inference_var(tv); |
489 | // recursive type | 502 | if tv_stack.contains(&inner) { |
490 | return self.type_variable_table.fallback_value(tv, kind); | 503 | cov_mark::hit!(type_var_cycles_resolve_as_possible); |
491 | } | 504 | // recursive type |
492 | if let Some(known_ty) = | 505 | return self.type_variable_table.fallback_value(tv, kind); |
493 | self.var_unification_table.inlined_probe_value(inner).known() | 506 | } |
494 | { | 507 | if let Some(known_ty) = |
495 | // known_ty may contain other variables that are known by now | 508 | self.var_unification_table.inlined_probe_value(inner).known() |
496 | tv_stack.push(inner); | 509 | { |
497 | 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 |
498 | tv_stack.pop(); | 511 | tv_stack.push(inner); |
499 | result | 512 | let result = self.resolve_ty_as_possible_inner(tv_stack, known_ty.clone()); |
500 | } else { | 513 | tv_stack.pop(); |
501 | ty | 514 | result |
515 | } else { | ||
516 | ty | ||
517 | } | ||
502 | } | 518 | } |
503 | } | 519 | _ => ty, |
504 | _ => ty, | 520 | }, |
505 | }) | 521 | DebruijnIndex::INNERMOST, |
522 | ) | ||
506 | } | 523 | } |
507 | 524 | ||
508 | /// Resolves the type completely; type variables without known type are | 525 | /// Resolves the type completely; type variables without known type are |
509 | /// replaced by TyKind::Unknown. | 526 | /// replaced by TyKind::Unknown. |
510 | 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 { |
511 | ty.fold(&mut |ty| match ty.kind(&Interner) { | 528 | fold_tys( |
512 | &TyKind::InferenceVar(tv, kind) => { | 529 | ty, |
513 | let inner = tv.to_inner(); | 530 | |ty, _| match ty.kind(&Interner) { |
514 | if tv_stack.contains(&inner) { | 531 | &TyKind::InferenceVar(tv, kind) => { |
515 | cov_mark::hit!(type_var_cycles_resolve_completely); | 532 | let inner = from_inference_var(tv); |
516 | // recursive type | 533 | if tv_stack.contains(&inner) { |
517 | return self.type_variable_table.fallback_value(tv, kind); | 534 | cov_mark::hit!(type_var_cycles_resolve_completely); |
518 | } | 535 | // recursive type |
519 | if let Some(known_ty) = | 536 | return self.type_variable_table.fallback_value(tv, kind); |
520 | self.var_unification_table.inlined_probe_value(inner).known() | 537 | } |
521 | { | 538 | if let Some(known_ty) = |
522 | // known_ty may contain other variables that are known by now | 539 | self.var_unification_table.inlined_probe_value(inner).known() |
523 | tv_stack.push(inner); | 540 | { |
524 | let result = self.resolve_ty_completely_inner(tv_stack, known_ty.clone()); | 541 | // known_ty may contain other variables that are known by now |
525 | tv_stack.pop(); | 542 | tv_stack.push(inner); |
526 | result | 543 | let result = self.resolve_ty_completely_inner(tv_stack, known_ty.clone()); |
527 | } else { | 544 | tv_stack.pop(); |
528 | self.type_variable_table.fallback_value(tv, kind) | 545 | result |
546 | } else { | ||
547 | self.type_variable_table.fallback_value(tv, kind) | ||
548 | } | ||
529 | } | 549 | } |
530 | } | 550 | _ => ty, |
531 | _ => ty, | 551 | }, |
532 | }) | 552 | DebruijnIndex::INNERMOST, |
553 | ) | ||
533 | } | 554 | } |
534 | } | 555 | } |
535 | 556 | ||
@@ -553,6 +574,14 @@ impl UnifyKey for TypeVarId { | |||
553 | } | 574 | } |
554 | } | 575 | } |
555 | 576 | ||
577 | fn from_inference_var(var: InferenceVar) -> TypeVarId { | ||
578 | TypeVarId(var.index()) | ||
579 | } | ||
580 | |||
581 | fn to_inference_var(TypeVarId(index): TypeVarId) -> InferenceVar { | ||
582 | index.into() | ||
583 | } | ||
584 | |||
556 | /// 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 |
557 | /// know it yet. | 586 | /// know it yet. |
558 | #[derive(Clone, PartialEq, Eq, Debug)] | 587 | #[derive(Clone, PartialEq, Eq, Debug)] |