diff options
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 38 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 235 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 41 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/path.rs | 6 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 105 |
5 files changed, 239 insertions, 186 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 7e8846f27..36670043a 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs | |||
@@ -7,7 +7,7 @@ | |||
7 | use chalk_ir::{Mutability, TyVariableKind}; | 7 | use chalk_ir::{Mutability, TyVariableKind}; |
8 | use hir_def::lang_item::LangItemTarget; | 8 | use hir_def::lang_item::LangItemTarget; |
9 | 9 | ||
10 | use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty}; | 10 | use crate::{autoderef, traits::Solution, Interner, Obligation, Substs, TraitRef, Ty, TyKind}; |
11 | 11 | ||
12 | use super::{InEnvironment, InferenceContext}; | 12 | use super::{InEnvironment, InferenceContext}; |
13 | 13 | ||
@@ -33,7 +33,9 @@ impl<'a> InferenceContext<'a> { | |||
33 | } else if self.coerce(ty2, ty1) { | 33 | } else if self.coerce(ty2, ty1) { |
34 | ty1.clone() | 34 | ty1.clone() |
35 | } else { | 35 | } else { |
36 | if let (Ty::FnDef(..), Ty::FnDef(..)) = (ty1, ty2) { | 36 | if let (TyKind::FnDef(..), TyKind::FnDef(..)) = |
37 | (ty1.interned(&Interner), ty2.interned(&Interner)) | ||
38 | { | ||
37 | cov_mark::hit!(coerce_fn_reification); | 39 | cov_mark::hit!(coerce_fn_reification); |
38 | // Special case: two function types. Try to coerce both to | 40 | // Special case: two function types. Try to coerce both to |
39 | // pointers to have a chance at getting a match. See | 41 | // pointers to have a chance at getting a match. See |
@@ -51,13 +53,13 @@ impl<'a> InferenceContext<'a> { | |||
51 | } | 53 | } |
52 | 54 | ||
53 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { | 55 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { |
54 | match (&from_ty, to_ty) { | 56 | match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { |
55 | // Never type will make type variable to fallback to Never Type instead of Unknown. | 57 | // Never type will make type variable to fallback to Never Type instead of Unknown. |
56 | (Ty::Never, Ty::InferenceVar(tv, TyVariableKind::General)) => { | 58 | (TyKind::Never, TyKind::InferenceVar(tv, TyVariableKind::General)) => { |
57 | self.table.type_variable_table.set_diverging(*tv, true); | 59 | self.table.type_variable_table.set_diverging(*tv, true); |
58 | return true; | 60 | return true; |
59 | } | 61 | } |
60 | (Ty::Never, _) => return true, | 62 | (TyKind::Never, _) => return true, |
61 | 63 | ||
62 | // Trivial cases, this should go after `never` check to | 64 | // Trivial cases, this should go after `never` check to |
63 | // avoid infer result type to be never | 65 | // avoid infer result type to be never |
@@ -69,33 +71,33 @@ impl<'a> InferenceContext<'a> { | |||
69 | } | 71 | } |
70 | 72 | ||
71 | // Pointer weakening and function to pointer | 73 | // Pointer weakening and function to pointer |
72 | match (&mut from_ty, to_ty) { | 74 | match (&mut from_ty.0, to_ty.interned(&Interner)) { |
73 | // `*mut T` -> `*const T` | 75 | // `*mut T` -> `*const T` |
74 | // `&mut T` -> `&T` | 76 | // `&mut T` -> `&T` |
75 | (Ty::Raw(m1, ..), Ty::Raw(m2 @ Mutability::Not, ..)) | 77 | (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) |
76 | | (Ty::Ref(m1, ..), Ty::Ref(m2 @ Mutability::Not, ..)) => { | 78 | | (TyKind::Ref(m1, ..), TyKind::Ref(m2 @ Mutability::Not, ..)) => { |
77 | *m1 = *m2; | 79 | *m1 = *m2; |
78 | } | 80 | } |
79 | // `&T` -> `*const T` | 81 | // `&T` -> `*const T` |
80 | // `&mut T` -> `*mut T`/`*const T` | 82 | // `&mut T` -> `*mut T`/`*const T` |
81 | (Ty::Ref(.., substs), &Ty::Raw(m2 @ Mutability::Not, ..)) | 83 | (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..)) |
82 | | (Ty::Ref(Mutability::Mut, substs), &Ty::Raw(m2, ..)) => { | 84 | | (TyKind::Ref(Mutability::Mut, substs), &TyKind::Raw(m2, ..)) => { |
83 | from_ty = Ty::Raw(m2, substs.clone()); | 85 | from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner); |
84 | } | 86 | } |
85 | 87 | ||
86 | // Illegal mutability conversion | 88 | // Illegal mutability conversion |
87 | (Ty::Raw(Mutability::Not, ..), Ty::Raw(Mutability::Mut, ..)) | 89 | (TyKind::Raw(Mutability::Not, ..), TyKind::Raw(Mutability::Mut, ..)) |
88 | | (Ty::Ref(Mutability::Not, ..), Ty::Ref(Mutability::Mut, ..)) => return false, | 90 | | (TyKind::Ref(Mutability::Not, ..), TyKind::Ref(Mutability::Mut, ..)) => return false, |
89 | 91 | ||
90 | // `{function_type}` -> `fn()` | 92 | // `{function_type}` -> `fn()` |
91 | (Ty::FnDef(..), Ty::Function { .. }) => match from_ty.callable_sig(self.db) { | 93 | (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) { |
92 | None => return false, | 94 | None => return false, |
93 | Some(sig) => { | 95 | Some(sig) => { |
94 | from_ty = Ty::fn_ptr(sig); | 96 | from_ty = Ty::fn_ptr(sig); |
95 | } | 97 | } |
96 | }, | 98 | }, |
97 | 99 | ||
98 | (Ty::Closure(.., substs), Ty::Function { .. }) => { | 100 | (TyKind::Closure(.., substs), TyKind::Function { .. }) => { |
99 | from_ty = substs[0].clone(); | 101 | from_ty = substs[0].clone(); |
100 | } | 102 | } |
101 | 103 | ||
@@ -107,9 +109,11 @@ impl<'a> InferenceContext<'a> { | |||
107 | } | 109 | } |
108 | 110 | ||
109 | // Auto Deref if cannot coerce | 111 | // Auto Deref if cannot coerce |
110 | match (&from_ty, to_ty) { | 112 | match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { |
111 | // FIXME: DerefMut | 113 | // FIXME: DerefMut |
112 | (Ty::Ref(_, st1), Ty::Ref(_, st2)) => self.unify_autoderef_behind_ref(&st1[0], &st2[0]), | 114 | (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => { |
115 | self.unify_autoderef_behind_ref(&st1[0], &st2[0]) | ||
116 | } | ||
113 | 117 | ||
114 | // Otherwise, normal unify | 118 | // Otherwise, normal unify |
115 | _ => self.unify(&from_ty, to_ty), | 119 | _ => self.unify(&from_ty, to_ty), |
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 262177ffb..4e77f22fd 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -20,8 +20,8 @@ use crate::{ | |||
20 | primitive::{self, UintTy}, | 20 | primitive::{self, UintTy}, |
21 | traits::{FnTrait, InEnvironment}, | 21 | traits::{FnTrait, InEnvironment}, |
22 | utils::{generics, variant_data, Generics}, | 22 | utils::{generics, variant_data, Generics}, |
23 | AdtId, Binders, CallableDefId, FnPointer, FnSig, Obligation, OpaqueTyId, Rawness, Scalar, | 23 | AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, OpaqueTyId, Rawness, |
24 | Substs, TraitRef, Ty, | 24 | Scalar, Substs, TraitRef, Ty, TyKind, |
25 | }; | 25 | }; |
26 | 26 | ||
27 | use super::{ | 27 | use super::{ |
@@ -57,7 +57,7 @@ impl<'a> InferenceContext<'a> { | |||
57 | // Return actual type when type mismatch. | 57 | // Return actual type when type mismatch. |
58 | // This is needed for diagnostic when return type mismatch. | 58 | // This is needed for diagnostic when return type mismatch. |
59 | ty | 59 | ty |
60 | } else if expected.coercion_target() == &Ty::Unknown { | 60 | } else if expected.coercion_target().is_unknown() { |
61 | ty | 61 | ty |
62 | } else { | 62 | } else { |
63 | expected.ty.clone() | 63 | expected.ty.clone() |
@@ -84,7 +84,7 @@ impl<'a> InferenceContext<'a> { | |||
84 | arg_tys.push(arg); | 84 | arg_tys.push(arg); |
85 | } | 85 | } |
86 | let parameters = param_builder.build(); | 86 | let parameters = param_builder.build(); |
87 | let arg_ty = Ty::Tuple(num_args, parameters); | 87 | let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner); |
88 | let substs = | 88 | let substs = |
89 | Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); | 89 | Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); |
90 | 90 | ||
@@ -116,10 +116,13 @@ impl<'a> InferenceContext<'a> { | |||
116 | fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { | 116 | fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { |
117 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 117 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
118 | let ty = match &body[tgt_expr] { | 118 | let ty = match &body[tgt_expr] { |
119 | Expr::Missing => Ty::Unknown, | 119 | Expr::Missing => self.err_ty(), |
120 | Expr::If { condition, then_branch, else_branch } => { | 120 | Expr::If { condition, then_branch, else_branch } => { |
121 | // if let is desugared to match, so this is always simple if | 121 | // if let is desugared to match, so this is always simple if |
122 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); | 122 | self.infer_expr( |
123 | *condition, | ||
124 | &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), | ||
125 | ); | ||
123 | 126 | ||
124 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); | 127 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); |
125 | let mut both_arms_diverge = Diverges::Always; | 128 | let mut both_arms_diverge = Diverges::Always; |
@@ -167,14 +170,14 @@ impl<'a> InferenceContext<'a> { | |||
167 | Expr::TryBlock { body } => { | 170 | Expr::TryBlock { body } => { |
168 | let _inner = self.infer_expr(*body, expected); | 171 | let _inner = self.infer_expr(*body, expected); |
169 | // FIXME should be std::result::Result<{inner}, _> | 172 | // FIXME should be std::result::Result<{inner}, _> |
170 | Ty::Unknown | 173 | self.err_ty() |
171 | } | 174 | } |
172 | Expr::Async { body } => { | 175 | Expr::Async { body } => { |
173 | // Use the first type parameter as the output type of future. | 176 | // Use the first type parameter as the output type of future. |
174 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> | 177 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> |
175 | let inner_ty = self.infer_expr(*body, &Expectation::none()); | 178 | let inner_ty = self.infer_expr(*body, &Expectation::none()); |
176 | let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); | 179 | let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); |
177 | Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty)) | 180 | TyKind::OpaqueType(opaque_ty_id, Substs::single(inner_ty)).intern(&Interner) |
178 | } | 181 | } |
179 | Expr::Loop { body, label } => { | 182 | Expr::Loop { body, label } => { |
180 | self.breakables.push(BreakableContext { | 183 | self.breakables.push(BreakableContext { |
@@ -192,17 +195,20 @@ impl<'a> InferenceContext<'a> { | |||
192 | if ctxt.may_break { | 195 | if ctxt.may_break { |
193 | ctxt.break_ty | 196 | ctxt.break_ty |
194 | } else { | 197 | } else { |
195 | Ty::Never | 198 | TyKind::Never.intern(&Interner) |
196 | } | 199 | } |
197 | } | 200 | } |
198 | Expr::While { condition, body, label } => { | 201 | Expr::While { condition, body, label } => { |
199 | self.breakables.push(BreakableContext { | 202 | self.breakables.push(BreakableContext { |
200 | may_break: false, | 203 | may_break: false, |
201 | break_ty: Ty::Unknown, | 204 | break_ty: self.err_ty(), |
202 | label: label.map(|label| self.body[label].name.clone()), | 205 | label: label.map(|label| self.body[label].name.clone()), |
203 | }); | 206 | }); |
204 | // while let is desugared to a match loop, so this is always simple while | 207 | // while let is desugared to a match loop, so this is always simple while |
205 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); | 208 | self.infer_expr( |
209 | *condition, | ||
210 | &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), | ||
211 | ); | ||
206 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 212 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
207 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); | 213 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); |
208 | // the body may not run, so it diverging doesn't mean we diverge | 214 | // the body may not run, so it diverging doesn't mean we diverge |
@@ -214,7 +220,7 @@ impl<'a> InferenceContext<'a> { | |||
214 | 220 | ||
215 | self.breakables.push(BreakableContext { | 221 | self.breakables.push(BreakableContext { |
216 | may_break: false, | 222 | may_break: false, |
217 | break_ty: Ty::Unknown, | 223 | break_ty: self.err_ty(), |
218 | label: label.map(|label| self.body[label].name.clone()), | 224 | label: label.map(|label| self.body[label].name.clone()), |
219 | }); | 225 | }); |
220 | let pat_ty = | 226 | let pat_ty = |
@@ -249,12 +255,14 @@ impl<'a> InferenceContext<'a> { | |||
249 | None => self.table.new_type_var(), | 255 | None => self.table.new_type_var(), |
250 | }; | 256 | }; |
251 | sig_tys.push(ret_ty.clone()); | 257 | sig_tys.push(ret_ty.clone()); |
252 | let sig_ty = Ty::Function(FnPointer { | 258 | let sig_ty = TyKind::Function(FnPointer { |
253 | num_args: sig_tys.len() - 1, | 259 | num_args: sig_tys.len() - 1, |
254 | sig: FnSig { variadic: false }, | 260 | sig: FnSig { variadic: false }, |
255 | substs: Substs(sig_tys.clone().into()), | 261 | substs: Substs(sig_tys.clone().into()), |
256 | }); | 262 | }) |
257 | let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty)); | 263 | .intern(&Interner); |
264 | let closure_ty = | ||
265 | TyKind::Closure(self.owner, tgt_expr, Substs::single(sig_ty)).intern(&Interner); | ||
258 | 266 | ||
259 | // Eagerly try to relate the closure type with the expected | 267 | // Eagerly try to relate the closure type with the expected |
260 | // type, otherwise we often won't have enough information to | 268 | // type, otherwise we often won't have enough information to |
@@ -295,7 +303,7 @@ impl<'a> InferenceContext<'a> { | |||
295 | args.len(), | 303 | args.len(), |
296 | ) | 304 | ) |
297 | }) | 305 | }) |
298 | .unwrap_or((Vec::new(), Ty::Unknown)); | 306 | .unwrap_or((Vec::new(), self.err_ty())); |
299 | self.register_obligations_for_call(&callee_ty); | 307 | self.register_obligations_for_call(&callee_ty); |
300 | self.check_call_arguments(args, ¶m_tys); | 308 | self.check_call_arguments(args, ¶m_tys); |
301 | self.normalize_associated_types_in(ret_ty) | 309 | self.normalize_associated_types_in(ret_ty) |
@@ -305,8 +313,11 @@ impl<'a> InferenceContext<'a> { | |||
305 | Expr::Match { expr, arms } => { | 313 | Expr::Match { expr, arms } => { |
306 | let input_ty = self.infer_expr(*expr, &Expectation::none()); | 314 | let input_ty = self.infer_expr(*expr, &Expectation::none()); |
307 | 315 | ||
308 | let mut result_ty = | 316 | let mut result_ty = if arms.is_empty() { |
309 | if arms.is_empty() { Ty::Never } else { self.table.new_type_var() }; | 317 | TyKind::Never.intern(&Interner) |
318 | } else { | ||
319 | self.table.new_type_var() | ||
320 | }; | ||
310 | 321 | ||
311 | let matchee_diverges = self.diverges; | 322 | let matchee_diverges = self.diverges; |
312 | let mut all_arms_diverge = Diverges::Always; | 323 | let mut all_arms_diverge = Diverges::Always; |
@@ -317,7 +328,7 @@ impl<'a> InferenceContext<'a> { | |||
317 | if let Some(guard_expr) = arm.guard { | 328 | if let Some(guard_expr) = arm.guard { |
318 | self.infer_expr( | 329 | self.infer_expr( |
319 | guard_expr, | 330 | guard_expr, |
320 | &Expectation::has_type(Ty::Scalar(Scalar::Bool)), | 331 | &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), |
321 | ); | 332 | ); |
322 | } | 333 | } |
323 | 334 | ||
@@ -333,9 +344,9 @@ impl<'a> InferenceContext<'a> { | |||
333 | Expr::Path(p) => { | 344 | Expr::Path(p) => { |
334 | // FIXME this could be more efficient... | 345 | // FIXME this could be more efficient... |
335 | let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); | 346 | let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); |
336 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) | 347 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(self.err_ty()) |
337 | } | 348 | } |
338 | Expr::Continue { .. } => Ty::Never, | 349 | Expr::Continue { .. } => TyKind::Never.intern(&Interner), |
339 | Expr::Break { expr, label } => { | 350 | Expr::Break { expr, label } => { |
340 | let val_ty = if let Some(expr) = expr { | 351 | let val_ty = if let Some(expr) = expr { |
341 | self.infer_expr(*expr, &Expectation::none()) | 352 | self.infer_expr(*expr, &Expectation::none()) |
@@ -347,7 +358,7 @@ impl<'a> InferenceContext<'a> { | |||
347 | if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { | 358 | if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { |
348 | ctxt.break_ty.clone() | 359 | ctxt.break_ty.clone() |
349 | } else { | 360 | } else { |
350 | Ty::Unknown | 361 | self.err_ty() |
351 | }; | 362 | }; |
352 | 363 | ||
353 | let merged_type = self.coerce_merge_branch(&last_ty, &val_ty); | 364 | let merged_type = self.coerce_merge_branch(&last_ty, &val_ty); |
@@ -360,7 +371,7 @@ impl<'a> InferenceContext<'a> { | |||
360 | expr: tgt_expr, | 371 | expr: tgt_expr, |
361 | }); | 372 | }); |
362 | } | 373 | } |
363 | Ty::Never | 374 | TyKind::Never.intern(&Interner) |
364 | } | 375 | } |
365 | Expr::Return { expr } => { | 376 | Expr::Return { expr } => { |
366 | if let Some(expr) = expr { | 377 | if let Some(expr) = expr { |
@@ -369,14 +380,14 @@ impl<'a> InferenceContext<'a> { | |||
369 | let unit = Ty::unit(); | 380 | let unit = Ty::unit(); |
370 | self.coerce(&unit, &self.return_ty.clone()); | 381 | self.coerce(&unit, &self.return_ty.clone()); |
371 | } | 382 | } |
372 | Ty::Never | 383 | TyKind::Never.intern(&Interner) |
373 | } | 384 | } |
374 | Expr::Yield { expr } => { | 385 | Expr::Yield { expr } => { |
375 | // FIXME: track yield type for coercion | 386 | // FIXME: track yield type for coercion |
376 | if let Some(expr) = expr { | 387 | if let Some(expr) = expr { |
377 | self.infer_expr(*expr, &Expectation::none()); | 388 | self.infer_expr(*expr, &Expectation::none()); |
378 | } | 389 | } |
379 | Ty::Never | 390 | TyKind::Never.intern(&Interner) |
380 | } | 391 | } |
381 | Expr::RecordLit { path, fields, spread } => { | 392 | Expr::RecordLit { path, fields, spread } => { |
382 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 393 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
@@ -404,8 +415,9 @@ impl<'a> InferenceContext<'a> { | |||
404 | if let Some(field_def) = field_def { | 415 | if let Some(field_def) = field_def { |
405 | self.result.record_field_resolutions.insert(field.expr, field_def); | 416 | self.result.record_field_resolutions.insert(field.expr, field_def); |
406 | } | 417 | } |
407 | let field_ty = field_def | 418 | let field_ty = field_def.map_or(self.err_ty(), |it| { |
408 | .map_or(Ty::Unknown, |it| field_types[it.local_id].clone().subst(&substs)); | 419 | field_types[it.local_id].clone().subst(&substs) |
420 | }); | ||
409 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); | 421 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); |
410 | } | 422 | } |
411 | if let Some(expr) = spread { | 423 | if let Some(expr) = spread { |
@@ -424,27 +436,33 @@ impl<'a> InferenceContext<'a> { | |||
424 | environment: self.trait_env.clone(), | 436 | environment: self.trait_env.clone(), |
425 | }, | 437 | }, |
426 | ) | 438 | ) |
427 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { | 439 | .find_map(|derefed_ty| { |
428 | Ty::Tuple(_, substs) => { | 440 | match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) { |
429 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) | 441 | TyKind::Tuple(_, substs) => { |
430 | } | 442 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) |
431 | Ty::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { | 443 | } |
432 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { | 444 | TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { |
433 | let field = FieldId { parent: s.into(), local_id }; | 445 | self.db.struct_data(*s).variant_data.field(name).map(|local_id| { |
434 | self.write_field_resolution(tgt_expr, field); | 446 | let field = FieldId { parent: (*s).into(), local_id }; |
435 | self.db.field_types(s.into())[field.local_id].clone().subst(¶meters) | 447 | self.write_field_resolution(tgt_expr, field); |
436 | }) | 448 | self.db.field_types((*s).into())[field.local_id] |
437 | } | 449 | .clone() |
438 | Ty::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => { | 450 | .subst(¶meters) |
439 | self.db.union_data(u).variant_data.field(name).map(|local_id| { | 451 | }) |
440 | let field = FieldId { parent: u.into(), local_id }; | 452 | } |
441 | self.write_field_resolution(tgt_expr, field); | 453 | TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => { |
442 | self.db.field_types(u.into())[field.local_id].clone().subst(¶meters) | 454 | self.db.union_data(*u).variant_data.field(name).map(|local_id| { |
443 | }) | 455 | let field = FieldId { parent: (*u).into(), local_id }; |
456 | self.write_field_resolution(tgt_expr, field); | ||
457 | self.db.field_types((*u).into())[field.local_id] | ||
458 | .clone() | ||
459 | .subst(¶meters) | ||
460 | }) | ||
461 | } | ||
462 | _ => None, | ||
444 | } | 463 | } |
445 | _ => None, | ||
446 | }) | 464 | }) |
447 | .unwrap_or(Ty::Unknown); | 465 | .unwrap_or(self.err_ty()); |
448 | let ty = self.insert_type_vars(ty); | 466 | let ty = self.insert_type_vars(ty); |
449 | self.normalize_associated_types_in(ty) | 467 | self.normalize_associated_types_in(ty) |
450 | } | 468 | } |
@@ -481,9 +499,10 @@ impl<'a> InferenceContext<'a> { | |||
481 | }; | 499 | }; |
482 | let inner_ty = self.infer_expr_inner(*expr, &expectation); | 500 | let inner_ty = self.infer_expr_inner(*expr, &expectation); |
483 | match rawness { | 501 | match rawness { |
484 | Rawness::RawPtr => Ty::Raw(mutability, Substs::single(inner_ty)), | 502 | Rawness::RawPtr => TyKind::Raw(mutability, Substs::single(inner_ty)), |
485 | Rawness::Ref => Ty::Ref(mutability, Substs::single(inner_ty)), | 503 | Rawness::Ref => TyKind::Ref(mutability, Substs::single(inner_ty)), |
486 | } | 504 | } |
505 | .intern(&Interner) | ||
487 | } | 506 | } |
488 | Expr::Box { expr } => { | 507 | Expr::Box { expr } => { |
489 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 508 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
@@ -499,7 +518,7 @@ impl<'a> InferenceContext<'a> { | |||
499 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); | 518 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); |
500 | Ty::adt_ty(box_, sb.build()) | 519 | Ty::adt_ty(box_, sb.build()) |
501 | } else { | 520 | } else { |
502 | Ty::Unknown | 521 | self.err_ty() |
503 | } | 522 | } |
504 | } | 523 | } |
505 | Expr::UnaryOp { expr, op } => { | 524 | Expr::UnaryOp { expr, op } => { |
@@ -519,31 +538,31 @@ impl<'a> InferenceContext<'a> { | |||
519 | Some(derefed_ty) => { | 538 | Some(derefed_ty) => { |
520 | canonicalized.decanonicalize_ty(derefed_ty.value) | 539 | canonicalized.decanonicalize_ty(derefed_ty.value) |
521 | } | 540 | } |
522 | None => Ty::Unknown, | 541 | None => self.err_ty(), |
523 | } | 542 | } |
524 | } | 543 | } |
525 | None => Ty::Unknown, | 544 | None => self.err_ty(), |
526 | }, | 545 | }, |
527 | UnaryOp::Neg => { | 546 | UnaryOp::Neg => { |
528 | match &inner_ty { | 547 | match inner_ty.interned(&Interner) { |
529 | // Fast path for builtins | 548 | // Fast path for builtins |
530 | Ty::Scalar(Scalar::Int(_)) | 549 | TyKind::Scalar(Scalar::Int(_)) |
531 | | Ty::Scalar(Scalar::Uint(_)) | 550 | | TyKind::Scalar(Scalar::Uint(_)) |
532 | | Ty::Scalar(Scalar::Float(_)) | 551 | | TyKind::Scalar(Scalar::Float(_)) |
533 | | Ty::InferenceVar(_, TyVariableKind::Integer) | 552 | | TyKind::InferenceVar(_, TyVariableKind::Integer) |
534 | | Ty::InferenceVar(_, TyVariableKind::Float) => inner_ty, | 553 | | TyKind::InferenceVar(_, TyVariableKind::Float) => inner_ty, |
535 | // Otherwise we resolve via the std::ops::Neg trait | 554 | // Otherwise we resolve via the std::ops::Neg trait |
536 | _ => self | 555 | _ => self |
537 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), | 556 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), |
538 | } | 557 | } |
539 | } | 558 | } |
540 | UnaryOp::Not => { | 559 | UnaryOp::Not => { |
541 | match &inner_ty { | 560 | match inner_ty.interned(&Interner) { |
542 | // Fast path for builtins | 561 | // Fast path for builtins |
543 | Ty::Scalar(Scalar::Bool) | 562 | TyKind::Scalar(Scalar::Bool) |
544 | | Ty::Scalar(Scalar::Int(_)) | 563 | | TyKind::Scalar(Scalar::Int(_)) |
545 | | Ty::Scalar(Scalar::Uint(_)) | 564 | | TyKind::Scalar(Scalar::Uint(_)) |
546 | | Ty::InferenceVar(_, TyVariableKind::Integer) => inner_ty, | 565 | | TyKind::InferenceVar(_, TyVariableKind::Integer) => inner_ty, |
547 | // Otherwise we resolve via the std::ops::Not trait | 566 | // Otherwise we resolve via the std::ops::Not trait |
548 | _ => self | 567 | _ => self |
549 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), | 568 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), |
@@ -554,7 +573,9 @@ impl<'a> InferenceContext<'a> { | |||
554 | Expr::BinaryOp { lhs, rhs, op } => match op { | 573 | Expr::BinaryOp { lhs, rhs, op } => match op { |
555 | Some(op) => { | 574 | Some(op) => { |
556 | let lhs_expectation = match op { | 575 | let lhs_expectation = match op { |
557 | BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)), | 576 | BinaryOp::LogicOp(..) => { |
577 | Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)) | ||
578 | } | ||
558 | _ => Expectation::none(), | 579 | _ => Expectation::none(), |
559 | }; | 580 | }; |
560 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); | 581 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); |
@@ -563,7 +584,7 @@ impl<'a> InferenceContext<'a> { | |||
563 | 584 | ||
564 | let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone()); | 585 | let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone()); |
565 | 586 | ||
566 | if ret == Ty::Unknown { | 587 | if ret.is_unknown() { |
567 | cov_mark::hit!(infer_expr_inner_binary_operator_overload); | 588 | cov_mark::hit!(infer_expr_inner_binary_operator_overload); |
568 | 589 | ||
569 | self.resolve_associated_type_with_params( | 590 | self.resolve_associated_type_with_params( |
@@ -575,7 +596,7 @@ impl<'a> InferenceContext<'a> { | |||
575 | ret | 596 | ret |
576 | } | 597 | } |
577 | } | 598 | } |
578 | _ => Ty::Unknown, | 599 | _ => self.err_ty(), |
579 | }, | 600 | }, |
580 | Expr::Range { lhs, rhs, range_type } => { | 601 | Expr::Range { lhs, rhs, range_type } => { |
581 | let lhs_ty = lhs.map(|e| self.infer_expr_inner(e, &Expectation::none())); | 602 | let lhs_ty = lhs.map(|e| self.infer_expr_inner(e, &Expectation::none())); |
@@ -586,33 +607,33 @@ impl<'a> InferenceContext<'a> { | |||
586 | match (range_type, lhs_ty, rhs_ty) { | 607 | match (range_type, lhs_ty, rhs_ty) { |
587 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { | 608 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { |
588 | Some(adt) => Ty::adt_ty(adt, Substs::empty()), | 609 | Some(adt) => Ty::adt_ty(adt, Substs::empty()), |
589 | None => Ty::Unknown, | 610 | None => self.err_ty(), |
590 | }, | 611 | }, |
591 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { | 612 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { |
592 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 613 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
593 | None => Ty::Unknown, | 614 | None => self.err_ty(), |
594 | }, | 615 | }, |
595 | (RangeOp::Inclusive, None, Some(ty)) => { | 616 | (RangeOp::Inclusive, None, Some(ty)) => { |
596 | match self.resolve_range_to_inclusive() { | 617 | match self.resolve_range_to_inclusive() { |
597 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 618 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
598 | None => Ty::Unknown, | 619 | None => self.err_ty(), |
599 | } | 620 | } |
600 | } | 621 | } |
601 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { | 622 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { |
602 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 623 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
603 | None => Ty::Unknown, | 624 | None => self.err_ty(), |
604 | }, | 625 | }, |
605 | (RangeOp::Inclusive, Some(_), Some(ty)) => { | 626 | (RangeOp::Inclusive, Some(_), Some(ty)) => { |
606 | match self.resolve_range_inclusive() { | 627 | match self.resolve_range_inclusive() { |
607 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 628 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
608 | None => Ty::Unknown, | 629 | None => self.err_ty(), |
609 | } | 630 | } |
610 | } | 631 | } |
611 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { | 632 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { |
612 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 633 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
613 | None => Ty::Unknown, | 634 | None => self.err_ty(), |
614 | }, | 635 | }, |
615 | (RangeOp::Inclusive, _, None) => Ty::Unknown, | 636 | (RangeOp::Inclusive, _, None) => self.err_ty(), |
616 | } | 637 | } |
617 | } | 638 | } |
618 | Expr::Index { base, index } => { | 639 | Expr::Index { base, index } => { |
@@ -631,19 +652,19 @@ impl<'a> InferenceContext<'a> { | |||
631 | index_trait, | 652 | index_trait, |
632 | ); | 653 | ); |
633 | let self_ty = | 654 | let self_ty = |
634 | self_ty.map_or(Ty::Unknown, |t| canonicalized.decanonicalize_ty(t.value)); | 655 | self_ty.map_or(self.err_ty(), |t| canonicalized.decanonicalize_ty(t.value)); |
635 | self.resolve_associated_type_with_params( | 656 | self.resolve_associated_type_with_params( |
636 | self_ty, | 657 | self_ty, |
637 | self.resolve_ops_index_output(), | 658 | self.resolve_ops_index_output(), |
638 | &[index_ty], | 659 | &[index_ty], |
639 | ) | 660 | ) |
640 | } else { | 661 | } else { |
641 | Ty::Unknown | 662 | self.err_ty() |
642 | } | 663 | } |
643 | } | 664 | } |
644 | Expr::Tuple { exprs } => { | 665 | Expr::Tuple { exprs } => { |
645 | let mut tys = match &expected.ty { | 666 | let mut tys = match expected.ty.interned(&Interner) { |
646 | Ty::Tuple(_, substs) => substs | 667 | TyKind::Tuple(_, substs) => substs |
647 | .iter() | 668 | .iter() |
648 | .cloned() | 669 | .cloned() |
649 | .chain(repeat_with(|| self.table.new_type_var())) | 670 | .chain(repeat_with(|| self.table.new_type_var())) |
@@ -656,11 +677,11 @@ impl<'a> InferenceContext<'a> { | |||
656 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); | 677 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); |
657 | } | 678 | } |
658 | 679 | ||
659 | Ty::Tuple(tys.len(), Substs(tys.into())) | 680 | TyKind::Tuple(tys.len(), Substs(tys.into())).intern(&Interner) |
660 | } | 681 | } |
661 | Expr::Array(array) => { | 682 | Expr::Array(array) => { |
662 | let elem_ty = match &expected.ty { | 683 | let elem_ty = match expected.ty.interned(&Interner) { |
663 | Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(), | 684 | TyKind::Array(st) | TyKind::Slice(st) => st.as_single().clone(), |
664 | _ => self.table.new_type_var(), | 685 | _ => self.table.new_type_var(), |
665 | }; | 686 | }; |
666 | 687 | ||
@@ -677,43 +698,51 @@ impl<'a> InferenceContext<'a> { | |||
677 | ); | 698 | ); |
678 | self.infer_expr( | 699 | self.infer_expr( |
679 | *repeat, | 700 | *repeat, |
680 | &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))), | 701 | &Expectation::has_type( |
702 | TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner), | ||
703 | ), | ||
681 | ); | 704 | ); |
682 | } | 705 | } |
683 | } | 706 | } |
684 | 707 | ||
685 | Ty::Array(Substs::single(elem_ty)) | 708 | TyKind::Array(Substs::single(elem_ty)).intern(&Interner) |
686 | } | 709 | } |
687 | Expr::Literal(lit) => match lit { | 710 | Expr::Literal(lit) => match lit { |
688 | Literal::Bool(..) => Ty::Scalar(Scalar::Bool), | 711 | Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), |
689 | Literal::String(..) => Ty::Ref(Mutability::Not, Substs::single(Ty::Str)), | 712 | Literal::String(..) => { |
713 | TyKind::Ref(Mutability::Not, Substs::single(TyKind::Str.intern(&Interner))) | ||
714 | .intern(&Interner) | ||
715 | } | ||
690 | Literal::ByteString(..) => { | 716 | Literal::ByteString(..) => { |
691 | let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8)); | 717 | let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); |
692 | let array_type = Ty::Array(Substs::single(byte_type)); | 718 | let array_type = TyKind::Array(Substs::single(byte_type)).intern(&Interner); |
693 | Ty::Ref(Mutability::Not, Substs::single(array_type)) | 719 | TyKind::Ref(Mutability::Not, Substs::single(array_type)).intern(&Interner) |
694 | } | 720 | } |
695 | Literal::Char(..) => Ty::Scalar(Scalar::Char), | 721 | Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner), |
696 | Literal::Int(_v, ty) => match ty { | 722 | Literal::Int(_v, ty) => match ty { |
697 | Some(int_ty) => { | 723 | Some(int_ty) => { |
698 | Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty))) | 724 | TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty))) |
725 | .intern(&Interner) | ||
699 | } | 726 | } |
700 | None => self.table.new_integer_var(), | 727 | None => self.table.new_integer_var(), |
701 | }, | 728 | }, |
702 | Literal::Uint(_v, ty) => match ty { | 729 | Literal::Uint(_v, ty) => match ty { |
703 | Some(int_ty) => { | 730 | Some(int_ty) => { |
704 | Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty))) | 731 | TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty))) |
732 | .intern(&Interner) | ||
705 | } | 733 | } |
706 | None => self.table.new_integer_var(), | 734 | None => self.table.new_integer_var(), |
707 | }, | 735 | }, |
708 | Literal::Float(_v, ty) => match ty { | 736 | Literal::Float(_v, ty) => match ty { |
709 | Some(float_ty) => { | 737 | Some(float_ty) => { |
710 | Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty))) | 738 | TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty))) |
739 | .intern(&Interner) | ||
711 | } | 740 | } |
712 | None => self.table.new_float_var(), | 741 | None => self.table.new_float_var(), |
713 | }, | 742 | }, |
714 | }, | 743 | }, |
715 | }; | 744 | }; |
716 | // use a new type variable if we got Ty::Unknown here | 745 | // use a new type variable if we got unknown here |
717 | let ty = self.insert_type_vars_shallow(ty); | 746 | let ty = self.insert_type_vars_shallow(ty); |
718 | let ty = self.resolve_ty_as_possible(ty); | 747 | let ty = self.resolve_ty_as_possible(ty); |
719 | self.write_expr_ty(tgt_expr, ty.clone()); | 748 | self.write_expr_ty(tgt_expr, ty.clone()); |
@@ -730,7 +759,7 @@ impl<'a> InferenceContext<'a> { | |||
730 | match stmt { | 759 | match stmt { |
731 | Statement::Let { pat, type_ref, initializer } => { | 760 | Statement::Let { pat, type_ref, initializer } => { |
732 | let decl_ty = | 761 | let decl_ty = |
733 | type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(Ty::Unknown); | 762 | type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(self.err_ty()); |
734 | 763 | ||
735 | // Always use the declared type when specified | 764 | // Always use the declared type when specified |
736 | let mut ty = decl_ty.clone(); | 765 | let mut ty = decl_ty.clone(); |
@@ -738,7 +767,7 @@ impl<'a> InferenceContext<'a> { | |||
738 | if let Some(expr) = initializer { | 767 | if let Some(expr) = initializer { |
739 | let actual_ty = | 768 | let actual_ty = |
740 | self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone())); | 769 | self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone())); |
741 | if decl_ty == Ty::Unknown { | 770 | if decl_ty.is_unknown() { |
742 | ty = actual_ty; | 771 | ty = actual_ty; |
743 | } | 772 | } |
744 | } | 773 | } |
@@ -802,7 +831,7 @@ impl<'a> InferenceContext<'a> { | |||
802 | self.write_method_resolution(tgt_expr, func); | 831 | self.write_method_resolution(tgt_expr, func); |
803 | (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) | 832 | (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) |
804 | } | 833 | } |
805 | None => (receiver_ty, Binders::new(0, Ty::Unknown), None), | 834 | None => (receiver_ty, Binders::new(0, self.err_ty()), None), |
806 | }; | 835 | }; |
807 | let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); | 836 | let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); |
808 | let method_ty = method_ty.subst(&substs); | 837 | let method_ty = method_ty.subst(&substs); |
@@ -813,15 +842,17 @@ impl<'a> InferenceContext<'a> { | |||
813 | if !sig.params().is_empty() { | 842 | if !sig.params().is_empty() { |
814 | (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone()) | 843 | (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone()) |
815 | } else { | 844 | } else { |
816 | (Ty::Unknown, Vec::new(), sig.ret().clone()) | 845 | (self.err_ty(), Vec::new(), sig.ret().clone()) |
817 | } | 846 | } |
818 | } | 847 | } |
819 | None => (Ty::Unknown, Vec::new(), Ty::Unknown), | 848 | None => (self.err_ty(), Vec::new(), self.err_ty()), |
820 | }; | 849 | }; |
821 | // Apply autoref so the below unification works correctly | 850 | // Apply autoref so the below unification works correctly |
822 | // FIXME: return correct autorefs from lookup_method | 851 | // FIXME: return correct autorefs from lookup_method |
823 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { | 852 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { |
824 | Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)), | 853 | Some((_, mutability)) => { |
854 | TyKind::Ref(mutability, Substs::single(derefed_receiver_ty)).intern(&Interner) | ||
855 | } | ||
825 | _ => derefed_receiver_ty, | 856 | _ => derefed_receiver_ty, |
826 | }; | 857 | }; |
827 | self.unify(&expected_receiver_ty, &actual_receiver_ty); | 858 | self.unify(&expected_receiver_ty, &actual_receiver_ty); |
@@ -837,7 +868,7 @@ impl<'a> InferenceContext<'a> { | |||
837 | // that we have more information about the types of arguments when we | 868 | // that we have more information about the types of arguments when we |
838 | // type-check the functions. This isn't really the right way to do this. | 869 | // type-check the functions. This isn't really the right way to do this. |
839 | for &check_closures in &[false, true] { | 870 | for &check_closures in &[false, true] { |
840 | let param_iter = param_tys.iter().cloned().chain(repeat(Ty::Unknown)); | 871 | let param_iter = param_tys.iter().cloned().chain(repeat(self.err_ty())); |
841 | for (&arg, param_ty) in args.iter().zip(param_iter) { | 872 | for (&arg, param_ty) in args.iter().zip(param_iter) { |
842 | let is_closure = matches!(&self.body[arg], Expr::Lambda { .. }); | 873 | let is_closure = matches!(&self.body[arg], Expr::Lambda { .. }); |
843 | if is_closure != check_closures { | 874 | if is_closure != check_closures { |
@@ -867,7 +898,7 @@ impl<'a> InferenceContext<'a> { | |||
867 | if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf { | 898 | if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf { |
868 | substs.push(receiver_ty.clone()); | 899 | substs.push(receiver_ty.clone()); |
869 | } else { | 900 | } else { |
870 | substs.push(Ty::Unknown); | 901 | substs.push(self.err_ty()); |
871 | } | 902 | } |
872 | } | 903 | } |
873 | } | 904 | } |
@@ -891,15 +922,15 @@ impl<'a> InferenceContext<'a> { | |||
891 | }; | 922 | }; |
892 | let supplied_params = substs.len(); | 923 | let supplied_params = substs.len(); |
893 | for _ in supplied_params..total_len { | 924 | for _ in supplied_params..total_len { |
894 | substs.push(Ty::Unknown); | 925 | substs.push(self.err_ty()); |
895 | } | 926 | } |
896 | assert_eq!(substs.len(), total_len); | 927 | assert_eq!(substs.len(), total_len); |
897 | Substs(substs.into()) | 928 | Substs(substs.into()) |
898 | } | 929 | } |
899 | 930 | ||
900 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { | 931 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { |
901 | if let &Ty::FnDef(def, ref parameters) = callable_ty { | 932 | if let TyKind::FnDef(def, parameters) = callable_ty.interned(&Interner) { |
902 | let generic_predicates = self.db.generic_predicates(def.into()); | 933 | let generic_predicates = self.db.generic_predicates((*def).into()); |
903 | for predicate in generic_predicates.iter() { | 934 | for predicate in generic_predicates.iter() { |
904 | let predicate = predicate.clone().subst(parameters); | 935 | let predicate = predicate.clone().subst(parameters); |
905 | if let Some(obligation) = Obligation::from_predicate(predicate) { | 936 | if let Some(obligation) = Obligation::from_predicate(predicate) { |
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index a0ac8d80f..a16755cda 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs | |||
@@ -12,7 +12,7 @@ use hir_def::{ | |||
12 | use hir_expand::name::Name; | 12 | use hir_expand::name::Name; |
13 | 13 | ||
14 | use super::{BindingMode, Expectation, InferenceContext}; | 14 | use super::{BindingMode, Expectation, InferenceContext}; |
15 | use crate::{lower::lower_to_chalk_mutability, utils::variant_data, Substs, Ty}; | 15 | use crate::{lower::lower_to_chalk_mutability, utils::variant_data, Interner, Substs, Ty, TyKind}; |
16 | 16 | ||
17 | impl<'a> InferenceContext<'a> { | 17 | impl<'a> InferenceContext<'a> { |
18 | fn infer_tuple_struct_pat( | 18 | fn infer_tuple_struct_pat( |
@@ -46,7 +46,7 @@ impl<'a> InferenceContext<'a> { | |||
46 | let expected_ty = var_data | 46 | let expected_ty = var_data |
47 | .as_ref() | 47 | .as_ref() |
48 | .and_then(|d| d.field(&Name::new_tuple_field(i))) | 48 | .and_then(|d| d.field(&Name::new_tuple_field(i))) |
49 | .map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs)); | 49 | .map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs)); |
50 | let expected_ty = self.normalize_associated_types_in(expected_ty); | 50 | let expected_ty = self.normalize_associated_types_in(expected_ty); |
51 | self.infer_pat(subpat, &expected_ty, default_bm); | 51 | self.infer_pat(subpat, &expected_ty, default_bm); |
52 | } | 52 | } |
@@ -80,8 +80,8 @@ impl<'a> InferenceContext<'a> { | |||
80 | self.result.record_pat_field_resolutions.insert(subpat.pat, field_def); | 80 | self.result.record_pat_field_resolutions.insert(subpat.pat, field_def); |
81 | } | 81 | } |
82 | 82 | ||
83 | let expected_ty = | 83 | let expected_ty = matching_field |
84 | matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs)); | 84 | .map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs)); |
85 | let expected_ty = self.normalize_associated_types_in(expected_ty); | 85 | let expected_ty = self.normalize_associated_types_in(expected_ty); |
86 | self.infer_pat(subpat.pat, &expected_ty, default_bm); | 86 | self.infer_pat(subpat.pat, &expected_ty, default_bm); |
87 | } | 87 | } |
@@ -129,7 +129,8 @@ impl<'a> InferenceContext<'a> { | |||
129 | None => (&args[..], &[][..]), | 129 | None => (&args[..], &[][..]), |
130 | }; | 130 | }; |
131 | let n_uncovered_patterns = expectations.len().saturating_sub(args.len()); | 131 | let n_uncovered_patterns = expectations.len().saturating_sub(args.len()); |
132 | let mut expectations_iter = expectations.iter().chain(repeat(&Ty::Unknown)); | 132 | let err_ty = self.err_ty(); |
133 | let mut expectations_iter = expectations.iter().chain(repeat(&err_ty)); | ||
133 | let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm); | 134 | let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm); |
134 | 135 | ||
135 | let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len()); | 136 | let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len()); |
@@ -137,7 +138,7 @@ impl<'a> InferenceContext<'a> { | |||
137 | 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()); |
138 | inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); | 139 | inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); |
139 | 140 | ||
140 | Ty::Tuple(inner_tys.len(), Substs(inner_tys.into())) | 141 | TyKind::Tuple(inner_tys.len(), Substs(inner_tys.into())).intern(&Interner) |
141 | } | 142 | } |
142 | Pat::Or(ref pats) => { | 143 | Pat::Or(ref pats) => { |
143 | if let Some((first_pat, rest)) = pats.split_first() { | 144 | if let Some((first_pat, rest)) = pats.split_first() { |
@@ -147,7 +148,7 @@ impl<'a> InferenceContext<'a> { | |||
147 | } | 148 | } |
148 | ty | 149 | ty |
149 | } else { | 150 | } else { |
150 | Ty::Unknown | 151 | self.err_ty() |
151 | } | 152 | } |
152 | } | 153 | } |
153 | Pat::Ref { pat, mutability } => { | 154 | Pat::Ref { pat, mutability } => { |
@@ -159,10 +160,10 @@ impl<'a> InferenceContext<'a> { | |||
159 | } | 160 | } |
160 | inner_ty | 161 | inner_ty |
161 | } | 162 | } |
162 | _ => &Ty::Unknown, | 163 | _ => &Ty(TyKind::Unknown), |
163 | }; | 164 | }; |
164 | let subty = self.infer_pat(*pat, expectation, default_bm); | 165 | let subty = self.infer_pat(*pat, expectation, default_bm); |
165 | Ty::Ref(mutability, Substs::single(subty)) | 166 | TyKind::Ref(mutability, Substs::single(subty)).intern(&Interner) |
166 | } | 167 | } |
167 | 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( |
168 | p.as_ref(), | 169 | p.as_ref(), |
@@ -178,7 +179,7 @@ impl<'a> InferenceContext<'a> { | |||
178 | Pat::Path(path) => { | 179 | Pat::Path(path) => { |
179 | // FIXME use correct resolver for the surrounding expression | 180 | // FIXME use correct resolver for the surrounding expression |
180 | let resolver = self.resolver.clone(); | 181 | let resolver = self.resolver.clone(); |
181 | self.infer_path(&resolver, &path, pat.into()).unwrap_or(Ty::Unknown) | 182 | self.infer_path(&resolver, &path, pat.into()).unwrap_or(self.err_ty()) |
182 | } | 183 | } |
183 | Pat::Bind { mode, name: _, subpat } => { | 184 | Pat::Bind { mode, name: _, subpat } => { |
184 | let mode = if mode == &BindingAnnotation::Unannotated { | 185 | let mode = if mode == &BindingAnnotation::Unannotated { |
@@ -195,7 +196,7 @@ impl<'a> InferenceContext<'a> { | |||
195 | 196 | ||
196 | let bound_ty = match mode { | 197 | let bound_ty = match mode { |
197 | BindingMode::Ref(mutability) => { | 198 | BindingMode::Ref(mutability) => { |
198 | Ty::Ref(mutability, Substs::single(inner_ty.clone())) | 199 | TyKind::Ref(mutability, Substs::single(inner_ty.clone())).intern(&Interner) |
199 | } | 200 | } |
200 | BindingMode::Move => inner_ty.clone(), | 201 | BindingMode::Move => inner_ty.clone(), |
201 | }; | 202 | }; |
@@ -204,17 +205,17 @@ impl<'a> InferenceContext<'a> { | |||
204 | return inner_ty; | 205 | return inner_ty; |
205 | } | 206 | } |
206 | Pat::Slice { prefix, slice, suffix } => { | 207 | Pat::Slice { prefix, slice, suffix } => { |
207 | let (container_ty, elem_ty): (fn(_) -> _, _) = match &expected { | 208 | let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.interned(&Interner) { |
208 | Ty::Array(st) => (Ty::Array, st.as_single().clone()), | 209 | TyKind::Array(st) => (TyKind::Array, st.as_single().clone()), |
209 | Ty::Slice(st) => (Ty::Slice, st.as_single().clone()), | 210 | TyKind::Slice(st) => (TyKind::Slice, st.as_single().clone()), |
210 | _ => (Ty::Slice, Ty::Unknown), | 211 | _ => (TyKind::Slice, self.err_ty()), |
211 | }; | 212 | }; |
212 | 213 | ||
213 | for pat_id in prefix.iter().chain(suffix) { | 214 | for pat_id in prefix.iter().chain(suffix) { |
214 | self.infer_pat(*pat_id, &elem_ty, default_bm); | 215 | self.infer_pat(*pat_id, &elem_ty, default_bm); |
215 | } | 216 | } |
216 | 217 | ||
217 | let pat_ty = container_ty(Substs::single(elem_ty)); | 218 | let pat_ty = container_ty(Substs::single(elem_ty)).intern(&Interner); |
218 | if let Some(slice_pat_id) = slice { | 219 | if let Some(slice_pat_id) = slice { |
219 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); | 220 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); |
220 | } | 221 | } |
@@ -232,20 +233,20 @@ impl<'a> InferenceContext<'a> { | |||
232 | Some(box_adt) => { | 233 | Some(box_adt) => { |
233 | let inner_expected = match expected.as_adt() { | 234 | let inner_expected = match expected.as_adt() { |
234 | Some((adt, substs)) if adt == box_adt => substs.as_single(), | 235 | Some((adt, substs)) if adt == box_adt => substs.as_single(), |
235 | _ => &Ty::Unknown, | 236 | _ => &Ty(TyKind::Unknown), |
236 | }; | 237 | }; |
237 | 238 | ||
238 | let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); | 239 | let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); |
239 | Ty::adt_ty(box_adt, Substs::single(inner_ty)) | 240 | Ty::adt_ty(box_adt, Substs::single(inner_ty)) |
240 | } | 241 | } |
241 | None => Ty::Unknown, | 242 | None => self.err_ty(), |
242 | }, | 243 | }, |
243 | Pat::ConstBlock(expr) => { | 244 | Pat::ConstBlock(expr) => { |
244 | self.infer_expr(*expr, &Expectation::has_type(expected.clone())) | 245 | self.infer_expr(*expr, &Expectation::has_type(expected.clone())) |
245 | } | 246 | } |
246 | Pat::Missing => Ty::Unknown, | 247 | Pat::Missing => self.err_ty(), |
247 | }; | 248 | }; |
248 | // use a new type variable if we got Ty::Unknown here | 249 | // use a new type variable if we got error type here |
249 | let ty = self.insert_type_vars_shallow(ty); | 250 | let ty = self.insert_type_vars_shallow(ty); |
250 | if !self.unify(&ty, expected) { | 251 | if !self.unify(&ty, expected) { |
251 | // FIXME record mismatch, we need to change the type of self.type_mismatches for that | 252 | // FIXME record mismatch, we need to change the type of self.type_mismatches for that |
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs index ae3554bac..392952178 100644 --- a/crates/hir_ty/src/infer/path.rs +++ b/crates/hir_ty/src/infer/path.rs | |||
@@ -9,7 +9,7 @@ use hir_def::{ | |||
9 | }; | 9 | }; |
10 | use hir_expand::name::Name; | 10 | use hir_expand::name::Name; |
11 | 11 | ||
12 | use crate::{method_resolution, Substs, Ty, ValueTyDefId}; | 12 | use crate::{method_resolution, Interner, Substs, Ty, TyKind, ValueTyDefId}; |
13 | 13 | ||
14 | use super::{ExprOrPatId, InferenceContext, TraitRef}; | 14 | use super::{ExprOrPatId, InferenceContext, TraitRef}; |
15 | 15 | ||
@@ -144,7 +144,7 @@ impl<'a> InferenceContext<'a> { | |||
144 | remaining_segments_for_ty, | 144 | remaining_segments_for_ty, |
145 | true, | 145 | true, |
146 | ); | 146 | ); |
147 | if let Ty::Unknown = ty { | 147 | if let TyKind::Unknown = ty.interned(&Interner) { |
148 | return None; | 148 | return None; |
149 | } | 149 | } |
150 | 150 | ||
@@ -209,7 +209,7 @@ impl<'a> InferenceContext<'a> { | |||
209 | name: &Name, | 209 | name: &Name, |
210 | id: ExprOrPatId, | 210 | id: ExprOrPatId, |
211 | ) -> Option<(ValueNs, Option<Substs>)> { | 211 | ) -> Option<(ValueNs, Option<Substs>)> { |
212 | if let Ty::Unknown = ty { | 212 | if let TyKind::Unknown = ty.interned(&Interner) { |
213 | return None; | 213 | return None; |
214 | } | 214 | } |
215 | 215 | ||
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 54fcfed10..16d89ed1b 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -7,8 +7,8 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; | |||
7 | 7 | ||
8 | use super::{InferenceContext, Obligation}; | 8 | use super::{InferenceContext, Obligation}; |
9 | use crate::{ | 9 | use crate::{ |
10 | BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferenceVar, Scalar, | 10 | BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferenceVar, Interner, |
11 | Substs, Ty, TypeWalk, | 11 | Scalar, Substs, Ty, TyKind, TypeWalk, |
12 | }; | 12 | }; |
13 | 13 | ||
14 | impl<'a> InferenceContext<'a> { | 14 | impl<'a> InferenceContext<'a> { |
@@ -49,8 +49,8 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { | |||
49 | 49 | ||
50 | fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { | 50 | fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { |
51 | t.fold_binders( | 51 | t.fold_binders( |
52 | &mut |ty, binders| match ty { | 52 | &mut |ty, binders| match ty.interned(&Interner) { |
53 | Ty::InferenceVar(var, kind) => { | 53 | &TyKind::InferenceVar(var, kind) => { |
54 | let inner = var.to_inner(); | 54 | let inner = var.to_inner(); |
55 | if self.var_stack.contains(&inner) { | 55 | if self.var_stack.contains(&inner) { |
56 | // recursive type | 56 | // recursive type |
@@ -66,7 +66,7 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { | |||
66 | } else { | 66 | } else { |
67 | let root = self.ctx.table.var_unification_table.find(inner); | 67 | let root = self.ctx.table.var_unification_table.find(inner); |
68 | let position = self.add(InferenceVar::from_inner(root), kind); | 68 | let position = self.add(InferenceVar::from_inner(root), kind); |
69 | Ty::BoundVar(BoundVar::new(binders, position)) | 69 | TyKind::BoundVar(BoundVar::new(binders, position)).intern(&Interner) |
70 | } | 70 | } |
71 | } | 71 | } |
72 | _ => ty, | 72 | _ => ty, |
@@ -108,10 +108,10 @@ impl<T> Canonicalized<T> { | |||
108 | pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { | 108 | pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { |
109 | ty.walk_mut_binders( | 109 | ty.walk_mut_binders( |
110 | &mut |ty, binders| { | 110 | &mut |ty, binders| { |
111 | if let &mut Ty::BoundVar(bound) = ty { | 111 | if let &mut TyKind::BoundVar(bound) = &mut ty.0 { |
112 | if bound.debruijn >= binders { | 112 | if bound.debruijn >= binders { |
113 | let (v, k) = self.free_vars[bound.index]; | 113 | let (v, k) = self.free_vars[bound.index]; |
114 | *ty = Ty::InferenceVar(v, k); | 114 | *ty = TyKind::InferenceVar(v, k).intern(&Interner); |
115 | } | 115 | } |
116 | } | 116 | } |
117 | }, | 117 | }, |
@@ -142,7 +142,7 @@ impl<T> Canonicalized<T> { | |||
142 | // eagerly replace projections in the type; we may be getting types | 142 | // eagerly replace projections in the type; we may be getting types |
143 | // e.g. from where clauses where this hasn't happened yet | 143 | // e.g. from where clauses where this hasn't happened yet |
144 | let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); | 144 | let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); |
145 | ctx.table.unify(&Ty::InferenceVar(v, k), &ty); | 145 | ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); |
146 | } | 146 | } |
147 | } | 147 | } |
148 | } | 148 | } |
@@ -166,7 +166,10 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> { | |||
166 | // (kind of hacky) | 166 | // (kind of hacky) |
167 | for (i, var) in vars.iter().enumerate() { | 167 | for (i, var) in vars.iter().enumerate() { |
168 | if &*table.resolve_ty_shallow(var) == var { | 168 | if &*table.resolve_ty_shallow(var) == var { |
169 | table.unify(var, &Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i))); | 169 | table.unify( |
170 | var, | ||
171 | &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i)).intern(&Interner), | ||
172 | ); | ||
170 | } | 173 | } |
171 | } | 174 | } |
172 | Some( | 175 | Some( |
@@ -196,11 +199,12 @@ impl TypeVariableTable { | |||
196 | 199 | ||
197 | fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { | 200 | fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { |
198 | match kind { | 201 | match kind { |
199 | _ if self.inner[iv.to_inner().0 as usize].diverging => Ty::Never, | 202 | _ if self.inner[iv.to_inner().0 as usize].diverging => TyKind::Never, |
200 | TyVariableKind::General => Ty::Unknown, | 203 | TyVariableKind::General => TyKind::Unknown, |
201 | TyVariableKind::Integer => Ty::Scalar(Scalar::Int(IntTy::I32)), | 204 | TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)), |
202 | TyVariableKind::Float => Ty::Scalar(Scalar::Float(FloatTy::F64)), | 205 | TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)), |
203 | } | 206 | } |
207 | .intern(&Interner) | ||
204 | } | 208 | } |
205 | } | 209 | } |
206 | 210 | ||
@@ -227,7 +231,7 @@ impl InferenceTable { | |||
227 | self.type_variable_table.push(TypeVariableData { diverging }); | 231 | self.type_variable_table.push(TypeVariableData { diverging }); |
228 | let key = self.var_unification_table.new_key(TypeVarValue::Unknown); | 232 | let key = self.var_unification_table.new_key(TypeVarValue::Unknown); |
229 | assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1); | 233 | assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1); |
230 | Ty::InferenceVar(InferenceVar::from_inner(key), kind) | 234 | TyKind::InferenceVar(InferenceVar::from_inner(key), kind).intern(&Interner) |
231 | } | 235 | } |
232 | 236 | ||
233 | pub(crate) fn new_type_var(&mut self) -> Ty { | 237 | pub(crate) fn new_type_var(&mut self) -> Ty { |
@@ -290,12 +294,12 @@ impl InferenceTable { | |||
290 | } | 294 | } |
291 | 295 | ||
292 | pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { | 296 | pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { |
293 | match (ty1, ty2) { | 297 | match (ty1.interned(&Interner), ty2.interned(&Interner)) { |
294 | (Ty::Unknown, _) | (_, Ty::Unknown) => true, | 298 | (TyKind::Unknown, _) | (_, TyKind::Unknown) => true, |
295 | 299 | ||
296 | (Ty::Placeholder(p1), Ty::Placeholder(p2)) if *p1 == *p2 => true, | 300 | (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, |
297 | 301 | ||
298 | (Ty::Dyn(dyn1), Ty::Dyn(dyn2)) if dyn1.len() == dyn2.len() => { | 302 | (TyKind::Dyn(dyn1), TyKind::Dyn(dyn2)) if dyn1.len() == dyn2.len() => { |
299 | for (pred1, pred2) in dyn1.iter().zip(dyn2.iter()) { | 303 | for (pred1, pred2) in dyn1.iter().zip(dyn2.iter()) { |
300 | if !self.unify_preds(pred1, pred2, depth + 1) { | 304 | if !self.unify_preds(pred1, pred2, depth + 1) { |
301 | return false; | 305 | return false; |
@@ -305,16 +309,16 @@ impl InferenceTable { | |||
305 | } | 309 | } |
306 | 310 | ||
307 | ( | 311 | ( |
308 | Ty::InferenceVar(tv1, TyVariableKind::General), | 312 | TyKind::InferenceVar(tv1, TyVariableKind::General), |
309 | Ty::InferenceVar(tv2, TyVariableKind::General), | 313 | TyKind::InferenceVar(tv2, TyVariableKind::General), |
310 | ) | 314 | ) |
311 | | ( | 315 | | ( |
312 | Ty::InferenceVar(tv1, TyVariableKind::Integer), | 316 | TyKind::InferenceVar(tv1, TyVariableKind::Integer), |
313 | Ty::InferenceVar(tv2, TyVariableKind::Integer), | 317 | TyKind::InferenceVar(tv2, TyVariableKind::Integer), |
314 | ) | 318 | ) |
315 | | ( | 319 | | ( |
316 | Ty::InferenceVar(tv1, TyVariableKind::Float), | 320 | TyKind::InferenceVar(tv1, TyVariableKind::Float), |
317 | Ty::InferenceVar(tv2, TyVariableKind::Float), | 321 | TyKind::InferenceVar(tv2, TyVariableKind::Float), |
318 | ) if self.type_variable_table.is_diverging(*tv1) | 322 | ) if self.type_variable_table.is_diverging(*tv1) |
319 | == self.type_variable_table.is_diverging(*tv2) => | 323 | == self.type_variable_table.is_diverging(*tv2) => |
320 | { | 324 | { |
@@ -326,24 +330,37 @@ impl InferenceTable { | |||
326 | // The order of MaybeNeverTypeVar matters here. | 330 | // The order of MaybeNeverTypeVar matters here. |
327 | // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. | 331 | // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. |
328 | // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. | 332 | // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. |
329 | (Ty::InferenceVar(tv, TyVariableKind::General), other) | 333 | (TyKind::InferenceVar(tv, TyVariableKind::General), other) |
330 | | (other, Ty::InferenceVar(tv, TyVariableKind::General)) | 334 | | (other, TyKind::InferenceVar(tv, TyVariableKind::General)) |
331 | | (Ty::InferenceVar(tv, TyVariableKind::Integer), other @ Ty::Scalar(Scalar::Int(_))) | ||
332 | | (other @ Ty::Scalar(Scalar::Int(_)), Ty::InferenceVar(tv, TyVariableKind::Integer)) | ||
333 | | ( | 335 | | ( |
334 | Ty::InferenceVar(tv, TyVariableKind::Integer), | 336 | TyKind::InferenceVar(tv, TyVariableKind::Integer), |
335 | other @ Ty::Scalar(Scalar::Uint(_)), | 337 | other @ TyKind::Scalar(Scalar::Int(_)), |
336 | ) | 338 | ) |
337 | | ( | 339 | | ( |
338 | other @ Ty::Scalar(Scalar::Uint(_)), | 340 | other @ TyKind::Scalar(Scalar::Int(_)), |
339 | Ty::InferenceVar(tv, TyVariableKind::Integer), | 341 | TyKind::InferenceVar(tv, TyVariableKind::Integer), |
340 | ) | 342 | ) |
341 | | (Ty::InferenceVar(tv, TyVariableKind::Float), other @ Ty::Scalar(Scalar::Float(_))) | 343 | | ( |
342 | | (other @ Ty::Scalar(Scalar::Float(_)), Ty::InferenceVar(tv, TyVariableKind::Float)) => | 344 | TyKind::InferenceVar(tv, TyVariableKind::Integer), |
343 | { | 345 | other @ TyKind::Scalar(Scalar::Uint(_)), |
346 | ) | ||
347 | | ( | ||
348 | other @ TyKind::Scalar(Scalar::Uint(_)), | ||
349 | TyKind::InferenceVar(tv, TyVariableKind::Integer), | ||
350 | ) | ||
351 | | ( | ||
352 | TyKind::InferenceVar(tv, TyVariableKind::Float), | ||
353 | other @ TyKind::Scalar(Scalar::Float(_)), | ||
354 | ) | ||
355 | | ( | ||
356 | other @ TyKind::Scalar(Scalar::Float(_)), | ||
357 | TyKind::InferenceVar(tv, TyVariableKind::Float), | ||
358 | ) => { | ||
344 | // the type var is unknown since we tried to resolve it | 359 | // the type var is unknown since we tried to resolve it |
345 | self.var_unification_table | 360 | self.var_unification_table.union_value( |
346 | .union_value(tv.to_inner(), TypeVarValue::Known(other.clone())); | 361 | tv.to_inner(), |
362 | TypeVarValue::Known(other.clone().intern(&Interner)), | ||
363 | ); | ||
347 | true | 364 | true |
348 | } | 365 | } |
349 | 366 | ||
@@ -387,8 +404,8 @@ impl InferenceTable { | |||
387 | if i > 0 { | 404 | if i > 0 { |
388 | cov_mark::hit!(type_var_resolves_to_int_var); | 405 | cov_mark::hit!(type_var_resolves_to_int_var); |
389 | } | 406 | } |
390 | match &*ty { | 407 | match &ty.0 { |
391 | Ty::InferenceVar(tv, _) => { | 408 | TyKind::InferenceVar(tv, _) => { |
392 | let inner = tv.to_inner(); | 409 | let inner = tv.to_inner(); |
393 | match self.var_unification_table.inlined_probe_value(inner).known() { | 410 | match self.var_unification_table.inlined_probe_value(inner).known() { |
394 | Some(known_ty) => { | 411 | Some(known_ty) => { |
@@ -410,8 +427,8 @@ impl InferenceTable { | |||
410 | /// be resolved as far as possible, i.e. contain no type variables with | 427 | /// be resolved as far as possible, i.e. contain no type variables with |
411 | /// known type. | 428 | /// known type. |
412 | fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | 429 | fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { |
413 | ty.fold(&mut |ty| match ty { | 430 | ty.fold(&mut |ty| match ty.interned(&Interner) { |
414 | Ty::InferenceVar(tv, kind) => { | 431 | &TyKind::InferenceVar(tv, kind) => { |
415 | let inner = tv.to_inner(); | 432 | let inner = tv.to_inner(); |
416 | if tv_stack.contains(&inner) { | 433 | if tv_stack.contains(&inner) { |
417 | cov_mark::hit!(type_var_cycles_resolve_as_possible); | 434 | cov_mark::hit!(type_var_cycles_resolve_as_possible); |
@@ -435,10 +452,10 @@ impl InferenceTable { | |||
435 | } | 452 | } |
436 | 453 | ||
437 | /// Resolves the type completely; type variables without known type are | 454 | /// Resolves the type completely; type variables without known type are |
438 | /// replaced by Ty::Unknown. | 455 | /// replaced by TyKind::Unknown. |
439 | fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | 456 | fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { |
440 | ty.fold(&mut |ty| match ty { | 457 | ty.fold(&mut |ty| match ty.interned(&Interner) { |
441 | Ty::InferenceVar(tv, kind) => { | 458 | &TyKind::InferenceVar(tv, kind) => { |
442 | let inner = tv.to_inner(); | 459 | let inner = tv.to_inner(); |
443 | if tv_stack.contains(&inner) { | 460 | if tv_stack.contains(&inner) { |
444 | cov_mark::hit!(type_var_cycles_resolve_completely); | 461 | cov_mark::hit!(type_var_cycles_resolve_completely); |