diff options
Diffstat (limited to 'crates/hir_ty')
-rw-r--r-- | crates/hir_ty/src/autoderef.rs | 6 | ||||
-rw-r--r-- | crates/hir_ty/src/display.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/infer.rs | 28 | ||||
-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 | ||||
-rw-r--r-- | crates/hir_ty/src/lib.rs | 17 | ||||
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 6 | ||||
-rw-r--r-- | crates/hir_ty/src/op.rs | 15 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 32 |
10 files changed, 170 insertions, 150 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs index ece68183e..21d1e5446 100644 --- a/crates/hir_ty/src/autoderef.rs +++ b/crates/hir_ty/src/autoderef.rs | |||
@@ -89,8 +89,10 @@ fn deref_by_trait( | |||
89 | 89 | ||
90 | let in_env = InEnvironment { value: obligation, environment: ty.environment }; | 90 | let in_env = InEnvironment { value: obligation, environment: ty.environment }; |
91 | 91 | ||
92 | let canonical = | 92 | let canonical = Canonical::new( |
93 | Canonical::new(in_env, ty.value.kinds.iter().copied().chain(Some(super::TyKind::General))); | 93 | in_env, |
94 | ty.value.kinds.iter().copied().chain(Some(chalk_ir::TyVariableKind::General)), | ||
95 | ); | ||
94 | 96 | ||
95 | let solution = db.trait_solve(krate, canonical)?; | 97 | let solution = db.trait_solve(krate, canonical)?; |
96 | 98 | ||
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 179f7ff44..ff8211094 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -565,7 +565,7 @@ impl HirDisplay for Ty { | |||
565 | } | 565 | } |
566 | write!(f, "{{unknown}}")?; | 566 | write!(f, "{{unknown}}")?; |
567 | } | 567 | } |
568 | Ty::Infer(..) => write!(f, "_")?, | 568 | Ty::InferenceVar(..) => write!(f, "_")?, |
569 | } | 569 | } |
570 | Ok(()) | 570 | Ok(()) |
571 | } | 571 | } |
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index a1769729f..1d78d1feb 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs | |||
@@ -36,12 +36,11 @@ use stdx::impl_from; | |||
36 | use syntax::SmolStr; | 36 | use syntax::SmolStr; |
37 | 37 | ||
38 | use super::{ | 38 | use super::{ |
39 | primitive::{FloatTy, IntTy}, | ||
40 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, | 39 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, |
41 | InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, | 40 | InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, |
42 | }; | 41 | }; |
43 | use crate::{ | 42 | use crate::{ |
44 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, Scalar, | 43 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, |
45 | }; | 44 | }; |
46 | 45 | ||
47 | pub(crate) use unify::unify; | 46 | pub(crate) use unify::unify; |
@@ -655,30 +654,17 @@ impl<'a> InferenceContext<'a> { | |||
655 | /// two are used for inference of literal values (e.g. `100` could be one of | 654 | /// two are used for inference of literal values (e.g. `100` could be one of |
656 | /// several integer types). | 655 | /// several integer types). |
657 | #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] | 656 | #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] |
658 | pub enum InferTy { | 657 | pub struct InferenceVar { |
659 | TypeVar(unify::TypeVarId), | 658 | index: u32, |
660 | IntVar(unify::TypeVarId), | ||
661 | FloatVar(unify::TypeVarId), | ||
662 | MaybeNeverTypeVar(unify::TypeVarId), | ||
663 | } | 659 | } |
664 | 660 | ||
665 | impl InferTy { | 661 | impl InferenceVar { |
666 | fn to_inner(self) -> unify::TypeVarId { | 662 | fn to_inner(self) -> unify::TypeVarId { |
667 | match self { | 663 | unify::TypeVarId(self.index) |
668 | InferTy::TypeVar(ty) | ||
669 | | InferTy::IntVar(ty) | ||
670 | | InferTy::FloatVar(ty) | ||
671 | | InferTy::MaybeNeverTypeVar(ty) => ty, | ||
672 | } | ||
673 | } | 664 | } |
674 | 665 | ||
675 | fn fallback_value(self) -> Ty { | 666 | fn from_inner(unify::TypeVarId(index): unify::TypeVarId) -> Self { |
676 | match self { | 667 | InferenceVar { index } |
677 | InferTy::TypeVar(..) => Ty::Unknown, | ||
678 | InferTy::IntVar(..) => Ty::Scalar(Scalar::Int(IntTy::I32)), | ||
679 | InferTy::FloatVar(..) => Ty::Scalar(Scalar::Float(FloatTy::F64)), | ||
680 | InferTy::MaybeNeverTypeVar(..) => Ty::Never, | ||
681 | } | ||
682 | } | 668 | } |
683 | } | 669 | } |
684 | 670 | ||
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 | } |
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 1abb0440f..762437bf4 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -42,14 +42,14 @@ use crate::{ | |||
42 | }; | 42 | }; |
43 | 43 | ||
44 | pub use autoderef::autoderef; | 44 | pub use autoderef::autoderef; |
45 | pub use infer::{InferTy, InferenceResult}; | 45 | pub use infer::{InferenceResult, InferenceVar}; |
46 | pub use lower::{ | 46 | pub use lower::{ |
47 | associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, | 47 | associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, |
48 | TyDefId, TyLoweringContext, ValueTyDefId, | 48 | TyDefId, TyLoweringContext, ValueTyDefId, |
49 | }; | 49 | }; |
50 | pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; | 50 | pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; |
51 | 51 | ||
52 | pub use chalk_ir::{BoundVar, DebruijnIndex, Scalar}; | 52 | pub use chalk_ir::{BoundVar, DebruijnIndex, Scalar, TyVariableKind}; |
53 | 53 | ||
54 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 54 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
55 | pub enum Lifetime { | 55 | pub enum Lifetime { |
@@ -218,7 +218,7 @@ pub enum Ty { | |||
218 | Bound(BoundVar), | 218 | Bound(BoundVar), |
219 | 219 | ||
220 | /// A type variable used during type checking. | 220 | /// A type variable used during type checking. |
221 | Infer(InferTy), | 221 | InferenceVar(InferenceVar, TyVariableKind), |
222 | 222 | ||
223 | /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust). | 223 | /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust). |
224 | /// | 224 | /// |
@@ -527,22 +527,15 @@ impl TypeWalk for GenericPredicate { | |||
527 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 527 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
528 | pub struct Canonical<T> { | 528 | pub struct Canonical<T> { |
529 | pub value: T, | 529 | pub value: T, |
530 | pub kinds: Arc<[TyKind]>, | 530 | pub kinds: Arc<[chalk_ir::TyVariableKind]>, |
531 | } | 531 | } |
532 | 532 | ||
533 | impl<T> Canonical<T> { | 533 | impl<T> Canonical<T> { |
534 | pub fn new(value: T, kinds: impl IntoIterator<Item = TyKind>) -> Self { | 534 | pub fn new(value: T, kinds: impl IntoIterator<Item = chalk_ir::TyVariableKind>) -> Self { |
535 | Self { value, kinds: kinds.into_iter().collect() } | 535 | Self { value, kinds: kinds.into_iter().collect() } |
536 | } | 536 | } |
537 | } | 537 | } |
538 | 538 | ||
539 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||
540 | pub enum TyKind { | ||
541 | General, | ||
542 | Integer, | ||
543 | Float, | ||
544 | } | ||
545 | |||
546 | /// A function signature as seen by type inference: Several parameter types and | 539 | /// A function signature as seen by type inference: Several parameter types and |
547 | /// one return type. | 540 | /// one return type. |
548 | #[derive(Clone, PartialEq, Eq, Debug)] | 541 | #[derive(Clone, PartialEq, Eq, Debug)] |
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index c8a0ad5f1..8b1717873 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs | |||
@@ -19,7 +19,7 @@ use crate::{ | |||
19 | primitive::{self, FloatTy, IntTy, UintTy}, | 19 | primitive::{self, FloatTy, IntTy, UintTy}, |
20 | utils::all_super_traits, | 20 | utils::all_super_traits, |
21 | Canonical, DebruijnIndex, FnPointer, FnSig, InEnvironment, Scalar, Substs, TraitEnvironment, | 21 | Canonical, DebruijnIndex, FnPointer, FnSig, InEnvironment, Scalar, Substs, TraitEnvironment, |
22 | TraitRef, Ty, TyKind, TypeWalk, | 22 | TraitRef, Ty, TypeWalk, |
23 | }; | 23 | }; |
24 | 24 | ||
25 | /// This is used as a key for indexing impls. | 25 | /// This is used as a key for indexing impls. |
@@ -667,7 +667,7 @@ pub(crate) fn inherent_impl_substs( | |||
667 | .build(); | 667 | .build(); |
668 | let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); | 668 | let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); |
669 | let mut kinds = self_ty.kinds.to_vec(); | 669 | let mut kinds = self_ty.kinds.to_vec(); |
670 | kinds.extend(iter::repeat(TyKind::General).take(vars.len())); | 670 | kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(vars.len())); |
671 | let tys = Canonical { kinds: kinds.into(), value: (self_ty_with_vars, self_ty.value.clone()) }; | 671 | let tys = Canonical { kinds: kinds.into(), value: (self_ty_with_vars, self_ty.value.clone()) }; |
672 | let substs = super::infer::unify(&tys); | 672 | let substs = super::infer::unify(&tys); |
673 | // We only want the substs for the vars we added, not the ones from self_ty. | 673 | // We only want the substs for the vars we added, not the ones from self_ty. |
@@ -759,7 +759,7 @@ fn generic_implements_goal( | |||
759 | .push(self_ty.value) | 759 | .push(self_ty.value) |
760 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) | 760 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) |
761 | .build(); | 761 | .build(); |
762 | kinds.extend(iter::repeat(TyKind::General).take(substs.len() - 1)); | 762 | kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(substs.len() - 1)); |
763 | let trait_ref = TraitRef { trait_, substs }; | 763 | let trait_ref = TraitRef { trait_, substs }; |
764 | let obligation = super::Obligation::Trait(trait_ref); | 764 | let obligation = super::Obligation::Trait(trait_ref); |
765 | Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) } | 765 | Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) } |
diff --git a/crates/hir_ty/src/op.rs b/crates/hir_ty/src/op.rs index 1c01a67ad..bb9b8bbfc 100644 --- a/crates/hir_ty/src/op.rs +++ b/crates/hir_ty/src/op.rs | |||
@@ -1,7 +1,8 @@ | |||
1 | //! Helper functions for binary operator type inference. | 1 | //! Helper functions for binary operator type inference. |
2 | use chalk_ir::TyVariableKind; | ||
2 | use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; | 3 | use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; |
3 | 4 | ||
4 | use crate::{InferTy, Scalar, Ty}; | 5 | use crate::{Scalar, Ty}; |
5 | 6 | ||
6 | pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { | 7 | pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { |
7 | match op { | 8 | match op { |
@@ -11,14 +12,16 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { | |||
11 | Ty::Scalar(Scalar::Int(_)) | 12 | Ty::Scalar(Scalar::Int(_)) |
12 | | Ty::Scalar(Scalar::Uint(_)) | 13 | | Ty::Scalar(Scalar::Uint(_)) |
13 | | Ty::Scalar(Scalar::Float(_)) => lhs_ty, | 14 | | Ty::Scalar(Scalar::Float(_)) => lhs_ty, |
14 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, | 15 | Ty::InferenceVar(_, TyVariableKind::Integer) |
16 | | Ty::InferenceVar(_, TyVariableKind::Float) => lhs_ty, | ||
15 | _ => Ty::Unknown, | 17 | _ => Ty::Unknown, |
16 | }, | 18 | }, |
17 | BinaryOp::ArithOp(_) => match rhs_ty { | 19 | BinaryOp::ArithOp(_) => match rhs_ty { |
18 | Ty::Scalar(Scalar::Int(_)) | 20 | Ty::Scalar(Scalar::Int(_)) |
19 | | Ty::Scalar(Scalar::Uint(_)) | 21 | | Ty::Scalar(Scalar::Uint(_)) |
20 | | Ty::Scalar(Scalar::Float(_)) => rhs_ty, | 22 | | Ty::Scalar(Scalar::Float(_)) => rhs_ty, |
21 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => rhs_ty, | 23 | Ty::InferenceVar(_, TyVariableKind::Integer) |
24 | | Ty::InferenceVar(_, TyVariableKind::Float) => rhs_ty, | ||
22 | _ => Ty::Unknown, | 25 | _ => Ty::Unknown, |
23 | }, | 26 | }, |
24 | } | 27 | } |
@@ -30,7 +33,8 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { | |||
30 | BinaryOp::Assignment { op: None } => lhs_ty, | 33 | BinaryOp::Assignment { op: None } => lhs_ty, |
31 | BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty { | 34 | BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty { |
32 | Ty::Scalar(_) | Ty::Str => lhs_ty, | 35 | Ty::Scalar(_) | Ty::Str => lhs_ty, |
33 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, | 36 | Ty::InferenceVar(_, TyVariableKind::Integer) |
37 | | Ty::InferenceVar(_, TyVariableKind::Float) => lhs_ty, | ||
34 | _ => Ty::Unknown, | 38 | _ => Ty::Unknown, |
35 | }, | 39 | }, |
36 | BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => Ty::Unknown, | 40 | BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => Ty::Unknown, |
@@ -40,7 +44,8 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { | |||
40 | Ty::Scalar(Scalar::Int(_)) | 44 | Ty::Scalar(Scalar::Int(_)) |
41 | | Ty::Scalar(Scalar::Uint(_)) | 45 | | Ty::Scalar(Scalar::Uint(_)) |
42 | | Ty::Scalar(Scalar::Float(_)) => lhs_ty, | 46 | | Ty::Scalar(Scalar::Float(_)) => lhs_ty, |
43 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, | 47 | Ty::InferenceVar(_, TyVariableKind::Integer) |
48 | | Ty::InferenceVar(_, TyVariableKind::Float) => lhs_ty, | ||
44 | _ => Ty::Unknown, | 49 | _ => Ty::Unknown, |
45 | }, | 50 | }, |
46 | } | 51 | } |
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 60d74e21a..995ff6a9a 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs | |||
@@ -17,7 +17,7 @@ use crate::{ | |||
17 | primitive::UintTy, | 17 | primitive::UintTy, |
18 | traits::{Canonical, Obligation}, | 18 | traits::{Canonical, Obligation}, |
19 | CallableDefId, FnPointer, FnSig, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, | 19 | CallableDefId, FnPointer, FnSig, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, |
20 | ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty, TyKind, | 20 | ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty, |
21 | }; | 21 | }; |
22 | 22 | ||
23 | use super::interner::*; | 23 | use super::interner::*; |
@@ -107,7 +107,7 @@ impl ToChalk for Ty { | |||
107 | .to_ty::<Interner>(&Interner) | 107 | .to_ty::<Interner>(&Interner) |
108 | } | 108 | } |
109 | Ty::Bound(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner), | 109 | Ty::Bound(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner), |
110 | Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), | 110 | Ty::InferenceVar(..) => panic!("uncanonicalized infer ty"), |
111 | Ty::Dyn(predicates) => { | 111 | Ty::Dyn(predicates) => { |
112 | let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( | 112 | let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( |
113 | &Interner, | 113 | &Interner, |
@@ -532,20 +532,12 @@ where | |||
532 | type Chalk = chalk_ir::Canonical<T::Chalk>; | 532 | type Chalk = chalk_ir::Canonical<T::Chalk>; |
533 | 533 | ||
534 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> { | 534 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> { |
535 | let kinds = self | 535 | let kinds = self.kinds.iter().map(|&tk| { |
536 | .kinds | 536 | chalk_ir::CanonicalVarKind::new( |
537 | .iter() | 537 | chalk_ir::VariableKind::Ty(tk), |
538 | .map(|k| match k { | 538 | chalk_ir::UniverseIndex::ROOT, |
539 | TyKind::General => chalk_ir::TyVariableKind::General, | 539 | ) |
540 | TyKind::Integer => chalk_ir::TyVariableKind::Integer, | 540 | }); |
541 | TyKind::Float => chalk_ir::TyVariableKind::Float, | ||
542 | }) | ||
543 | .map(|tk| { | ||
544 | chalk_ir::CanonicalVarKind::new( | ||
545 | chalk_ir::VariableKind::Ty(tk), | ||
546 | chalk_ir::UniverseIndex::ROOT, | ||
547 | ) | ||
548 | }); | ||
549 | let value = self.value.to_chalk(db); | 541 | let value = self.value.to_chalk(db); |
550 | chalk_ir::Canonical { | 542 | chalk_ir::Canonical { |
551 | value, | 543 | value, |
@@ -558,17 +550,13 @@ where | |||
558 | .binders | 550 | .binders |
559 | .iter(&Interner) | 551 | .iter(&Interner) |
560 | .map(|k| match k.kind { | 552 | .map(|k| match k.kind { |
561 | chalk_ir::VariableKind::Ty(tk) => match tk { | 553 | chalk_ir::VariableKind::Ty(tk) => tk, |
562 | chalk_ir::TyVariableKind::General => TyKind::General, | ||
563 | chalk_ir::TyVariableKind::Integer => TyKind::Integer, | ||
564 | chalk_ir::TyVariableKind::Float => TyKind::Float, | ||
565 | }, | ||
566 | // HACK: Chalk can sometimes return new lifetime variables. We | 554 | // HACK: Chalk can sometimes return new lifetime variables. We |
567 | // want to just skip them, but to not mess up the indices of | 555 | // want to just skip them, but to not mess up the indices of |
568 | // other variables, we'll just create a new type variable in | 556 | // other variables, we'll just create a new type variable in |
569 | // their place instead. This should not matter (we never see the | 557 | // their place instead. This should not matter (we never see the |
570 | // actual *uses* of the lifetime variable). | 558 | // actual *uses* of the lifetime variable). |
571 | chalk_ir::VariableKind::Lifetime => TyKind::General, | 559 | chalk_ir::VariableKind::Lifetime => chalk_ir::TyVariableKind::General, |
572 | chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"), | 560 | chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"), |
573 | }) | 561 | }) |
574 | .collect(); | 562 | .collect(); |