diff options
author | Lukas Wirth <[email protected]> | 2021-03-01 11:35:11 +0000 |
---|---|---|
committer | Lukas Wirth <[email protected]> | 2021-03-01 11:41:29 +0000 |
commit | 11a1f13cd1cf6da484fd4b8bfb5f72a625c2186a (patch) | |
tree | d9923bbea2a75e02b599961790952e8a9a2edf2e /crates/hir_ty/src/infer | |
parent | 4e5c49619986144f6f0b1656bed2fac30b638a26 (diff) |
Being Ty::InferenceVar closes to chalk equivalent
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 8 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 13 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 193 |
3 files changed, 130 insertions, 84 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 4cca35904..667b26a76 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs | |||
@@ -4,12 +4,13 @@ | |||
4 | //! | 4 | //! |
5 | //! See: https://doc.rust-lang.org/nomicon/coercions.html | 5 | //! See: https://doc.rust-lang.org/nomicon/coercions.html |
6 | 6 | ||
7 | use chalk_ir::TyVariableKind; | ||
7 | use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; | 8 | use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; |
8 | use test_utils::mark; | 9 | use test_utils::mark; |
9 | 10 | ||
10 | use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty}; | 11 | use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty}; |
11 | 12 | ||
12 | use super::{unify::TypeVarValue, InEnvironment, InferTy, InferenceContext}; | 13 | use super::{InEnvironment, InferenceContext}; |
13 | 14 | ||
14 | impl<'a> InferenceContext<'a> { | 15 | impl<'a> InferenceContext<'a> { |
15 | /// Unify two types, but may coerce the first one to the second one | 16 | /// Unify two types, but may coerce the first one to the second one |
@@ -53,9 +54,8 @@ impl<'a> InferenceContext<'a> { | |||
53 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { | 54 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { |
54 | match (&from_ty, to_ty) { | 55 | match (&from_ty, to_ty) { |
55 | // Never type will make type variable to fallback to Never Type instead of Unknown. | 56 | // Never type will make type variable to fallback to Never Type instead of Unknown. |
56 | (Ty::Never, Ty::Infer(InferTy::TypeVar(tv))) => { | 57 | (Ty::Never, Ty::InferenceVar(tv, TyVariableKind::General)) => { |
57 | let var = self.table.new_maybe_never_type_var(); | 58 | self.table.type_variable_table.set_diverging(*tv, true); |
58 | self.table.var_unification_table.union_value(*tv, TypeVarValue::Known(var)); | ||
59 | return true; | 59 | return true; |
60 | } | 60 | } |
61 | (Ty::Never, _) => return true, | 61 | (Ty::Never, _) => return true, |
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 23d4ac8ef..928ad37a3 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -3,6 +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::TyVariableKind; | ||
6 | use hir_def::{ | 7 | use hir_def::{ |
7 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, | 8 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, |
8 | path::{GenericArg, GenericArgs}, | 9 | path::{GenericArg, GenericArgs}, |
@@ -18,8 +19,8 @@ use crate::{ | |||
18 | primitive::{self, UintTy}, | 19 | primitive::{self, UintTy}, |
19 | traits::{FnTrait, InEnvironment}, | 20 | traits::{FnTrait, InEnvironment}, |
20 | utils::{generics, variant_data, Generics}, | 21 | utils::{generics, variant_data, Generics}, |
21 | Binders, CallableDefId, FnPointer, FnSig, InferTy, Mutability, Obligation, OpaqueTyId, Rawness, | 22 | Binders, CallableDefId, FnPointer, FnSig, Mutability, Obligation, OpaqueTyId, Rawness, Scalar, |
22 | Scalar, Substs, TraitRef, Ty, | 23 | Substs, TraitRef, Ty, |
23 | }; | 24 | }; |
24 | 25 | ||
25 | use super::{ | 26 | use super::{ |
@@ -527,8 +528,8 @@ impl<'a> InferenceContext<'a> { | |||
527 | Ty::Scalar(Scalar::Int(_)) | 528 | Ty::Scalar(Scalar::Int(_)) |
528 | | Ty::Scalar(Scalar::Uint(_)) | 529 | | Ty::Scalar(Scalar::Uint(_)) |
529 | | Ty::Scalar(Scalar::Float(_)) | 530 | | Ty::Scalar(Scalar::Float(_)) |
530 | | Ty::Infer(InferTy::IntVar(..)) | 531 | | Ty::InferenceVar(_, TyVariableKind::Integer) |
531 | | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, | 532 | | Ty::InferenceVar(_, TyVariableKind::Float) => inner_ty, |
532 | // Otherwise we resolve via the std::ops::Neg trait | 533 | // Otherwise we resolve via the std::ops::Neg trait |
533 | _ => self | 534 | _ => self |
534 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), | 535 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), |
@@ -540,7 +541,7 @@ impl<'a> InferenceContext<'a> { | |||
540 | Ty::Scalar(Scalar::Bool) | 541 | Ty::Scalar(Scalar::Bool) |
541 | | Ty::Scalar(Scalar::Int(_)) | 542 | | Ty::Scalar(Scalar::Int(_)) |
542 | | Ty::Scalar(Scalar::Uint(_)) | 543 | | Ty::Scalar(Scalar::Uint(_)) |
543 | | Ty::Infer(InferTy::IntVar(..)) => inner_ty, | 544 | | Ty::InferenceVar(_, TyVariableKind::Integer) => inner_ty, |
544 | // Otherwise we resolve via the std::ops::Not trait | 545 | // Otherwise we resolve via the std::ops::Not trait |
545 | _ => self | 546 | _ => self |
546 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), | 547 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), |
@@ -761,7 +762,7 @@ impl<'a> InferenceContext<'a> { | |||
761 | // `!`). | 762 | // `!`). |
762 | if self.diverges.is_always() { | 763 | if self.diverges.is_always() { |
763 | // we don't even make an attempt at coercion | 764 | // we don't even make an attempt at coercion |
764 | self.table.new_maybe_never_type_var() | 765 | self.table.new_maybe_never_var() |
765 | } else { | 766 | } else { |
766 | self.coerce(&Ty::unit(), expected.coercion_target()); | 767 | self.coerce(&Ty::unit(), expected.coercion_target()); |
767 | Ty::unit() | 768 | Ty::unit() |
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 2852ad5bf..1e9a94c04 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -2,14 +2,15 @@ | |||
2 | 2 | ||
3 | use std::borrow::Cow; | 3 | use std::borrow::Cow; |
4 | 4 | ||
5 | use chalk_ir::{FloatTy, IntTy, TyVariableKind}; | ||
5 | use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; | 6 | use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; |
6 | 7 | ||
7 | use test_utils::mark; | 8 | use test_utils::mark; |
8 | 9 | ||
9 | use super::{InferenceContext, Obligation}; | 10 | use super::{InferenceContext, Obligation}; |
10 | use crate::{ | 11 | use crate::{ |
11 | BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Scalar, Substs, | 12 | BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferenceVar, Scalar, |
12 | Ty, TyKind, TypeWalk, | 13 | Substs, Ty, TypeWalk, |
13 | }; | 14 | }; |
14 | 15 | ||
15 | impl<'a> InferenceContext<'a> { | 16 | impl<'a> InferenceContext<'a> { |
@@ -26,7 +27,7 @@ where | |||
26 | 'a: 'b, | 27 | 'a: 'b, |
27 | { | 28 | { |
28 | ctx: &'b mut InferenceContext<'a>, | 29 | ctx: &'b mut InferenceContext<'a>, |
29 | free_vars: Vec<InferTy>, | 30 | free_vars: Vec<(InferenceVar, TyVariableKind)>, |
30 | /// A stack of type variables that is used to detect recursive types (which | 31 | /// A stack of type variables that is used to detect recursive types (which |
31 | /// are an error, but we need to protect against them to avoid stack | 32 | /// are an error, but we need to protect against them to avoid stack |
32 | /// overflows). | 33 | /// overflows). |
@@ -36,17 +37,14 @@ where | |||
36 | #[derive(Debug)] | 37 | #[derive(Debug)] |
37 | pub(super) struct Canonicalized<T> { | 38 | pub(super) struct Canonicalized<T> { |
38 | pub(super) value: Canonical<T>, | 39 | pub(super) value: Canonical<T>, |
39 | free_vars: Vec<InferTy>, | 40 | free_vars: Vec<(InferenceVar, TyVariableKind)>, |
40 | } | 41 | } |
41 | 42 | ||
42 | impl<'a, 'b> Canonicalizer<'a, 'b> | 43 | impl<'a, 'b> Canonicalizer<'a, 'b> { |
43 | where | 44 | fn add(&mut self, free_var: InferenceVar, kind: TyVariableKind) -> usize { |
44 | 'a: 'b, | 45 | self.free_vars.iter().position(|&(v, _)| v == free_var).unwrap_or_else(|| { |
45 | { | ||
46 | fn add(&mut self, free_var: InferTy) -> usize { | ||
47 | self.free_vars.iter().position(|&v| v == free_var).unwrap_or_else(|| { | ||
48 | let next_index = self.free_vars.len(); | 46 | let next_index = self.free_vars.len(); |
49 | self.free_vars.push(free_var); | 47 | self.free_vars.push((free_var, kind)); |
50 | next_index | 48 | next_index |
51 | }) | 49 | }) |
52 | } | 50 | } |
@@ -54,11 +52,11 @@ where | |||
54 | fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { | 52 | fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { |
55 | t.fold_binders( | 53 | t.fold_binders( |
56 | &mut |ty, binders| match ty { | 54 | &mut |ty, binders| match ty { |
57 | Ty::Infer(tv) => { | 55 | Ty::InferenceVar(var, kind) => { |
58 | let inner = tv.to_inner(); | 56 | let inner = var.to_inner(); |
59 | if self.var_stack.contains(&inner) { | 57 | if self.var_stack.contains(&inner) { |
60 | // recursive type | 58 | // recursive type |
61 | return tv.fallback_value(); | 59 | return self.ctx.table.type_variable_table.fallback_value(var, kind); |
62 | } | 60 | } |
63 | if let Some(known_ty) = | 61 | if let Some(known_ty) = |
64 | self.ctx.table.var_unification_table.inlined_probe_value(inner).known() | 62 | self.ctx.table.var_unification_table.inlined_probe_value(inner).known() |
@@ -69,13 +67,7 @@ where | |||
69 | result | 67 | result |
70 | } else { | 68 | } else { |
71 | let root = self.ctx.table.var_unification_table.find(inner); | 69 | let root = self.ctx.table.var_unification_table.find(inner); |
72 | let free_var = match tv { | 70 | let position = self.add(InferenceVar::from_inner(root), kind); |
73 | InferTy::TypeVar(_) => InferTy::TypeVar(root), | ||
74 | InferTy::IntVar(_) => InferTy::IntVar(root), | ||
75 | InferTy::FloatVar(_) => InferTy::FloatVar(root), | ||
76 | InferTy::MaybeNeverTypeVar(_) => InferTy::MaybeNeverTypeVar(root), | ||
77 | }; | ||
78 | let position = self.add(free_var); | ||
79 | Ty::Bound(BoundVar::new(binders, position)) | 71 | Ty::Bound(BoundVar::new(binders, position)) |
80 | } | 72 | } |
81 | } | 73 | } |
@@ -86,19 +78,7 @@ where | |||
86 | } | 78 | } |
87 | 79 | ||
88 | fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> { | 80 | fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> { |
89 | let kinds = self | 81 | let kinds = self.free_vars.iter().map(|&(_, k)| k).collect(); |
90 | .free_vars | ||
91 | .iter() | ||
92 | .map(|v| match v { | ||
93 | // mapping MaybeNeverTypeVar to the same kind as general ones | ||
94 | // should be fine, because as opposed to int or float type vars, | ||
95 | // they don't restrict what kind of type can go into them, they | ||
96 | // just affect fallback. | ||
97 | InferTy::TypeVar(_) | InferTy::MaybeNeverTypeVar(_) => TyKind::General, | ||
98 | InferTy::IntVar(_) => TyKind::Integer, | ||
99 | InferTy::FloatVar(_) => TyKind::Float, | ||
100 | }) | ||
101 | .collect(); | ||
102 | Canonicalized { value: Canonical { value: result, kinds }, free_vars: self.free_vars } | 82 | Canonicalized { value: Canonical { value: result, kinds }, free_vars: self.free_vars } |
103 | } | 83 | } |
104 | 84 | ||
@@ -132,7 +112,8 @@ impl<T> Canonicalized<T> { | |||
132 | &mut |ty, binders| { | 112 | &mut |ty, binders| { |
133 | if let &mut Ty::Bound(bound) = ty { | 113 | if let &mut Ty::Bound(bound) = ty { |
134 | if bound.debruijn >= binders { | 114 | if bound.debruijn >= binders { |
135 | *ty = Ty::Infer(self.free_vars[bound.index]); | 115 | let (v, k) = self.free_vars[bound.index]; |
116 | *ty = Ty::InferenceVar(v, k); | ||
136 | } | 117 | } |
137 | } | 118 | } |
138 | }, | 119 | }, |
@@ -152,18 +133,18 @@ impl<T> Canonicalized<T> { | |||
152 | .kinds | 133 | .kinds |
153 | .iter() | 134 | .iter() |
154 | .map(|k| match k { | 135 | .map(|k| match k { |
155 | TyKind::General => ctx.table.new_type_var(), | 136 | TyVariableKind::General => ctx.table.new_type_var(), |
156 | TyKind::Integer => ctx.table.new_integer_var(), | 137 | TyVariableKind::Integer => ctx.table.new_integer_var(), |
157 | TyKind::Float => ctx.table.new_float_var(), | 138 | TyVariableKind::Float => ctx.table.new_float_var(), |
158 | }) | 139 | }) |
159 | .collect(), | 140 | .collect(), |
160 | ); | 141 | ); |
161 | for (i, ty) in solution.value.into_iter().enumerate() { | 142 | for (i, ty) in solution.value.into_iter().enumerate() { |
162 | let var = self.free_vars[i]; | 143 | let (v, k) = self.free_vars[i]; |
163 | // eagerly replace projections in the type; we may be getting types | 144 | // eagerly replace projections in the type; we may be getting types |
164 | // e.g. from where clauses where this hasn't happened yet | 145 | // e.g. from where clauses where this hasn't happened yet |
165 | let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); | 146 | let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); |
166 | ctx.table.unify(&Ty::Infer(var), &ty); | 147 | ctx.table.unify(&Ty::InferenceVar(v, k), &ty); |
167 | } | 148 | } |
168 | } | 149 | } |
169 | } | 150 | } |
@@ -198,31 +179,82 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> { | |||
198 | } | 179 | } |
199 | 180 | ||
200 | #[derive(Clone, Debug)] | 181 | #[derive(Clone, Debug)] |
182 | pub(super) struct TypeVariableTable { | ||
183 | inner: Vec<TypeVariableData>, | ||
184 | } | ||
185 | |||
186 | impl TypeVariableTable { | ||
187 | fn push(&mut self, data: TypeVariableData) { | ||
188 | self.inner.push(data); | ||
189 | } | ||
190 | |||
191 | pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) { | ||
192 | self.inner[iv.to_inner().0 as usize].diverging = diverging; | ||
193 | } | ||
194 | |||
195 | fn is_diverging(&mut self, iv: InferenceVar) -> bool { | ||
196 | self.inner[iv.to_inner().0 as usize].diverging | ||
197 | } | ||
198 | |||
199 | fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { | ||
200 | match kind { | ||
201 | _ if self.inner[iv.to_inner().0 as usize].diverging => Ty::Never, | ||
202 | TyVariableKind::General => Ty::Unknown, | ||
203 | TyVariableKind::Integer => Ty::Scalar(Scalar::Int(IntTy::I32)), | ||
204 | TyVariableKind::Float => Ty::Scalar(Scalar::Float(FloatTy::F64)), | ||
205 | } | ||
206 | } | ||
207 | } | ||
208 | |||
209 | #[derive(Copy, Clone, Debug)] | ||
210 | pub(crate) struct TypeVariableData { | ||
211 | diverging: bool, | ||
212 | } | ||
213 | |||
214 | #[derive(Clone, Debug)] | ||
201 | pub(crate) struct InferenceTable { | 215 | pub(crate) struct InferenceTable { |
202 | pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>, | 216 | pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>, |
217 | pub(super) type_variable_table: TypeVariableTable, | ||
203 | } | 218 | } |
204 | 219 | ||
205 | impl InferenceTable { | 220 | impl InferenceTable { |
206 | pub(crate) fn new() -> Self { | 221 | pub(crate) fn new() -> Self { |
207 | InferenceTable { var_unification_table: InPlaceUnificationTable::new() } | 222 | InferenceTable { |
223 | var_unification_table: InPlaceUnificationTable::new(), | ||
224 | type_variable_table: TypeVariableTable { inner: Vec::new() }, | ||
225 | } | ||
208 | } | 226 | } |
209 | 227 | ||
210 | pub(crate) fn new_type_var(&mut self) -> Ty { | 228 | pub(crate) fn new_type_var(&mut self) -> Ty { |
211 | Ty::Infer(InferTy::TypeVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) | 229 | self.type_variable_table.push(TypeVariableData { diverging: false }); |
230 | Ty::InferenceVar( | ||
231 | InferenceVar::from_inner(self.var_unification_table.new_key(TypeVarValue::Unknown)), | ||
232 | TyVariableKind::General, | ||
233 | ) | ||
212 | } | 234 | } |
213 | 235 | ||
214 | pub(crate) fn new_integer_var(&mut self) -> Ty { | 236 | pub(crate) fn new_integer_var(&mut self) -> Ty { |
215 | Ty::Infer(InferTy::IntVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) | 237 | self.type_variable_table.push(TypeVariableData { diverging: false }); |
238 | Ty::InferenceVar( | ||
239 | InferenceVar::from_inner(self.var_unification_table.new_key(TypeVarValue::Unknown)), | ||
240 | TyVariableKind::Integer, | ||
241 | ) | ||
216 | } | 242 | } |
217 | 243 | ||
218 | pub(crate) fn new_float_var(&mut self) -> Ty { | 244 | pub(crate) fn new_float_var(&mut self) -> Ty { |
219 | Ty::Infer(InferTy::FloatVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) | 245 | self.type_variable_table.push(TypeVariableData { diverging: false }); |
246 | Ty::InferenceVar( | ||
247 | InferenceVar::from_inner(self.var_unification_table.new_key(TypeVarValue::Unknown)), | ||
248 | TyVariableKind::Float, | ||
249 | ) | ||
220 | } | 250 | } |
221 | 251 | ||
222 | pub(crate) fn new_maybe_never_type_var(&mut self) -> Ty { | 252 | pub(crate) fn new_maybe_never_var(&mut self) -> Ty { |
223 | Ty::Infer(InferTy::MaybeNeverTypeVar( | 253 | self.type_variable_table.push(TypeVariableData { diverging: true }); |
224 | self.var_unification_table.new_key(TypeVarValue::Unknown), | 254 | Ty::InferenceVar( |
225 | )) | 255 | InferenceVar::from_inner(self.var_unification_table.new_key(TypeVarValue::Unknown)), |
256 | TyVariableKind::General, | ||
257 | ) | ||
226 | } | 258 | } |
227 | 259 | ||
228 | pub(crate) fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { | 260 | pub(crate) fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { |
@@ -283,33 +315,46 @@ impl InferenceTable { | |||
283 | true | 315 | true |
284 | } | 316 | } |
285 | 317 | ||
286 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) | 318 | ( |
287 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) | 319 | Ty::InferenceVar(tv1, TyVariableKind::General), |
288 | | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) | 320 | Ty::InferenceVar(tv2, TyVariableKind::General), |
321 | ) | ||
289 | | ( | 322 | | ( |
290 | Ty::Infer(InferTy::MaybeNeverTypeVar(tv1)), | 323 | Ty::InferenceVar(tv1, TyVariableKind::Integer), |
291 | Ty::Infer(InferTy::MaybeNeverTypeVar(tv2)), | 324 | Ty::InferenceVar(tv2, TyVariableKind::Integer), |
292 | ) => { | 325 | ) |
326 | | ( | ||
327 | Ty::InferenceVar(tv1, TyVariableKind::Float), | ||
328 | Ty::InferenceVar(tv2, TyVariableKind::Float), | ||
329 | ) if self.type_variable_table.is_diverging(*tv1) | ||
330 | == self.type_variable_table.is_diverging(*tv2) => | ||
331 | { | ||
293 | // both type vars are unknown since we tried to resolve them | 332 | // both type vars are unknown since we tried to resolve them |
294 | self.var_unification_table.union(*tv1, *tv2); | 333 | self.var_unification_table.union(tv1.to_inner(), tv2.to_inner()); |
295 | true | 334 | true |
296 | } | 335 | } |
297 | 336 | ||
298 | // The order of MaybeNeverTypeVar matters here. | 337 | // The order of MaybeNeverTypeVar matters here. |
299 | // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. | 338 | // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. |
300 | // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. | 339 | // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. |
301 | (Ty::Infer(InferTy::TypeVar(tv)), other) | 340 | (Ty::InferenceVar(tv, TyVariableKind::General), other) |
302 | | (other, Ty::Infer(InferTy::TypeVar(tv))) | 341 | | (other, Ty::InferenceVar(tv, TyVariableKind::General)) |
303 | | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other) | 342 | | (Ty::InferenceVar(tv, TyVariableKind::Integer), other @ Ty::Scalar(Scalar::Int(_))) |
304 | | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv))) | 343 | | (other @ Ty::Scalar(Scalar::Int(_)), Ty::InferenceVar(tv, TyVariableKind::Integer)) |
305 | | (Ty::Infer(InferTy::IntVar(tv)), other @ Ty::Scalar(Scalar::Int(_))) | 344 | | ( |
306 | | (other @ Ty::Scalar(Scalar::Int(_)), Ty::Infer(InferTy::IntVar(tv))) | 345 | Ty::InferenceVar(tv, TyVariableKind::Integer), |
307 | | (Ty::Infer(InferTy::IntVar(tv)), other @ Ty::Scalar(Scalar::Uint(_))) | 346 | other @ Ty::Scalar(Scalar::Uint(_)), |
308 | | (other @ Ty::Scalar(Scalar::Uint(_)), Ty::Infer(InferTy::IntVar(tv))) | 347 | ) |
309 | | (Ty::Infer(InferTy::FloatVar(tv)), other @ Ty::Scalar(Scalar::Float(_))) | 348 | | ( |
310 | | (other @ Ty::Scalar(Scalar::Float(_)), Ty::Infer(InferTy::FloatVar(tv))) => { | 349 | other @ Ty::Scalar(Scalar::Uint(_)), |
350 | Ty::InferenceVar(tv, TyVariableKind::Integer), | ||
351 | ) | ||
352 | | (Ty::InferenceVar(tv, TyVariableKind::Float), other @ Ty::Scalar(Scalar::Float(_))) | ||
353 | | (other @ Ty::Scalar(Scalar::Float(_)), Ty::InferenceVar(tv, TyVariableKind::Float)) => | ||
354 | { | ||
311 | // the type var is unknown since we tried to resolve it | 355 | // the type var is unknown since we tried to resolve it |
312 | self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); | 356 | self.var_unification_table |
357 | .union_value(tv.to_inner(), TypeVarValue::Known(other.clone())); | ||
313 | true | 358 | true |
314 | } | 359 | } |
315 | 360 | ||
@@ -354,7 +399,7 @@ impl InferenceTable { | |||
354 | mark::hit!(type_var_resolves_to_int_var); | 399 | mark::hit!(type_var_resolves_to_int_var); |
355 | } | 400 | } |
356 | match &*ty { | 401 | match &*ty { |
357 | Ty::Infer(tv) => { | 402 | Ty::InferenceVar(tv, _) => { |
358 | let inner = tv.to_inner(); | 403 | let inner = tv.to_inner(); |
359 | match self.var_unification_table.inlined_probe_value(inner).known() { | 404 | match self.var_unification_table.inlined_probe_value(inner).known() { |
360 | Some(known_ty) => { | 405 | Some(known_ty) => { |
@@ -377,12 +422,12 @@ impl InferenceTable { | |||
377 | /// known type. | 422 | /// known type. |
378 | fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | 423 | fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { |
379 | ty.fold(&mut |ty| match ty { | 424 | ty.fold(&mut |ty| match ty { |
380 | Ty::Infer(tv) => { | 425 | Ty::InferenceVar(tv, kind) => { |
381 | let inner = tv.to_inner(); | 426 | let inner = tv.to_inner(); |
382 | if tv_stack.contains(&inner) { | 427 | if tv_stack.contains(&inner) { |
383 | mark::hit!(type_var_cycles_resolve_as_possible); | 428 | mark::hit!(type_var_cycles_resolve_as_possible); |
384 | // recursive type | 429 | // recursive type |
385 | return tv.fallback_value(); | 430 | return self.type_variable_table.fallback_value(tv, kind); |
386 | } | 431 | } |
387 | if let Some(known_ty) = | 432 | if let Some(known_ty) = |
388 | self.var_unification_table.inlined_probe_value(inner).known() | 433 | self.var_unification_table.inlined_probe_value(inner).known() |
@@ -404,12 +449,12 @@ impl InferenceTable { | |||
404 | /// replaced by Ty::Unknown. | 449 | /// replaced by Ty::Unknown. |
405 | fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | 450 | fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { |
406 | ty.fold(&mut |ty| match ty { | 451 | ty.fold(&mut |ty| match ty { |
407 | Ty::Infer(tv) => { | 452 | Ty::InferenceVar(tv, kind) => { |
408 | let inner = tv.to_inner(); | 453 | let inner = tv.to_inner(); |
409 | if tv_stack.contains(&inner) { | 454 | if tv_stack.contains(&inner) { |
410 | mark::hit!(type_var_cycles_resolve_completely); | 455 | mark::hit!(type_var_cycles_resolve_completely); |
411 | // recursive type | 456 | // recursive type |
412 | return tv.fallback_value(); | 457 | return self.type_variable_table.fallback_value(tv, kind); |
413 | } | 458 | } |
414 | if let Some(known_ty) = | 459 | if let Some(known_ty) = |
415 | self.var_unification_table.inlined_probe_value(inner).known() | 460 | self.var_unification_table.inlined_probe_value(inner).known() |
@@ -420,7 +465,7 @@ impl InferenceTable { | |||
420 | tv_stack.pop(); | 465 | tv_stack.pop(); |
421 | result | 466 | result |
422 | } else { | 467 | } else { |
423 | tv.fallback_value() | 468 | self.type_variable_table.fallback_value(tv, kind) |
424 | } | 469 | } |
425 | } | 470 | } |
426 | _ => ty, | 471 | _ => ty, |
@@ -430,7 +475,7 @@ impl InferenceTable { | |||
430 | 475 | ||
431 | /// The ID of a type variable. | 476 | /// The ID of a type variable. |
432 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] | 477 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] |
433 | pub struct TypeVarId(pub(super) u32); | 478 | pub(super) struct TypeVarId(pub(super) u32); |
434 | 479 | ||
435 | impl UnifyKey for TypeVarId { | 480 | impl UnifyKey for TypeVarId { |
436 | type Value = TypeVarValue; | 481 | type Value = TypeVarValue; |
@@ -451,7 +496,7 @@ impl UnifyKey for TypeVarId { | |||
451 | /// The value of a type variable: either we already know the type, or we don't | 496 | /// The value of a type variable: either we already know the type, or we don't |
452 | /// know it yet. | 497 | /// know it yet. |
453 | #[derive(Clone, PartialEq, Eq, Debug)] | 498 | #[derive(Clone, PartialEq, Eq, Debug)] |
454 | pub enum TypeVarValue { | 499 | pub(super) enum TypeVarValue { |
455 | Known(Ty), | 500 | Known(Ty), |
456 | Unknown, | 501 | Unknown, |
457 | } | 502 | } |