diff options
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 11 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 36 |
2 files changed, 33 insertions, 14 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 159a53a63..f1af2a0bd 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, TyExt, 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 | ||
@@ -148,7 +148,14 @@ impl<'a> InferenceContext<'a> { | |||
148 | 148 | ||
149 | match solution { | 149 | match solution { |
150 | Solution::Unique(v) => { | 150 | Solution::Unique(v) => { |
151 | canonicalized.apply_solution(self, v.0); | 151 | canonicalized.apply_solution( |
152 | self, | ||
153 | Canonical { | ||
154 | binders: v.binders, | ||
155 | // FIXME handle constraints | ||
156 | value: v.value.subst, | ||
157 | }, | ||
158 | ); | ||
152 | } | 159 | } |
153 | _ => return None, | 160 | _ => return None, |
154 | }; | 161 | }; |
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 7d76cda68..d717e3375 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -51,7 +51,7 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { | |||
51 | t.fold_binders( | 51 | t.fold_binders( |
52 | &mut |ty, binders| match ty.kind(&Interner) { | 52 | &mut |ty, binders| match ty.kind(&Interner) { |
53 | &TyKind::InferenceVar(var, kind) => { | 53 | &TyKind::InferenceVar(var, kind) => { |
54 | let inner = var.to_inner(); | 54 | let inner = from_inference_var(var); |
55 | if self.var_stack.contains(&inner) { | 55 | if self.var_stack.contains(&inner) { |
56 | // recursive type | 56 | // recursive type |
57 | return self.ctx.table.type_variable_table.fallback_value(var, kind); | 57 | return self.ctx.table.type_variable_table.fallback_value(var, kind); |
@@ -65,7 +65,7 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { | |||
65 | result | 65 | result |
66 | } else { | 66 | } else { |
67 | let root = self.ctx.table.var_unification_table.find(inner); | 67 | let root = self.ctx.table.var_unification_table.find(inner); |
68 | let position = self.add(InferenceVar::from_inner(root), kind); | 68 | let position = self.add(to_inference_var(root), kind); |
69 | TyKind::BoundVar(BoundVar::new(binders, position)).intern(&Interner) | 69 | TyKind::BoundVar(BoundVar::new(binders, position)).intern(&Interner) |
70 | } | 70 | } |
71 | } | 71 | } |
@@ -207,16 +207,16 @@ impl TypeVariableTable { | |||
207 | } | 207 | } |
208 | 208 | ||
209 | pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) { | 209 | pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) { |
210 | self.inner[iv.to_inner().0 as usize].diverging = diverging; | 210 | self.inner[from_inference_var(iv).0 as usize].diverging = diverging; |
211 | } | 211 | } |
212 | 212 | ||
213 | fn is_diverging(&mut self, iv: InferenceVar) -> bool { | 213 | fn is_diverging(&mut self, iv: InferenceVar) -> bool { |
214 | self.inner[iv.to_inner().0 as usize].diverging | 214 | self.inner[from_inference_var(iv).0 as usize].diverging |
215 | } | 215 | } |
216 | 216 | ||
217 | fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { | 217 | fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { |
218 | match kind { | 218 | match kind { |
219 | _ if self.inner[iv.to_inner().0 as usize].diverging => TyKind::Never, | 219 | _ if self.inner[from_inference_var(iv).0 as usize].diverging => TyKind::Never, |
220 | TyVariableKind::General => TyKind::Error, | 220 | TyVariableKind::General => TyKind::Error, |
221 | TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)), | 221 | TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)), |
222 | TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)), | 222 | TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)), |
@@ -250,7 +250,7 @@ impl InferenceTable { | |||
250 | self.type_variable_table.push(TypeVariableData { diverging }); | 250 | self.type_variable_table.push(TypeVariableData { diverging }); |
251 | let key = self.var_unification_table.new_key(TypeVarValue::Unknown); | 251 | let key = self.var_unification_table.new_key(TypeVarValue::Unknown); |
252 | assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1); | 252 | assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1); |
253 | TyKind::InferenceVar(InferenceVar::from_inner(key), kind).intern(&Interner) | 253 | TyKind::InferenceVar(to_inference_var(key), kind).intern(&Interner) |
254 | } | 254 | } |
255 | 255 | ||
256 | pub(crate) fn new_type_var(&mut self) -> Ty { | 256 | pub(crate) fn new_type_var(&mut self) -> Ty { |
@@ -369,8 +369,12 @@ impl InferenceTable { | |||
369 | == self.type_variable_table.is_diverging(*tv2) => | 369 | == self.type_variable_table.is_diverging(*tv2) => |
370 | { | 370 | { |
371 | // both type vars are unknown since we tried to resolve them | 371 | // both type vars are unknown since we tried to resolve them |
372 | if !self.var_unification_table.unioned(tv1.to_inner(), tv2.to_inner()) { | 372 | if !self |
373 | self.var_unification_table.union(tv1.to_inner(), tv2.to_inner()); | 373 | .var_unification_table |
374 | .unioned(from_inference_var(*tv1), from_inference_var(*tv2)) | ||
375 | { | ||
376 | self.var_unification_table | ||
377 | .union(from_inference_var(*tv1), from_inference_var(*tv2)); | ||
374 | self.revision += 1; | 378 | self.revision += 1; |
375 | } | 379 | } |
376 | true | 380 | true |
@@ -407,7 +411,7 @@ impl InferenceTable { | |||
407 | ) => { | 411 | ) => { |
408 | // the type var is unknown since we tried to resolve it | 412 | // the type var is unknown since we tried to resolve it |
409 | self.var_unification_table.union_value( | 413 | self.var_unification_table.union_value( |
410 | tv.to_inner(), | 414 | from_inference_var(*tv), |
411 | TypeVarValue::Known(other.clone().intern(&Interner)), | 415 | TypeVarValue::Known(other.clone().intern(&Interner)), |
412 | ); | 416 | ); |
413 | self.revision += 1; | 417 | self.revision += 1; |
@@ -462,7 +466,7 @@ impl InferenceTable { | |||
462 | } | 466 | } |
463 | match ty.kind(&Interner) { | 467 | match ty.kind(&Interner) { |
464 | TyKind::InferenceVar(tv, _) => { | 468 | TyKind::InferenceVar(tv, _) => { |
465 | let inner = tv.to_inner(); | 469 | let inner = from_inference_var(*tv); |
466 | match self.var_unification_table.inlined_probe_value(inner).known() { | 470 | match self.var_unification_table.inlined_probe_value(inner).known() { |
467 | Some(known_ty) => { | 471 | Some(known_ty) => { |
468 | // The known_ty can't be a type var itself | 472 | // The known_ty can't be a type var itself |
@@ -485,7 +489,7 @@ impl InferenceTable { | |||
485 | fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | 489 | fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { |
486 | ty.fold(&mut |ty| match ty.kind(&Interner) { | 490 | ty.fold(&mut |ty| match ty.kind(&Interner) { |
487 | &TyKind::InferenceVar(tv, kind) => { | 491 | &TyKind::InferenceVar(tv, kind) => { |
488 | let inner = tv.to_inner(); | 492 | let inner = from_inference_var(tv); |
489 | if tv_stack.contains(&inner) { | 493 | if tv_stack.contains(&inner) { |
490 | cov_mark::hit!(type_var_cycles_resolve_as_possible); | 494 | cov_mark::hit!(type_var_cycles_resolve_as_possible); |
491 | // recursive type | 495 | // recursive type |
@@ -512,7 +516,7 @@ impl InferenceTable { | |||
512 | fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | 516 | fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { |
513 | ty.fold(&mut |ty| match ty.kind(&Interner) { | 517 | ty.fold(&mut |ty| match ty.kind(&Interner) { |
514 | &TyKind::InferenceVar(tv, kind) => { | 518 | &TyKind::InferenceVar(tv, kind) => { |
515 | let inner = tv.to_inner(); | 519 | let inner = from_inference_var(tv); |
516 | if tv_stack.contains(&inner) { | 520 | if tv_stack.contains(&inner) { |
517 | cov_mark::hit!(type_var_cycles_resolve_completely); | 521 | cov_mark::hit!(type_var_cycles_resolve_completely); |
518 | // recursive type | 522 | // recursive type |
@@ -555,6 +559,14 @@ impl UnifyKey for TypeVarId { | |||
555 | } | 559 | } |
556 | } | 560 | } |
557 | 561 | ||
562 | fn from_inference_var(var: InferenceVar) -> TypeVarId { | ||
563 | TypeVarId(var.index()) | ||
564 | } | ||
565 | |||
566 | fn to_inference_var(TypeVarId(index): TypeVarId) -> InferenceVar { | ||
567 | index.into() | ||
568 | } | ||
569 | |||
558 | /// The value of a type variable: either we already know the type, or we don't | 570 | /// The value of a type variable: either we already know the type, or we don't |
559 | /// know it yet. | 571 | /// know it yet. |
560 | #[derive(Clone, PartialEq, Eq, Debug)] | 572 | #[derive(Clone, PartialEq, Eq, Debug)] |