diff options
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 87 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 280 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 34 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 200 |
4 files changed, 319 insertions, 282 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 32c7c57cd..cf0a3add4 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 hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; | 7 | use chalk_ir::{Mutability, TyVariableKind}; |
8 | use hir_def::lang_item::LangItemTarget; | ||
8 | use test_utils::mark; | 9 | use test_utils::mark; |
9 | 10 | ||
10 | use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty, TypeCtor}; | 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 |
@@ -33,7 +34,7 @@ impl<'a> InferenceContext<'a> { | |||
33 | } else if self.coerce(ty2, ty1) { | 34 | } else if self.coerce(ty2, ty1) { |
34 | ty1.clone() | 35 | ty1.clone() |
35 | } else { | 36 | } else { |
36 | if let (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnDef(_))) = (ty1, ty2) { | 37 | if let (Ty::FnDef(..), Ty::FnDef(..)) = (ty1, ty2) { |
37 | mark::hit!(coerce_fn_reification); | 38 | mark::hit!(coerce_fn_reification); |
38 | // Special case: two function types. Try to coerce both to | 39 | // Special case: two function types. Try to coerce both to |
39 | // pointers to have a chance at getting a match. See | 40 | // pointers to have a chance at getting a match. See |
@@ -53,12 +54,11 @@ 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_app!(TypeCtor::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_app!(TypeCtor::Never), _) => return true, | 61 | (Ty::Never, _) => return true, |
62 | 62 | ||
63 | // Trivial cases, this should go after `never` check to | 63 | // Trivial cases, this should go after `never` check to |
64 | // avoid infer result type to be never | 64 | // avoid infer result type to be never |
@@ -71,38 +71,33 @@ impl<'a> InferenceContext<'a> { | |||
71 | 71 | ||
72 | // Pointer weakening and function to pointer | 72 | // Pointer weakening and function to pointer |
73 | match (&mut from_ty, to_ty) { | 73 | match (&mut from_ty, to_ty) { |
74 | // `*mut T`, `&mut T, `&T`` -> `*const T` | 74 | // `*mut T` -> `*const T` |
75 | // `&mut T` -> `&T` | 75 | // `&mut T` -> `&T` |
76 | // `&mut T` -> `*mut T` | 76 | (Ty::Raw(m1, ..), Ty::Raw(m2 @ Mutability::Not, ..)) |
77 | (ty_app!(c1@TypeCtor::RawPtr(_)), ty_app!(c2@TypeCtor::RawPtr(Mutability::Shared))) | 77 | | (Ty::Ref(m1, ..), Ty::Ref(m2 @ Mutability::Not, ..)) => { |
78 | | (ty_app!(c1@TypeCtor::Ref(_)), ty_app!(c2@TypeCtor::RawPtr(Mutability::Shared))) | 78 | *m1 = *m2; |
79 | | (ty_app!(c1@TypeCtor::Ref(_)), ty_app!(c2@TypeCtor::Ref(Mutability::Shared))) | 79 | } |
80 | | (ty_app!(c1@TypeCtor::Ref(Mutability::Mut)), ty_app!(c2@TypeCtor::RawPtr(_))) => { | 80 | // `&T` -> `*const T` |
81 | *c1 = *c2; | 81 | // `&mut T` -> `*mut T`/`*const T` |
82 | (Ty::Ref(.., substs), &Ty::Raw(m2 @ Mutability::Not, ..)) | ||
83 | | (Ty::Ref(Mutability::Mut, substs), &Ty::Raw(m2, ..)) => { | ||
84 | from_ty = Ty::Raw(m2, substs.clone()); | ||
82 | } | 85 | } |
83 | 86 | ||
84 | // Illegal mutablity conversion | 87 | // Illegal mutability conversion |
85 | ( | 88 | (Ty::Raw(Mutability::Not, ..), Ty::Raw(Mutability::Mut, ..)) |
86 | ty_app!(TypeCtor::RawPtr(Mutability::Shared)), | 89 | | (Ty::Ref(Mutability::Not, ..), Ty::Ref(Mutability::Mut, ..)) => return false, |
87 | ty_app!(TypeCtor::RawPtr(Mutability::Mut)), | ||
88 | ) | ||
89 | | ( | ||
90 | ty_app!(TypeCtor::Ref(Mutability::Shared)), | ||
91 | ty_app!(TypeCtor::Ref(Mutability::Mut)), | ||
92 | ) => return false, | ||
93 | 90 | ||
94 | // `{function_type}` -> `fn()` | 91 | // `{function_type}` -> `fn()` |
95 | (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnPtr { .. })) => { | 92 | (Ty::FnDef(..), Ty::Function { .. }) => match from_ty.callable_sig(self.db) { |
96 | match from_ty.callable_sig(self.db) { | 93 | None => return false, |
97 | None => return false, | 94 | Some(sig) => { |
98 | Some(sig) => { | 95 | from_ty = Ty::fn_ptr(sig); |
99 | from_ty = Ty::fn_ptr(sig); | ||
100 | } | ||
101 | } | 96 | } |
102 | } | 97 | }, |
103 | 98 | ||
104 | (ty_app!(TypeCtor::Closure { .. }, params), ty_app!(TypeCtor::FnPtr { .. })) => { | 99 | (Ty::Closure(.., substs), Ty::Function { .. }) => { |
105 | from_ty = params[0].clone(); | 100 | from_ty = substs[0].clone(); |
106 | } | 101 | } |
107 | 102 | ||
108 | _ => {} | 103 | _ => {} |
@@ -115,9 +110,7 @@ impl<'a> InferenceContext<'a> { | |||
115 | // Auto Deref if cannot coerce | 110 | // Auto Deref if cannot coerce |
116 | match (&from_ty, to_ty) { | 111 | match (&from_ty, to_ty) { |
117 | // FIXME: DerefMut | 112 | // FIXME: DerefMut |
118 | (ty_app!(TypeCtor::Ref(_), st1), ty_app!(TypeCtor::Ref(_), st2)) => { | 113 | (Ty::Ref(_, st1), Ty::Ref(_, st2)) => self.unify_autoderef_behind_ref(&st1[0], &st2[0]), |
119 | self.unify_autoderef_behind_ref(&st1[0], &st2[0]) | ||
120 | } | ||
121 | 114 | ||
122 | // Otherwise, normal unify | 115 | // Otherwise, normal unify |
123 | _ => self.unify(&from_ty, to_ty), | 116 | _ => self.unify(&from_ty, to_ty), |
@@ -178,17 +171,17 @@ impl<'a> InferenceContext<'a> { | |||
178 | }, | 171 | }, |
179 | ) { | 172 | ) { |
180 | let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); | 173 | let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); |
181 | match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) { | 174 | let from_ty = self.resolve_ty_shallow(&derefed_ty); |
182 | // Stop when constructor matches. | 175 | // Stop when constructor matches. |
183 | (ty_app!(from_ctor, st1), ty_app!(to_ctor, st2)) if from_ctor == to_ctor => { | 176 | if from_ty.equals_ctor(&to_ty) { |
184 | // It will not recurse to `coerce`. | 177 | // It will not recurse to `coerce`. |
185 | return self.table.unify_substs(st1, st2, 0); | 178 | return match (from_ty.substs(), to_ty.substs()) { |
186 | } | 179 | (Some(st1), Some(st2)) => self.table.unify_substs(st1, st2, 0), |
187 | _ => { | 180 | (None, None) => true, |
188 | if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { | 181 | _ => false, |
189 | return true; | 182 | }; |
190 | } | 183 | } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { |
191 | } | 184 | return true; |
192 | } | 185 | } |
193 | } | 186 | } |
194 | 187 | ||
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 9bf3b51b0..cf1f1038a 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -3,8 +3,8 @@ | |||
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::{Mutability, TyVariableKind}; | ||
6 | use hir_def::{ | 7 | use hir_def::{ |
7 | builtin_type::Signedness, | ||
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}, |
10 | resolver::resolver_for_expr, | 10 | resolver::resolver_for_expr, |
@@ -15,11 +15,14 @@ use syntax::ast::RangeOp; | |||
15 | use test_utils::mark; | 15 | use test_utils::mark; |
16 | 16 | ||
17 | use crate::{ | 17 | use crate::{ |
18 | autoderef, method_resolution, op, | 18 | autoderef, |
19 | lower::lower_to_chalk_mutability, | ||
20 | method_resolution, op, | ||
21 | primitive::{self, UintTy}, | ||
19 | traits::{FnTrait, InEnvironment}, | 22 | traits::{FnTrait, InEnvironment}, |
20 | utils::{generics, variant_data, Generics}, | 23 | utils::{generics, variant_data, Generics}, |
21 | ApplicationTy, Binders, CallableDefId, InferTy, IntTy, Mutability, Obligation, OpaqueTyId, | 24 | Binders, CallableDefId, FnPointer, FnSig, Obligation, OpaqueTyId, Rawness, Scalar, Substs, |
22 | Rawness, Substs, TraitRef, Ty, TypeCtor, | 25 | TraitRef, Ty, |
23 | }; | 26 | }; |
24 | 27 | ||
25 | use super::{ | 28 | use super::{ |
@@ -82,10 +85,7 @@ impl<'a> InferenceContext<'a> { | |||
82 | arg_tys.push(arg); | 85 | arg_tys.push(arg); |
83 | } | 86 | } |
84 | let parameters = param_builder.build(); | 87 | let parameters = param_builder.build(); |
85 | let arg_ty = Ty::Apply(ApplicationTy { | 88 | let arg_ty = Ty::Tuple(num_args, parameters); |
86 | ctor: TypeCtor::Tuple { cardinality: num_args as u16 }, | ||
87 | parameters, | ||
88 | }); | ||
89 | let substs = | 89 | let substs = |
90 | Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); | 90 | Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); |
91 | 91 | ||
@@ -120,7 +120,7 @@ impl<'a> InferenceContext<'a> { | |||
120 | Expr::Missing => Ty::Unknown, | 120 | Expr::Missing => Ty::Unknown, |
121 | Expr::If { condition, then_branch, else_branch } => { | 121 | Expr::If { condition, then_branch, else_branch } => { |
122 | // if let is desugared to match, so this is always simple if | 122 | // if let is desugared to match, so this is always simple if |
123 | self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); | 123 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); |
124 | 124 | ||
125 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); | 125 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); |
126 | let mut both_arms_diverge = Diverges::Always; | 126 | let mut both_arms_diverge = Diverges::Always; |
@@ -137,24 +137,33 @@ impl<'a> InferenceContext<'a> { | |||
137 | 137 | ||
138 | self.coerce_merge_branch(&then_ty, &else_ty) | 138 | self.coerce_merge_branch(&then_ty, &else_ty) |
139 | } | 139 | } |
140 | Expr::Block { statements, tail, label } => match label { | 140 | Expr::Block { statements, tail, label, id: _ } => { |
141 | Some(_) => { | 141 | let old_resolver = mem::replace( |
142 | let break_ty = self.table.new_type_var(); | 142 | &mut self.resolver, |
143 | self.breakables.push(BreakableContext { | 143 | resolver_for_expr(self.db.upcast(), self.owner, tgt_expr), |
144 | may_break: false, | 144 | ); |
145 | break_ty: break_ty.clone(), | 145 | let ty = match label { |
146 | label: label.map(|label| self.body[label].name.clone()), | 146 | Some(_) => { |
147 | }); | 147 | let break_ty = self.table.new_type_var(); |
148 | let ty = self.infer_block(statements, *tail, &Expectation::has_type(break_ty)); | 148 | self.breakables.push(BreakableContext { |
149 | let ctxt = self.breakables.pop().expect("breakable stack broken"); | 149 | may_break: false, |
150 | if ctxt.may_break { | 150 | break_ty: break_ty.clone(), |
151 | ctxt.break_ty | 151 | label: label.map(|label| self.body[label].name.clone()), |
152 | } else { | 152 | }); |
153 | ty | 153 | let ty = |
154 | self.infer_block(statements, *tail, &Expectation::has_type(break_ty)); | ||
155 | let ctxt = self.breakables.pop().expect("breakable stack broken"); | ||
156 | if ctxt.may_break { | ||
157 | ctxt.break_ty | ||
158 | } else { | ||
159 | ty | ||
160 | } | ||
154 | } | 161 | } |
155 | } | 162 | None => self.infer_block(statements, *tail, expected), |
156 | None => self.infer_block(statements, *tail, expected), | 163 | }; |
157 | }, | 164 | self.resolver = old_resolver; |
165 | ty | ||
166 | } | ||
158 | Expr::Unsafe { body } | Expr::Const { body } => self.infer_expr(*body, expected), | 167 | Expr::Unsafe { body } | Expr::Const { body } => self.infer_expr(*body, expected), |
159 | Expr::TryBlock { body } => { | 168 | Expr::TryBlock { body } => { |
160 | let _inner = self.infer_expr(*body, expected); | 169 | let _inner = self.infer_expr(*body, expected); |
@@ -166,7 +175,7 @@ impl<'a> InferenceContext<'a> { | |||
166 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> | 175 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> |
167 | let inner_ty = self.infer_expr(*body, &Expectation::none()); | 176 | let inner_ty = self.infer_expr(*body, &Expectation::none()); |
168 | let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); | 177 | let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); |
169 | Ty::apply_one(TypeCtor::OpaqueType(opaque_ty_id), inner_ty) | 178 | Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty)) |
170 | } | 179 | } |
171 | Expr::Loop { body, label } => { | 180 | Expr::Loop { body, label } => { |
172 | self.breakables.push(BreakableContext { | 181 | self.breakables.push(BreakableContext { |
@@ -184,7 +193,7 @@ impl<'a> InferenceContext<'a> { | |||
184 | if ctxt.may_break { | 193 | if ctxt.may_break { |
185 | ctxt.break_ty | 194 | ctxt.break_ty |
186 | } else { | 195 | } else { |
187 | Ty::simple(TypeCtor::Never) | 196 | Ty::Never |
188 | } | 197 | } |
189 | } | 198 | } |
190 | Expr::While { condition, body, label } => { | 199 | Expr::While { condition, body, label } => { |
@@ -194,7 +203,7 @@ impl<'a> InferenceContext<'a> { | |||
194 | label: label.map(|label| self.body[label].name.clone()), | 203 | label: label.map(|label| self.body[label].name.clone()), |
195 | }); | 204 | }); |
196 | // while let is desugared to a match loop, so this is always simple while | 205 | // while let is desugared to a match loop, so this is always simple while |
197 | self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); | 206 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); |
198 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 207 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
199 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); | 208 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); |
200 | // the body may not run, so it diverging doesn't mean we diverge | 209 | // the body may not run, so it diverging doesn't mean we diverge |
@@ -241,12 +250,12 @@ impl<'a> InferenceContext<'a> { | |||
241 | None => self.table.new_type_var(), | 250 | None => self.table.new_type_var(), |
242 | }; | 251 | }; |
243 | sig_tys.push(ret_ty.clone()); | 252 | sig_tys.push(ret_ty.clone()); |
244 | let sig_ty = Ty::apply( | 253 | let sig_ty = Ty::Function(FnPointer { |
245 | TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1, is_varargs: false }, | 254 | num_args: sig_tys.len() - 1, |
246 | Substs(sig_tys.clone().into()), | 255 | sig: FnSig { variadic: false }, |
247 | ); | 256 | substs: Substs(sig_tys.clone().into()), |
248 | let closure_ty = | 257 | }); |
249 | Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); | 258 | let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty)); |
250 | 259 | ||
251 | // Eagerly try to relate the closure type with the expected | 260 | // Eagerly try to relate the closure type with the expected |
252 | // type, otherwise we often won't have enough information to | 261 | // type, otherwise we often won't have enough information to |
@@ -297,11 +306,8 @@ impl<'a> InferenceContext<'a> { | |||
297 | Expr::Match { expr, arms } => { | 306 | Expr::Match { expr, arms } => { |
298 | let input_ty = self.infer_expr(*expr, &Expectation::none()); | 307 | let input_ty = self.infer_expr(*expr, &Expectation::none()); |
299 | 308 | ||
300 | let mut result_ty = if arms.is_empty() { | 309 | let mut result_ty = |
301 | Ty::simple(TypeCtor::Never) | 310 | if arms.is_empty() { Ty::Never } else { self.table.new_type_var() }; |
302 | } else { | ||
303 | self.table.new_type_var() | ||
304 | }; | ||
305 | 311 | ||
306 | let matchee_diverges = self.diverges; | 312 | let matchee_diverges = self.diverges; |
307 | let mut all_arms_diverge = Diverges::Always; | 313 | let mut all_arms_diverge = Diverges::Always; |
@@ -312,7 +318,7 @@ impl<'a> InferenceContext<'a> { | |||
312 | if let Some(guard_expr) = arm.guard { | 318 | if let Some(guard_expr) = arm.guard { |
313 | self.infer_expr( | 319 | self.infer_expr( |
314 | guard_expr, | 320 | guard_expr, |
315 | &Expectation::has_type(Ty::simple(TypeCtor::Bool)), | 321 | &Expectation::has_type(Ty::Scalar(Scalar::Bool)), |
316 | ); | 322 | ); |
317 | } | 323 | } |
318 | 324 | ||
@@ -330,7 +336,7 @@ impl<'a> InferenceContext<'a> { | |||
330 | let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); | 336 | let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); |
331 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) | 337 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) |
332 | } | 338 | } |
333 | Expr::Continue { .. } => Ty::simple(TypeCtor::Never), | 339 | Expr::Continue { .. } => Ty::Never, |
334 | Expr::Break { expr, label } => { | 340 | Expr::Break { expr, label } => { |
335 | let val_ty = if let Some(expr) = expr { | 341 | let val_ty = if let Some(expr) = expr { |
336 | self.infer_expr(*expr, &Expectation::none()) | 342 | self.infer_expr(*expr, &Expectation::none()) |
@@ -355,8 +361,7 @@ impl<'a> InferenceContext<'a> { | |||
355 | expr: tgt_expr, | 361 | expr: tgt_expr, |
356 | }); | 362 | }); |
357 | } | 363 | } |
358 | 364 | Ty::Never | |
359 | Ty::simple(TypeCtor::Never) | ||
360 | } | 365 | } |
361 | Expr::Return { expr } => { | 366 | Expr::Return { expr } => { |
362 | if let Some(expr) = expr { | 367 | if let Some(expr) = expr { |
@@ -365,14 +370,14 @@ impl<'a> InferenceContext<'a> { | |||
365 | let unit = Ty::unit(); | 370 | let unit = Ty::unit(); |
366 | self.coerce(&unit, &self.return_ty.clone()); | 371 | self.coerce(&unit, &self.return_ty.clone()); |
367 | } | 372 | } |
368 | Ty::simple(TypeCtor::Never) | 373 | Ty::Never |
369 | } | 374 | } |
370 | Expr::Yield { expr } => { | 375 | Expr::Yield { expr } => { |
371 | // FIXME: track yield type for coercion | 376 | // FIXME: track yield type for coercion |
372 | if let Some(expr) = expr { | 377 | if let Some(expr) = expr { |
373 | self.infer_expr(*expr, &Expectation::none()); | 378 | self.infer_expr(*expr, &Expectation::none()); |
374 | } | 379 | } |
375 | Ty::simple(TypeCtor::Never) | 380 | Ty::Never |
376 | } | 381 | } |
377 | Expr::RecordLit { path, fields, spread } => { | 382 | Expr::RecordLit { path, fields, spread } => { |
378 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 383 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
@@ -382,7 +387,7 @@ impl<'a> InferenceContext<'a> { | |||
382 | 387 | ||
383 | self.unify(&ty, &expected.ty); | 388 | self.unify(&ty, &expected.ty); |
384 | 389 | ||
385 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 390 | let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); |
386 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); | 391 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); |
387 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); | 392 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); |
388 | for (field_idx, field) in fields.iter().enumerate() { | 393 | for (field_idx, field) in fields.iter().enumerate() { |
@@ -421,30 +426,23 @@ impl<'a> InferenceContext<'a> { | |||
421 | }, | 426 | }, |
422 | ) | 427 | ) |
423 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { | 428 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { |
424 | Ty::Apply(a_ty) => match a_ty.ctor { | 429 | Ty::Tuple(_, substs) => { |
425 | TypeCtor::Tuple { .. } => name | 430 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) |
426 | .as_tuple_index() | 431 | } |
427 | .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), | 432 | Ty::Adt(AdtId::StructId(s), parameters) => { |
428 | TypeCtor::Adt(AdtId::StructId(s)) => { | 433 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { |
429 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { | 434 | let field = FieldId { parent: s.into(), local_id }; |
430 | let field = FieldId { parent: s.into(), local_id }; | 435 | self.write_field_resolution(tgt_expr, field); |
431 | self.write_field_resolution(tgt_expr, field); | 436 | self.db.field_types(s.into())[field.local_id].clone().subst(¶meters) |
432 | self.db.field_types(s.into())[field.local_id] | 437 | }) |
433 | .clone() | 438 | } |
434 | .subst(&a_ty.parameters) | 439 | Ty::Adt(AdtId::UnionId(u), parameters) => { |
435 | }) | 440 | self.db.union_data(u).variant_data.field(name).map(|local_id| { |
436 | } | 441 | let field = FieldId { parent: u.into(), local_id }; |
437 | TypeCtor::Adt(AdtId::UnionId(u)) => { | 442 | self.write_field_resolution(tgt_expr, field); |
438 | self.db.union_data(u).variant_data.field(name).map(|local_id| { | 443 | self.db.field_types(u.into())[field.local_id].clone().subst(¶meters) |
439 | let field = FieldId { parent: u.into(), local_id }; | 444 | }) |
440 | self.write_field_resolution(tgt_expr, field); | 445 | } |
441 | self.db.field_types(u.into())[field.local_id] | ||
442 | .clone() | ||
443 | .subst(&a_ty.parameters) | ||
444 | }) | ||
445 | } | ||
446 | _ => None, | ||
447 | }, | ||
448 | _ => None, | 446 | _ => None, |
449 | }) | 447 | }) |
450 | .unwrap_or(Ty::Unknown); | 448 | .unwrap_or(Ty::Unknown); |
@@ -466,10 +464,11 @@ impl<'a> InferenceContext<'a> { | |||
466 | cast_ty | 464 | cast_ty |
467 | } | 465 | } |
468 | Expr::Ref { expr, rawness, mutability } => { | 466 | Expr::Ref { expr, rawness, mutability } => { |
467 | let mutability = lower_to_chalk_mutability(*mutability); | ||
469 | let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = | 468 | let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = |
470 | &expected.ty.as_reference_or_ptr() | 469 | &expected.ty.as_reference_or_ptr() |
471 | { | 470 | { |
472 | if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared { | 471 | if *exp_mutability == Mutability::Mut && mutability == Mutability::Not { |
473 | // FIXME: throw type error - expected mut reference but found shared ref, | 472 | // FIXME: throw type error - expected mut reference but found shared ref, |
474 | // which cannot be coerced | 473 | // which cannot be coerced |
475 | } | 474 | } |
@@ -482,16 +481,24 @@ impl<'a> InferenceContext<'a> { | |||
482 | Expectation::none() | 481 | Expectation::none() |
483 | }; | 482 | }; |
484 | let inner_ty = self.infer_expr_inner(*expr, &expectation); | 483 | let inner_ty = self.infer_expr_inner(*expr, &expectation); |
485 | let ty = match rawness { | 484 | match rawness { |
486 | Rawness::RawPtr => TypeCtor::RawPtr(*mutability), | 485 | Rawness::RawPtr => Ty::Raw(mutability, Substs::single(inner_ty)), |
487 | Rawness::Ref => TypeCtor::Ref(*mutability), | 486 | Rawness::Ref => Ty::Ref(mutability, Substs::single(inner_ty)), |
488 | }; | 487 | } |
489 | Ty::apply_one(ty, inner_ty) | ||
490 | } | 488 | } |
491 | Expr::Box { expr } => { | 489 | Expr::Box { expr } => { |
492 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 490 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
493 | if let Some(box_) = self.resolve_boxed_box() { | 491 | if let Some(box_) = self.resolve_boxed_box() { |
494 | Ty::apply_one(TypeCtor::Adt(box_), inner_ty) | 492 | let mut sb = Substs::builder(generics(self.db.upcast(), box_.into()).len()); |
493 | sb = sb.push(inner_ty); | ||
494 | match self.db.generic_defaults(box_.into()).as_ref() { | ||
495 | [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => { | ||
496 | sb = sb.push(alloc_ty.value.clone()); | ||
497 | } | ||
498 | _ => (), | ||
499 | } | ||
500 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); | ||
501 | Ty::Adt(box_, sb.build()) | ||
495 | } else { | 502 | } else { |
496 | Ty::Unknown | 503 | Ty::Unknown |
497 | } | 504 | } |
@@ -521,13 +528,11 @@ impl<'a> InferenceContext<'a> { | |||
521 | UnaryOp::Neg => { | 528 | UnaryOp::Neg => { |
522 | match &inner_ty { | 529 | match &inner_ty { |
523 | // Fast path for builtins | 530 | // Fast path for builtins |
524 | Ty::Apply(ApplicationTy { | 531 | Ty::Scalar(Scalar::Int(_)) |
525 | ctor: TypeCtor::Int(IntTy { signedness: Signedness::Signed, .. }), | 532 | | Ty::Scalar(Scalar::Uint(_)) |
526 | .. | 533 | | Ty::Scalar(Scalar::Float(_)) |
527 | }) | 534 | | Ty::InferenceVar(_, TyVariableKind::Integer) |
528 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. }) | 535 | | Ty::InferenceVar(_, TyVariableKind::Float) => inner_ty, |
529 | | Ty::Infer(InferTy::IntVar(..)) | ||
530 | | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, | ||
531 | // Otherwise we resolve via the std::ops::Neg trait | 536 | // Otherwise we resolve via the std::ops::Neg trait |
532 | _ => self | 537 | _ => self |
533 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), | 538 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), |
@@ -536,9 +541,10 @@ impl<'a> InferenceContext<'a> { | |||
536 | UnaryOp::Not => { | 541 | UnaryOp::Not => { |
537 | match &inner_ty { | 542 | match &inner_ty { |
538 | // Fast path for builtins | 543 | // Fast path for builtins |
539 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }) | 544 | Ty::Scalar(Scalar::Bool) |
540 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(_), .. }) | 545 | | Ty::Scalar(Scalar::Int(_)) |
541 | | Ty::Infer(InferTy::IntVar(..)) => inner_ty, | 546 | | Ty::Scalar(Scalar::Uint(_)) |
547 | | Ty::InferenceVar(_, TyVariableKind::Integer) => inner_ty, | ||
542 | // Otherwise we resolve via the std::ops::Not trait | 548 | // Otherwise we resolve via the std::ops::Not trait |
543 | _ => self | 549 | _ => self |
544 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), | 550 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), |
@@ -549,7 +555,7 @@ impl<'a> InferenceContext<'a> { | |||
549 | Expr::BinaryOp { lhs, rhs, op } => match op { | 555 | Expr::BinaryOp { lhs, rhs, op } => match op { |
550 | Some(op) => { | 556 | Some(op) => { |
551 | let lhs_expectation = match op { | 557 | let lhs_expectation = match op { |
552 | BinaryOp::LogicOp(..) => Expectation::has_type(Ty::simple(TypeCtor::Bool)), | 558 | BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)), |
553 | _ => Expectation::none(), | 559 | _ => Expectation::none(), |
554 | }; | 560 | }; |
555 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); | 561 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); |
@@ -580,31 +586,31 @@ impl<'a> InferenceContext<'a> { | |||
580 | let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); | 586 | let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); |
581 | match (range_type, lhs_ty, rhs_ty) { | 587 | match (range_type, lhs_ty, rhs_ty) { |
582 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { | 588 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { |
583 | Some(adt) => Ty::simple(TypeCtor::Adt(adt)), | 589 | Some(adt) => Ty::Adt(adt, Substs::empty()), |
584 | None => Ty::Unknown, | 590 | None => Ty::Unknown, |
585 | }, | 591 | }, |
586 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { | 592 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { |
587 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 593 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
588 | None => Ty::Unknown, | 594 | None => Ty::Unknown, |
589 | }, | 595 | }, |
590 | (RangeOp::Inclusive, None, Some(ty)) => { | 596 | (RangeOp::Inclusive, None, Some(ty)) => { |
591 | match self.resolve_range_to_inclusive() { | 597 | match self.resolve_range_to_inclusive() { |
592 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 598 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
593 | None => Ty::Unknown, | 599 | None => Ty::Unknown, |
594 | } | 600 | } |
595 | } | 601 | } |
596 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { | 602 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { |
597 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 603 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
598 | None => Ty::Unknown, | 604 | None => Ty::Unknown, |
599 | }, | 605 | }, |
600 | (RangeOp::Inclusive, Some(_), Some(ty)) => { | 606 | (RangeOp::Inclusive, Some(_), Some(ty)) => { |
601 | match self.resolve_range_inclusive() { | 607 | match self.resolve_range_inclusive() { |
602 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 608 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
603 | None => Ty::Unknown, | 609 | None => Ty::Unknown, |
604 | } | 610 | } |
605 | } | 611 | } |
606 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { | 612 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { |
607 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 613 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
608 | None => Ty::Unknown, | 614 | None => Ty::Unknown, |
609 | }, | 615 | }, |
610 | (RangeOp::Inclusive, _, None) => Ty::Unknown, | 616 | (RangeOp::Inclusive, _, None) => Ty::Unknown, |
@@ -638,7 +644,7 @@ impl<'a> InferenceContext<'a> { | |||
638 | } | 644 | } |
639 | Expr::Tuple { exprs } => { | 645 | Expr::Tuple { exprs } => { |
640 | let mut tys = match &expected.ty { | 646 | let mut tys = match &expected.ty { |
641 | ty_app!(TypeCtor::Tuple { .. }, st) => st | 647 | Ty::Tuple(_, substs) => substs |
642 | .iter() | 648 | .iter() |
643 | .cloned() | 649 | .cloned() |
644 | .chain(repeat_with(|| self.table.new_type_var())) | 650 | .chain(repeat_with(|| self.table.new_type_var())) |
@@ -651,15 +657,11 @@ impl<'a> InferenceContext<'a> { | |||
651 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); | 657 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); |
652 | } | 658 | } |
653 | 659 | ||
654 | Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into())) | 660 | Ty::Tuple(tys.len(), Substs(tys.into())) |
655 | } | 661 | } |
656 | Expr::Array(array) => { | 662 | Expr::Array(array) => { |
657 | let elem_ty = match &expected.ty { | 663 | let elem_ty = match &expected.ty { |
658 | // FIXME: remove when https://github.com/rust-lang/rust/issues/80501 is fixed | 664 | Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(), |
659 | #[allow(unreachable_patterns)] | ||
660 | ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => { | ||
661 | st.as_single().clone() | ||
662 | } | ||
663 | _ => self.table.new_type_var(), | 665 | _ => self.table.new_type_var(), |
664 | }; | 666 | }; |
665 | 667 | ||
@@ -676,30 +678,38 @@ impl<'a> InferenceContext<'a> { | |||
676 | ); | 678 | ); |
677 | self.infer_expr( | 679 | self.infer_expr( |
678 | *repeat, | 680 | *repeat, |
679 | &Expectation::has_type(Ty::simple(TypeCtor::Int(IntTy::usize()))), | 681 | &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))), |
680 | ); | 682 | ); |
681 | } | 683 | } |
682 | } | 684 | } |
683 | 685 | ||
684 | Ty::apply_one(TypeCtor::Array, elem_ty) | 686 | Ty::Array(Substs::single(elem_ty)) |
685 | } | 687 | } |
686 | Expr::Literal(lit) => match lit { | 688 | Expr::Literal(lit) => match lit { |
687 | Literal::Bool(..) => Ty::simple(TypeCtor::Bool), | 689 | Literal::Bool(..) => Ty::Scalar(Scalar::Bool), |
688 | Literal::String(..) => { | 690 | Literal::String(..) => Ty::Ref(Mutability::Not, Substs::single(Ty::Str)), |
689 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str)) | ||
690 | } | ||
691 | Literal::ByteString(..) => { | 691 | Literal::ByteString(..) => { |
692 | let byte_type = Ty::simple(TypeCtor::Int(IntTy::u8())); | 692 | let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8)); |
693 | let array_type = Ty::apply_one(TypeCtor::Array, byte_type); | 693 | let array_type = Ty::Array(Substs::single(byte_type)); |
694 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) | 694 | Ty::Ref(Mutability::Not, Substs::single(array_type)) |
695 | } | 695 | } |
696 | Literal::Char(..) => Ty::simple(TypeCtor::Char), | 696 | Literal::Char(..) => Ty::Scalar(Scalar::Char), |
697 | Literal::Int(_v, ty) => match ty { | 697 | Literal::Int(_v, ty) => match ty { |
698 | Some(int_ty) => Ty::simple(TypeCtor::Int((*int_ty).into())), | 698 | Some(int_ty) => { |
699 | Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty))) | ||
700 | } | ||
701 | None => self.table.new_integer_var(), | ||
702 | }, | ||
703 | Literal::Uint(_v, ty) => match ty { | ||
704 | Some(int_ty) => { | ||
705 | Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty))) | ||
706 | } | ||
699 | None => self.table.new_integer_var(), | 707 | None => self.table.new_integer_var(), |
700 | }, | 708 | }, |
701 | Literal::Float(_v, ty) => match ty { | 709 | Literal::Float(_v, ty) => match ty { |
702 | Some(float_ty) => Ty::simple(TypeCtor::Float((*float_ty).into())), | 710 | Some(float_ty) => { |
711 | Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty))) | ||
712 | } | ||
703 | None => self.table.new_float_var(), | 713 | None => self.table.new_float_var(), |
704 | }, | 714 | }, |
705 | }, | 715 | }, |
@@ -755,7 +765,7 @@ impl<'a> InferenceContext<'a> { | |||
755 | // `!`). | 765 | // `!`). |
756 | if self.diverges.is_always() { | 766 | if self.diverges.is_always() { |
757 | // we don't even make an attempt at coercion | 767 | // we don't even make an attempt at coercion |
758 | self.table.new_maybe_never_type_var() | 768 | self.table.new_maybe_never_var() |
759 | } else { | 769 | } else { |
760 | self.coerce(&Ty::unit(), expected.coercion_target()); | 770 | self.coerce(&Ty::unit(), expected.coercion_target()); |
761 | Ty::unit() | 771 | Ty::unit() |
@@ -812,7 +822,7 @@ impl<'a> InferenceContext<'a> { | |||
812 | // Apply autoref so the below unification works correctly | 822 | // Apply autoref so the below unification works correctly |
813 | // FIXME: return correct autorefs from lookup_method | 823 | // FIXME: return correct autorefs from lookup_method |
814 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { | 824 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { |
815 | Some((_, mutability)) => Ty::apply_one(TypeCtor::Ref(mutability), derefed_receiver_ty), | 825 | Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)), |
816 | _ => derefed_receiver_ty, | 826 | _ => derefed_receiver_ty, |
817 | }; | 827 | }; |
818 | self.unify(&expected_receiver_ty, &actual_receiver_ty); | 828 | self.unify(&expected_receiver_ty, &actual_receiver_ty); |
@@ -889,30 +899,26 @@ impl<'a> InferenceContext<'a> { | |||
889 | } | 899 | } |
890 | 900 | ||
891 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { | 901 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { |
892 | if let Ty::Apply(a_ty) = callable_ty { | 902 | if let &Ty::FnDef(def, ref parameters) = callable_ty { |
893 | if let TypeCtor::FnDef(def) = a_ty.ctor { | 903 | let generic_predicates = self.db.generic_predicates(def.into()); |
894 | let generic_predicates = self.db.generic_predicates(def.into()); | 904 | for predicate in generic_predicates.iter() { |
895 | for predicate in generic_predicates.iter() { | 905 | let predicate = predicate.clone().subst(parameters); |
896 | let predicate = predicate.clone().subst(&a_ty.parameters); | 906 | if let Some(obligation) = Obligation::from_predicate(predicate) { |
897 | if let Some(obligation) = Obligation::from_predicate(predicate) { | 907 | self.obligations.push(obligation); |
898 | self.obligations.push(obligation); | ||
899 | } | ||
900 | } | 908 | } |
901 | // add obligation for trait implementation, if this is a trait method | 909 | } |
902 | match def { | 910 | // add obligation for trait implementation, if this is a trait method |
903 | CallableDefId::FunctionId(f) => { | 911 | match def { |
904 | if let AssocContainerId::TraitId(trait_) = | 912 | CallableDefId::FunctionId(f) => { |
905 | f.lookup(self.db.upcast()).container | 913 | if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container |
906 | { | 914 | { |
907 | // construct a TraitDef | 915 | // construct a TraitDef |
908 | let substs = a_ty | 916 | let substs = |
909 | .parameters | 917 | parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); |
910 | .prefix(generics(self.db.upcast(), trait_.into()).len()); | 918 | self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); |
911 | self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); | ||
912 | } | ||
913 | } | 919 | } |
914 | CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {} | ||
915 | } | 920 | } |
921 | CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {} | ||
916 | } | 922 | } |
917 | } | 923 | } |
918 | } | 924 | } |
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index d974f805b..eb099311c 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs | |||
@@ -3,17 +3,17 @@ | |||
3 | use std::iter::repeat; | 3 | use std::iter::repeat; |
4 | use std::sync::Arc; | 4 | use std::sync::Arc; |
5 | 5 | ||
6 | use chalk_ir::Mutability; | ||
6 | use hir_def::{ | 7 | use hir_def::{ |
7 | expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat}, | 8 | expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat}, |
8 | path::Path, | 9 | path::Path, |
9 | type_ref::Mutability, | ||
10 | FieldId, | 10 | FieldId, |
11 | }; | 11 | }; |
12 | use hir_expand::name::Name; | 12 | use hir_expand::name::Name; |
13 | use test_utils::mark; | 13 | use test_utils::mark; |
14 | 14 | ||
15 | use super::{BindingMode, Expectation, InferenceContext}; | 15 | use super::{BindingMode, Expectation, InferenceContext}; |
16 | use crate::{utils::variant_data, Substs, Ty, TypeCtor}; | 16 | use crate::{lower::lower_to_chalk_mutability, utils::variant_data, Substs, Ty}; |
17 | 17 | ||
18 | impl<'a> InferenceContext<'a> { | 18 | impl<'a> InferenceContext<'a> { |
19 | fn infer_tuple_struct_pat( | 19 | fn infer_tuple_struct_pat( |
@@ -32,7 +32,7 @@ impl<'a> InferenceContext<'a> { | |||
32 | } | 32 | } |
33 | self.unify(&ty, expected); | 33 | self.unify(&ty, expected); |
34 | 34 | ||
35 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 35 | let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); |
36 | 36 | ||
37 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); | 37 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); |
38 | let (pre, post) = match ellipsis { | 38 | let (pre, post) = match ellipsis { |
@@ -71,7 +71,7 @@ impl<'a> InferenceContext<'a> { | |||
71 | 71 | ||
72 | self.unify(&ty, expected); | 72 | self.unify(&ty, expected); |
73 | 73 | ||
74 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 74 | let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); |
75 | 75 | ||
76 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); | 76 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); |
77 | for subpat in subpats { | 77 | for subpat in subpats { |
@@ -103,7 +103,7 @@ impl<'a> InferenceContext<'a> { | |||
103 | expected = inner; | 103 | expected = inner; |
104 | default_bm = match default_bm { | 104 | default_bm = match default_bm { |
105 | BindingMode::Move => BindingMode::Ref(mutability), | 105 | BindingMode::Move => BindingMode::Ref(mutability), |
106 | BindingMode::Ref(Mutability::Shared) => BindingMode::Ref(Mutability::Shared), | 106 | BindingMode::Ref(Mutability::Not) => BindingMode::Ref(Mutability::Not), |
107 | BindingMode::Ref(Mutability::Mut) => BindingMode::Ref(mutability), | 107 | BindingMode::Ref(Mutability::Mut) => BindingMode::Ref(mutability), |
108 | } | 108 | } |
109 | } | 109 | } |
@@ -138,10 +138,7 @@ impl<'a> InferenceContext<'a> { | |||
138 | inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); | 138 | inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); |
139 | inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); | 139 | inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); |
140 | 140 | ||
141 | Ty::apply( | 141 | Ty::Tuple(inner_tys.len(), Substs(inner_tys.into())) |
142 | TypeCtor::Tuple { cardinality: inner_tys.len() as u16 }, | ||
143 | Substs(inner_tys.into()), | ||
144 | ) | ||
145 | } | 142 | } |
146 | Pat::Or(ref pats) => { | 143 | Pat::Or(ref pats) => { |
147 | if let Some((first_pat, rest)) = pats.split_first() { | 144 | if let Some((first_pat, rest)) = pats.split_first() { |
@@ -155,9 +152,10 @@ impl<'a> InferenceContext<'a> { | |||
155 | } | 152 | } |
156 | } | 153 | } |
157 | Pat::Ref { pat, mutability } => { | 154 | Pat::Ref { pat, mutability } => { |
155 | let mutability = lower_to_chalk_mutability(*mutability); | ||
158 | let expectation = match expected.as_reference() { | 156 | let expectation = match expected.as_reference() { |
159 | Some((inner_ty, exp_mut)) => { | 157 | Some((inner_ty, exp_mut)) => { |
160 | if *mutability != exp_mut { | 158 | if mutability != exp_mut { |
161 | // FIXME: emit type error? | 159 | // FIXME: emit type error? |
162 | } | 160 | } |
163 | inner_ty | 161 | inner_ty |
@@ -165,7 +163,7 @@ impl<'a> InferenceContext<'a> { | |||
165 | _ => &Ty::Unknown, | 163 | _ => &Ty::Unknown, |
166 | }; | 164 | }; |
167 | let subty = self.infer_pat(*pat, expectation, default_bm); | 165 | let subty = self.infer_pat(*pat, expectation, default_bm); |
168 | Ty::apply_one(TypeCtor::Ref(*mutability), subty) | 166 | Ty::Ref(mutability, Substs::single(subty)) |
169 | } | 167 | } |
170 | Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( | 168 | Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( |
171 | p.as_ref(), | 169 | p.as_ref(), |
@@ -198,7 +196,7 @@ impl<'a> InferenceContext<'a> { | |||
198 | 196 | ||
199 | let bound_ty = match mode { | 197 | let bound_ty = match mode { |
200 | BindingMode::Ref(mutability) => { | 198 | BindingMode::Ref(mutability) => { |
201 | Ty::apply_one(TypeCtor::Ref(mutability), inner_ty.clone()) | 199 | Ty::Ref(mutability, Substs::single(inner_ty.clone())) |
202 | } | 200 | } |
203 | BindingMode::Move => inner_ty.clone(), | 201 | BindingMode::Move => inner_ty.clone(), |
204 | }; | 202 | }; |
@@ -207,17 +205,17 @@ impl<'a> InferenceContext<'a> { | |||
207 | return inner_ty; | 205 | return inner_ty; |
208 | } | 206 | } |
209 | Pat::Slice { prefix, slice, suffix } => { | 207 | Pat::Slice { prefix, slice, suffix } => { |
210 | let (container_ty, elem_ty) = match &expected { | 208 | let (container_ty, elem_ty): (fn(_) -> _, _) = match &expected { |
211 | ty_app!(TypeCtor::Array, st) => (TypeCtor::Array, st.as_single().clone()), | 209 | Ty::Array(st) => (Ty::Array, st.as_single().clone()), |
212 | ty_app!(TypeCtor::Slice, st) => (TypeCtor::Slice, st.as_single().clone()), | 210 | Ty::Slice(st) => (Ty::Slice, st.as_single().clone()), |
213 | _ => (TypeCtor::Slice, Ty::Unknown), | 211 | _ => (Ty::Slice, Ty::Unknown), |
214 | }; | 212 | }; |
215 | 213 | ||
216 | for pat_id in prefix.iter().chain(suffix) { | 214 | for pat_id in prefix.iter().chain(suffix) { |
217 | self.infer_pat(*pat_id, &elem_ty, default_bm); | 215 | self.infer_pat(*pat_id, &elem_ty, default_bm); |
218 | } | 216 | } |
219 | 217 | ||
220 | let pat_ty = Ty::apply_one(container_ty, elem_ty); | 218 | let pat_ty = container_ty(Substs::single(elem_ty)); |
221 | if let Some(slice_pat_id) = slice { | 219 | if let Some(slice_pat_id) = slice { |
222 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); | 220 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); |
223 | } | 221 | } |
@@ -239,7 +237,7 @@ impl<'a> InferenceContext<'a> { | |||
239 | }; | 237 | }; |
240 | 238 | ||
241 | let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); | 239 | let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); |
242 | Ty::apply_one(TypeCtor::Adt(box_adt), inner_ty) | 240 | Ty::Adt(box_adt, Substs::single(inner_ty)) |
243 | } | 241 | } |
244 | None => Ty::Unknown, | 242 | None => Ty::Unknown, |
245 | }, | 243 | }, |
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 76984242e..99a89a7f3 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, Substs, Ty, | 12 | BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferenceVar, Scalar, |
12 | TyKind, TypeCtor, 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,14 +67,8 @@ 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), | 71 | Ty::BoundVar(BoundVar::new(binders, position)) |
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)) | ||
80 | } | 72 | } |
81 | } | 73 | } |
82 | _ => ty, | 74 | _ => ty, |
@@ -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 | ||
@@ -130,9 +110,10 @@ impl<T> Canonicalized<T> { | |||
130 | pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { | 110 | pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { |
131 | ty.walk_mut_binders( | 111 | ty.walk_mut_binders( |
132 | &mut |ty, binders| { | 112 | &mut |ty, binders| { |
133 | if let &mut Ty::Bound(bound) = ty { | 113 | if let &mut Ty::BoundVar(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 | } |
@@ -187,7 +168,7 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> { | |||
187 | // (kind of hacky) | 168 | // (kind of hacky) |
188 | for (i, var) in vars.iter().enumerate() { | 169 | for (i, var) in vars.iter().enumerate() { |
189 | if &*table.resolve_ty_shallow(var) == var { | 170 | if &*table.resolve_ty_shallow(var) == var { |
190 | table.unify(var, &Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i))); | 171 | table.unify(var, &Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i))); |
191 | } | 172 | } |
192 | } | 173 | } |
193 | Some( | 174 | Some( |
@@ -198,31 +179,73 @@ 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 | } | ||
226 | } | ||
227 | |||
228 | fn new_var(&mut self, kind: TyVariableKind, diverging: bool) -> Ty { | ||
229 | self.type_variable_table.push(TypeVariableData { diverging }); | ||
230 | let key = self.var_unification_table.new_key(TypeVarValue::Unknown); | ||
231 | assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1); | ||
232 | Ty::InferenceVar(InferenceVar::from_inner(key), kind) | ||
208 | } | 233 | } |
209 | 234 | ||
210 | pub(crate) fn new_type_var(&mut self) -> Ty { | 235 | pub(crate) fn new_type_var(&mut self) -> Ty { |
211 | Ty::Infer(InferTy::TypeVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) | 236 | self.new_var(TyVariableKind::General, false) |
212 | } | 237 | } |
213 | 238 | ||
214 | pub(crate) fn new_integer_var(&mut self) -> Ty { | 239 | pub(crate) fn new_integer_var(&mut self) -> Ty { |
215 | Ty::Infer(InferTy::IntVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) | 240 | self.new_var(TyVariableKind::Integer, false) |
216 | } | 241 | } |
217 | 242 | ||
218 | pub(crate) fn new_float_var(&mut self) -> Ty { | 243 | pub(crate) fn new_float_var(&mut self) -> Ty { |
219 | Ty::Infer(InferTy::FloatVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) | 244 | self.new_var(TyVariableKind::Float, false) |
220 | } | 245 | } |
221 | 246 | ||
222 | pub(crate) fn new_maybe_never_type_var(&mut self) -> Ty { | 247 | pub(crate) fn new_maybe_never_var(&mut self) -> Ty { |
223 | Ty::Infer(InferTy::MaybeNeverTypeVar( | 248 | self.new_var(TyVariableKind::General, true) |
224 | self.var_unification_table.new_key(TypeVarValue::Unknown), | ||
225 | )) | ||
226 | } | 249 | } |
227 | 250 | ||
228 | pub(crate) fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { | 251 | pub(crate) fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { |
@@ -257,12 +280,14 @@ impl InferenceTable { | |||
257 | // try to resolve type vars first | 280 | // try to resolve type vars first |
258 | let ty1 = self.resolve_ty_shallow(ty1); | 281 | let ty1 = self.resolve_ty_shallow(ty1); |
259 | let ty2 = self.resolve_ty_shallow(ty2); | 282 | let ty2 = self.resolve_ty_shallow(ty2); |
260 | match (&*ty1, &*ty2) { | 283 | if ty1.equals_ctor(&ty2) { |
261 | (Ty::Apply(a_ty1), Ty::Apply(a_ty2)) if a_ty1.ctor == a_ty2.ctor => { | 284 | match (ty1.substs(), ty2.substs()) { |
262 | self.unify_substs(&a_ty1.parameters, &a_ty2.parameters, depth + 1) | 285 | (Some(st1), Some(st2)) => self.unify_substs(st1, st2, depth + 1), |
286 | (None, None) => true, | ||
287 | _ => false, | ||
263 | } | 288 | } |
264 | 289 | } else { | |
265 | _ => self.unify_inner_trivial(&ty1, &ty2, depth), | 290 | self.unify_inner_trivial(&ty1, &ty2, depth) |
266 | } | 291 | } |
267 | } | 292 | } |
268 | 293 | ||
@@ -281,31 +306,46 @@ impl InferenceTable { | |||
281 | true | 306 | true |
282 | } | 307 | } |
283 | 308 | ||
284 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) | 309 | ( |
285 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) | 310 | Ty::InferenceVar(tv1, TyVariableKind::General), |
286 | | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) | 311 | Ty::InferenceVar(tv2, TyVariableKind::General), |
312 | ) | ||
287 | | ( | 313 | | ( |
288 | Ty::Infer(InferTy::MaybeNeverTypeVar(tv1)), | 314 | Ty::InferenceVar(tv1, TyVariableKind::Integer), |
289 | Ty::Infer(InferTy::MaybeNeverTypeVar(tv2)), | 315 | Ty::InferenceVar(tv2, TyVariableKind::Integer), |
290 | ) => { | 316 | ) |
317 | | ( | ||
318 | Ty::InferenceVar(tv1, TyVariableKind::Float), | ||
319 | Ty::InferenceVar(tv2, TyVariableKind::Float), | ||
320 | ) if self.type_variable_table.is_diverging(*tv1) | ||
321 | == self.type_variable_table.is_diverging(*tv2) => | ||
322 | { | ||
291 | // both type vars are unknown since we tried to resolve them | 323 | // both type vars are unknown since we tried to resolve them |
292 | self.var_unification_table.union(*tv1, *tv2); | 324 | self.var_unification_table.union(tv1.to_inner(), tv2.to_inner()); |
293 | true | 325 | true |
294 | } | 326 | } |
295 | 327 | ||
296 | // The order of MaybeNeverTypeVar matters here. | 328 | // The order of MaybeNeverTypeVar matters here. |
297 | // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. | 329 | // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. |
298 | // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. | 330 | // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. |
299 | (Ty::Infer(InferTy::TypeVar(tv)), other) | 331 | (Ty::InferenceVar(tv, TyVariableKind::General), other) |
300 | | (other, Ty::Infer(InferTy::TypeVar(tv))) | 332 | | (other, Ty::InferenceVar(tv, TyVariableKind::General)) |
301 | | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other) | 333 | | (Ty::InferenceVar(tv, TyVariableKind::Integer), other @ Ty::Scalar(Scalar::Int(_))) |
302 | | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv))) | 334 | | (other @ Ty::Scalar(Scalar::Int(_)), Ty::InferenceVar(tv, TyVariableKind::Integer)) |
303 | | (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Int(_))) | 335 | | ( |
304 | | (other @ ty_app!(TypeCtor::Int(_)), Ty::Infer(InferTy::IntVar(tv))) | 336 | Ty::InferenceVar(tv, TyVariableKind::Integer), |
305 | | (Ty::Infer(InferTy::FloatVar(tv)), other @ ty_app!(TypeCtor::Float(_))) | 337 | other @ Ty::Scalar(Scalar::Uint(_)), |
306 | | (other @ ty_app!(TypeCtor::Float(_)), Ty::Infer(InferTy::FloatVar(tv))) => { | 338 | ) |
339 | | ( | ||
340 | other @ Ty::Scalar(Scalar::Uint(_)), | ||
341 | Ty::InferenceVar(tv, TyVariableKind::Integer), | ||
342 | ) | ||
343 | | (Ty::InferenceVar(tv, TyVariableKind::Float), other @ Ty::Scalar(Scalar::Float(_))) | ||
344 | | (other @ Ty::Scalar(Scalar::Float(_)), Ty::InferenceVar(tv, TyVariableKind::Float)) => | ||
345 | { | ||
307 | // the type var is unknown since we tried to resolve it | 346 | // the type var is unknown since we tried to resolve it |
308 | self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); | 347 | self.var_unification_table |
348 | .union_value(tv.to_inner(), TypeVarValue::Known(other.clone())); | ||
309 | true | 349 | true |
310 | } | 350 | } |
311 | 351 | ||
@@ -350,7 +390,7 @@ impl InferenceTable { | |||
350 | mark::hit!(type_var_resolves_to_int_var); | 390 | mark::hit!(type_var_resolves_to_int_var); |
351 | } | 391 | } |
352 | match &*ty { | 392 | match &*ty { |
353 | Ty::Infer(tv) => { | 393 | Ty::InferenceVar(tv, _) => { |
354 | let inner = tv.to_inner(); | 394 | let inner = tv.to_inner(); |
355 | match self.var_unification_table.inlined_probe_value(inner).known() { | 395 | match self.var_unification_table.inlined_probe_value(inner).known() { |
356 | Some(known_ty) => { | 396 | Some(known_ty) => { |
@@ -373,12 +413,12 @@ impl InferenceTable { | |||
373 | /// known type. | 413 | /// known type. |
374 | fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | 414 | fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { |
375 | ty.fold(&mut |ty| match ty { | 415 | ty.fold(&mut |ty| match ty { |
376 | Ty::Infer(tv) => { | 416 | Ty::InferenceVar(tv, kind) => { |
377 | let inner = tv.to_inner(); | 417 | let inner = tv.to_inner(); |
378 | if tv_stack.contains(&inner) { | 418 | if tv_stack.contains(&inner) { |
379 | mark::hit!(type_var_cycles_resolve_as_possible); | 419 | mark::hit!(type_var_cycles_resolve_as_possible); |
380 | // recursive type | 420 | // recursive type |
381 | return tv.fallback_value(); | 421 | return self.type_variable_table.fallback_value(tv, kind); |
382 | } | 422 | } |
383 | if let Some(known_ty) = | 423 | if let Some(known_ty) = |
384 | self.var_unification_table.inlined_probe_value(inner).known() | 424 | self.var_unification_table.inlined_probe_value(inner).known() |
@@ -400,12 +440,12 @@ impl InferenceTable { | |||
400 | /// replaced by Ty::Unknown. | 440 | /// replaced by Ty::Unknown. |
401 | fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | 441 | fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { |
402 | ty.fold(&mut |ty| match ty { | 442 | ty.fold(&mut |ty| match ty { |
403 | Ty::Infer(tv) => { | 443 | Ty::InferenceVar(tv, kind) => { |
404 | let inner = tv.to_inner(); | 444 | let inner = tv.to_inner(); |
405 | if tv_stack.contains(&inner) { | 445 | if tv_stack.contains(&inner) { |
406 | mark::hit!(type_var_cycles_resolve_completely); | 446 | mark::hit!(type_var_cycles_resolve_completely); |
407 | // recursive type | 447 | // recursive type |
408 | return tv.fallback_value(); | 448 | return self.type_variable_table.fallback_value(tv, kind); |
409 | } | 449 | } |
410 | if let Some(known_ty) = | 450 | if let Some(known_ty) = |
411 | self.var_unification_table.inlined_probe_value(inner).known() | 451 | self.var_unification_table.inlined_probe_value(inner).known() |
@@ -416,7 +456,7 @@ impl InferenceTable { | |||
416 | tv_stack.pop(); | 456 | tv_stack.pop(); |
417 | result | 457 | result |
418 | } else { | 458 | } else { |
419 | tv.fallback_value() | 459 | self.type_variable_table.fallback_value(tv, kind) |
420 | } | 460 | } |
421 | } | 461 | } |
422 | _ => ty, | 462 | _ => ty, |
@@ -426,7 +466,7 @@ impl InferenceTable { | |||
426 | 466 | ||
427 | /// The ID of a type variable. | 467 | /// The ID of a type variable. |
428 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] | 468 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] |
429 | pub struct TypeVarId(pub(super) u32); | 469 | pub(super) struct TypeVarId(pub(super) u32); |
430 | 470 | ||
431 | impl UnifyKey for TypeVarId { | 471 | impl UnifyKey for TypeVarId { |
432 | type Value = TypeVarValue; | 472 | type Value = TypeVarValue; |
@@ -447,7 +487,7 @@ impl UnifyKey for TypeVarId { | |||
447 | /// The value of a type variable: either we already know the type, or we don't | 487 | /// The value of a type variable: either we already know the type, or we don't |
448 | /// know it yet. | 488 | /// know it yet. |
449 | #[derive(Clone, PartialEq, Eq, Debug)] | 489 | #[derive(Clone, PartialEq, Eq, Debug)] |
450 | pub enum TypeVarValue { | 490 | pub(super) enum TypeVarValue { |
451 | Known(Ty), | 491 | Known(Ty), |
452 | Unknown, | 492 | Unknown, |
453 | } | 493 | } |