diff options
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 79 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 245 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 27 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 38 |
4 files changed, 163 insertions, 226 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 32c7c57cd..4cca35904 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs | |||
@@ -7,7 +7,7 @@ | |||
7 | use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; | 7 | use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; |
8 | use test_utils::mark; | 8 | use test_utils::mark; |
9 | 9 | ||
10 | use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty, TypeCtor}; | 10 | use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty}; |
11 | 11 | ||
12 | use super::{unify::TypeVarValue, InEnvironment, InferTy, InferenceContext}; | 12 | use super::{unify::TypeVarValue, InEnvironment, InferTy, InferenceContext}; |
13 | 13 | ||
@@ -33,7 +33,7 @@ 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_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnDef(_))) = (ty1, ty2) { | 36 | if let (Ty::FnDef(..), Ty::FnDef(..)) = (ty1, ty2) { |
37 | mark::hit!(coerce_fn_reification); | 37 | mark::hit!(coerce_fn_reification); |
38 | // Special case: two function types. Try to coerce both to | 38 | // Special case: two function types. Try to coerce both to |
39 | // pointers to have a chance at getting a match. See | 39 | // pointers to have a chance at getting a match. See |
@@ -53,12 +53,12 @@ impl<'a> InferenceContext<'a> { | |||
53 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { | 53 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { |
54 | match (&from_ty, to_ty) { | 54 | match (&from_ty, to_ty) { |
55 | // Never type will make type variable to fallback to Never Type instead of Unknown. | 55 | // Never type will make type variable to fallback to Never Type instead of Unknown. |
56 | (ty_app!(TypeCtor::Never), Ty::Infer(InferTy::TypeVar(tv))) => { | 56 | (Ty::Never, Ty::Infer(InferTy::TypeVar(tv))) => { |
57 | let var = self.table.new_maybe_never_type_var(); | 57 | let var = self.table.new_maybe_never_type_var(); |
58 | self.table.var_unification_table.union_value(*tv, TypeVarValue::Known(var)); | 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::RawPtr(m1, ..), Ty::RawPtr(m2 @ Mutability::Shared, ..)) |
77 | (ty_app!(c1@TypeCtor::RawPtr(_)), ty_app!(c2@TypeCtor::RawPtr(Mutability::Shared))) | 77 | | (Ty::Ref(m1, ..), Ty::Ref(m2 @ Mutability::Shared, ..)) => { |
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::RawPtr(m2 @ Mutability::Shared, ..)) | ||
83 | | (Ty::Ref(Mutability::Mut, substs), &Ty::RawPtr(m2, ..)) => { | ||
84 | from_ty = Ty::RawPtr(m2, substs.clone()); | ||
82 | } | 85 | } |
83 | 86 | ||
84 | // Illegal mutablity conversion | 87 | // Illegal mutability conversion |
85 | ( | 88 | (Ty::RawPtr(Mutability::Shared, ..), Ty::RawPtr(Mutability::Mut, ..)) |
86 | ty_app!(TypeCtor::RawPtr(Mutability::Shared)), | 89 | | (Ty::Ref(Mutability::Shared, ..), 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 3fec0e431..23d4ac8ef 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -18,8 +18,8 @@ use crate::{ | |||
18 | primitive::{self, UintTy}, | 18 | primitive::{self, UintTy}, |
19 | traits::{FnTrait, InEnvironment}, | 19 | traits::{FnTrait, InEnvironment}, |
20 | utils::{generics, variant_data, Generics}, | 20 | utils::{generics, variant_data, Generics}, |
21 | ApplicationTy, Binders, CallableDefId, InferTy, Mutability, Obligation, OpaqueTyId, Rawness, | 21 | Binders, CallableDefId, FnPointer, FnSig, InferTy, Mutability, Obligation, OpaqueTyId, Rawness, |
22 | Scalar, Substs, TraitRef, Ty, TypeCtor, | 22 | Scalar, Substs, TraitRef, Ty, |
23 | }; | 23 | }; |
24 | 24 | ||
25 | use super::{ | 25 | use super::{ |
@@ -82,10 +82,7 @@ impl<'a> InferenceContext<'a> { | |||
82 | arg_tys.push(arg); | 82 | arg_tys.push(arg); |
83 | } | 83 | } |
84 | let parameters = param_builder.build(); | 84 | let parameters = param_builder.build(); |
85 | let arg_ty = Ty::Apply(ApplicationTy { | 85 | let arg_ty = Ty::Tuple(num_args, parameters); |
86 | ctor: TypeCtor::Tuple { cardinality: num_args as u16 }, | ||
87 | parameters, | ||
88 | }); | ||
89 | let substs = | 86 | let substs = |
90 | Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); | 87 | Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); |
91 | 88 | ||
@@ -120,10 +117,7 @@ impl<'a> InferenceContext<'a> { | |||
120 | Expr::Missing => Ty::Unknown, | 117 | Expr::Missing => Ty::Unknown, |
121 | Expr::If { condition, then_branch, else_branch } => { | 118 | Expr::If { condition, then_branch, else_branch } => { |
122 | // if let is desugared to match, so this is always simple if | 119 | // if let is desugared to match, so this is always simple if |
123 | self.infer_expr( | 120 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); |
124 | *condition, | ||
125 | &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))), | ||
126 | ); | ||
127 | 121 | ||
128 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); | 122 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); |
129 | let mut both_arms_diverge = Diverges::Always; | 123 | let mut both_arms_diverge = Diverges::Always; |
@@ -178,7 +172,7 @@ impl<'a> InferenceContext<'a> { | |||
178 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> | 172 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> |
179 | let inner_ty = self.infer_expr(*body, &Expectation::none()); | 173 | let inner_ty = self.infer_expr(*body, &Expectation::none()); |
180 | let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); | 174 | let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); |
181 | Ty::apply_one(TypeCtor::OpaqueType(opaque_ty_id), inner_ty) | 175 | Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty)) |
182 | } | 176 | } |
183 | Expr::Loop { body, label } => { | 177 | Expr::Loop { body, label } => { |
184 | self.breakables.push(BreakableContext { | 178 | self.breakables.push(BreakableContext { |
@@ -196,7 +190,7 @@ impl<'a> InferenceContext<'a> { | |||
196 | if ctxt.may_break { | 190 | if ctxt.may_break { |
197 | ctxt.break_ty | 191 | ctxt.break_ty |
198 | } else { | 192 | } else { |
199 | Ty::simple(TypeCtor::Never) | 193 | Ty::Never |
200 | } | 194 | } |
201 | } | 195 | } |
202 | Expr::While { condition, body, label } => { | 196 | Expr::While { condition, body, label } => { |
@@ -206,10 +200,7 @@ impl<'a> InferenceContext<'a> { | |||
206 | label: label.map(|label| self.body[label].name.clone()), | 200 | label: label.map(|label| self.body[label].name.clone()), |
207 | }); | 201 | }); |
208 | // while let is desugared to a match loop, so this is always simple while | 202 | // while let is desugared to a match loop, so this is always simple while |
209 | self.infer_expr( | 203 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); |
210 | *condition, | ||
211 | &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))), | ||
212 | ); | ||
213 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 204 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
214 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); | 205 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); |
215 | // the body may not run, so it diverging doesn't mean we diverge | 206 | // the body may not run, so it diverging doesn't mean we diverge |
@@ -256,12 +247,12 @@ impl<'a> InferenceContext<'a> { | |||
256 | None => self.table.new_type_var(), | 247 | None => self.table.new_type_var(), |
257 | }; | 248 | }; |
258 | sig_tys.push(ret_ty.clone()); | 249 | sig_tys.push(ret_ty.clone()); |
259 | let sig_ty = Ty::apply( | 250 | let sig_ty = Ty::Function(FnPointer { |
260 | TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1, is_varargs: false }, | 251 | num_args: sig_tys.len() - 1, |
261 | Substs(sig_tys.clone().into()), | 252 | sig: FnSig { variadic: false }, |
262 | ); | 253 | substs: Substs(sig_tys.clone().into()), |
263 | let closure_ty = | 254 | }); |
264 | Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); | 255 | let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty)); |
265 | 256 | ||
266 | // Eagerly try to relate the closure type with the expected | 257 | // Eagerly try to relate the closure type with the expected |
267 | // type, otherwise we often won't have enough information to | 258 | // type, otherwise we often won't have enough information to |
@@ -312,11 +303,8 @@ impl<'a> InferenceContext<'a> { | |||
312 | Expr::Match { expr, arms } => { | 303 | Expr::Match { expr, arms } => { |
313 | let input_ty = self.infer_expr(*expr, &Expectation::none()); | 304 | let input_ty = self.infer_expr(*expr, &Expectation::none()); |
314 | 305 | ||
315 | let mut result_ty = if arms.is_empty() { | 306 | let mut result_ty = |
316 | Ty::simple(TypeCtor::Never) | 307 | if arms.is_empty() { Ty::Never } else { self.table.new_type_var() }; |
317 | } else { | ||
318 | self.table.new_type_var() | ||
319 | }; | ||
320 | 308 | ||
321 | let matchee_diverges = self.diverges; | 309 | let matchee_diverges = self.diverges; |
322 | let mut all_arms_diverge = Diverges::Always; | 310 | let mut all_arms_diverge = Diverges::Always; |
@@ -327,7 +315,7 @@ impl<'a> InferenceContext<'a> { | |||
327 | if let Some(guard_expr) = arm.guard { | 315 | if let Some(guard_expr) = arm.guard { |
328 | self.infer_expr( | 316 | self.infer_expr( |
329 | guard_expr, | 317 | guard_expr, |
330 | &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))), | 318 | &Expectation::has_type(Ty::Scalar(Scalar::Bool)), |
331 | ); | 319 | ); |
332 | } | 320 | } |
333 | 321 | ||
@@ -345,7 +333,7 @@ impl<'a> InferenceContext<'a> { | |||
345 | let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); | 333 | let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); |
346 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) | 334 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) |
347 | } | 335 | } |
348 | Expr::Continue { .. } => Ty::simple(TypeCtor::Never), | 336 | Expr::Continue { .. } => Ty::Never, |
349 | Expr::Break { expr, label } => { | 337 | Expr::Break { expr, label } => { |
350 | let val_ty = if let Some(expr) = expr { | 338 | let val_ty = if let Some(expr) = expr { |
351 | self.infer_expr(*expr, &Expectation::none()) | 339 | self.infer_expr(*expr, &Expectation::none()) |
@@ -370,8 +358,7 @@ impl<'a> InferenceContext<'a> { | |||
370 | expr: tgt_expr, | 358 | expr: tgt_expr, |
371 | }); | 359 | }); |
372 | } | 360 | } |
373 | 361 | Ty::Never | |
374 | Ty::simple(TypeCtor::Never) | ||
375 | } | 362 | } |
376 | Expr::Return { expr } => { | 363 | Expr::Return { expr } => { |
377 | if let Some(expr) = expr { | 364 | if let Some(expr) = expr { |
@@ -380,14 +367,14 @@ impl<'a> InferenceContext<'a> { | |||
380 | let unit = Ty::unit(); | 367 | let unit = Ty::unit(); |
381 | self.coerce(&unit, &self.return_ty.clone()); | 368 | self.coerce(&unit, &self.return_ty.clone()); |
382 | } | 369 | } |
383 | Ty::simple(TypeCtor::Never) | 370 | Ty::Never |
384 | } | 371 | } |
385 | Expr::Yield { expr } => { | 372 | Expr::Yield { expr } => { |
386 | // FIXME: track yield type for coercion | 373 | // FIXME: track yield type for coercion |
387 | if let Some(expr) = expr { | 374 | if let Some(expr) = expr { |
388 | self.infer_expr(*expr, &Expectation::none()); | 375 | self.infer_expr(*expr, &Expectation::none()); |
389 | } | 376 | } |
390 | Ty::simple(TypeCtor::Never) | 377 | Ty::Never |
391 | } | 378 | } |
392 | Expr::RecordLit { path, fields, spread } => { | 379 | Expr::RecordLit { path, fields, spread } => { |
393 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 380 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
@@ -397,7 +384,7 @@ impl<'a> InferenceContext<'a> { | |||
397 | 384 | ||
398 | self.unify(&ty, &expected.ty); | 385 | self.unify(&ty, &expected.ty); |
399 | 386 | ||
400 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 387 | let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); |
401 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); | 388 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); |
402 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); | 389 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); |
403 | for (field_idx, field) in fields.iter().enumerate() { | 390 | for (field_idx, field) in fields.iter().enumerate() { |
@@ -436,30 +423,23 @@ impl<'a> InferenceContext<'a> { | |||
436 | }, | 423 | }, |
437 | ) | 424 | ) |
438 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { | 425 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { |
439 | Ty::Apply(a_ty) => match a_ty.ctor { | 426 | Ty::Tuple(_, substs) => { |
440 | TypeCtor::Tuple { .. } => name | 427 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) |
441 | .as_tuple_index() | 428 | } |
442 | .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), | 429 | Ty::Adt(AdtId::StructId(s), parameters) => { |
443 | TypeCtor::Adt(AdtId::StructId(s)) => { | 430 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { |
444 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { | 431 | let field = FieldId { parent: s.into(), local_id }; |
445 | let field = FieldId { parent: s.into(), local_id }; | 432 | self.write_field_resolution(tgt_expr, field); |
446 | self.write_field_resolution(tgt_expr, field); | 433 | self.db.field_types(s.into())[field.local_id].clone().subst(¶meters) |
447 | self.db.field_types(s.into())[field.local_id] | 434 | }) |
448 | .clone() | 435 | } |
449 | .subst(&a_ty.parameters) | 436 | Ty::Adt(AdtId::UnionId(u), parameters) => { |
450 | }) | 437 | self.db.union_data(u).variant_data.field(name).map(|local_id| { |
451 | } | 438 | let field = FieldId { parent: u.into(), local_id }; |
452 | TypeCtor::Adt(AdtId::UnionId(u)) => { | 439 | self.write_field_resolution(tgt_expr, field); |
453 | self.db.union_data(u).variant_data.field(name).map(|local_id| { | 440 | self.db.field_types(u.into())[field.local_id].clone().subst(¶meters) |
454 | let field = FieldId { parent: u.into(), local_id }; | 441 | }) |
455 | self.write_field_resolution(tgt_expr, field); | 442 | } |
456 | self.db.field_types(u.into())[field.local_id] | ||
457 | .clone() | ||
458 | .subst(&a_ty.parameters) | ||
459 | }) | ||
460 | } | ||
461 | _ => None, | ||
462 | }, | ||
463 | _ => None, | 443 | _ => None, |
464 | }) | 444 | }) |
465 | .unwrap_or(Ty::Unknown); | 445 | .unwrap_or(Ty::Unknown); |
@@ -497,19 +477,24 @@ impl<'a> InferenceContext<'a> { | |||
497 | Expectation::none() | 477 | Expectation::none() |
498 | }; | 478 | }; |
499 | let inner_ty = self.infer_expr_inner(*expr, &expectation); | 479 | let inner_ty = self.infer_expr_inner(*expr, &expectation); |
500 | let ty = match rawness { | 480 | match rawness { |
501 | Rawness::RawPtr => TypeCtor::RawPtr(*mutability), | 481 | Rawness::RawPtr => Ty::RawPtr(*mutability, Substs::single(inner_ty)), |
502 | Rawness::Ref => TypeCtor::Ref(*mutability), | 482 | Rawness::Ref => Ty::Ref(*mutability, Substs::single(inner_ty)), |
503 | }; | 483 | } |
504 | Ty::apply_one(ty, inner_ty) | ||
505 | } | 484 | } |
506 | Expr::Box { expr } => { | 485 | Expr::Box { expr } => { |
507 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 486 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
508 | if let Some(box_) = self.resolve_boxed_box() { | 487 | if let Some(box_) = self.resolve_boxed_box() { |
509 | let mut sb = Substs::build_for_type_ctor(self.db, TypeCtor::Adt(box_)); | 488 | let mut sb = Substs::builder(generics(self.db.upcast(), box_.into()).len()); |
510 | sb = sb.push(inner_ty); | 489 | sb = sb.push(inner_ty); |
490 | match self.db.generic_defaults(box_.into()).as_ref() { | ||
491 | [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => { | ||
492 | sb = sb.push(alloc_ty.value.clone()); | ||
493 | } | ||
494 | _ => (), | ||
495 | } | ||
511 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); | 496 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); |
512 | Ty::apply(TypeCtor::Adt(box_), sb.build()) | 497 | Ty::Adt(box_, sb.build()) |
513 | } else { | 498 | } else { |
514 | Ty::Unknown | 499 | Ty::Unknown |
515 | } | 500 | } |
@@ -539,14 +524,9 @@ impl<'a> InferenceContext<'a> { | |||
539 | UnaryOp::Neg => { | 524 | UnaryOp::Neg => { |
540 | match &inner_ty { | 525 | match &inner_ty { |
541 | // Fast path for builtins | 526 | // Fast path for builtins |
542 | Ty::Apply(ApplicationTy { | 527 | Ty::Scalar(Scalar::Int(_)) |
543 | ctor: TypeCtor::Scalar(Scalar::Int(_)), | 528 | | Ty::Scalar(Scalar::Uint(_)) |
544 | .. | 529 | | Ty::Scalar(Scalar::Float(_)) |
545 | }) | ||
546 | | Ty::Apply(ApplicationTy { | ||
547 | ctor: TypeCtor::Scalar(Scalar::Float(_)), | ||
548 | .. | ||
549 | }) | ||
550 | | Ty::Infer(InferTy::IntVar(..)) | 530 | | Ty::Infer(InferTy::IntVar(..)) |
551 | | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, | 531 | | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, |
552 | // Otherwise we resolve via the std::ops::Neg trait | 532 | // Otherwise we resolve via the std::ops::Neg trait |
@@ -557,18 +537,9 @@ impl<'a> InferenceContext<'a> { | |||
557 | UnaryOp::Not => { | 537 | UnaryOp::Not => { |
558 | match &inner_ty { | 538 | match &inner_ty { |
559 | // Fast path for builtins | 539 | // Fast path for builtins |
560 | Ty::Apply(ApplicationTy { | 540 | Ty::Scalar(Scalar::Bool) |
561 | ctor: TypeCtor::Scalar(Scalar::Bool), | 541 | | Ty::Scalar(Scalar::Int(_)) |
562 | .. | 542 | | Ty::Scalar(Scalar::Uint(_)) |
563 | }) | ||
564 | | Ty::Apply(ApplicationTy { | ||
565 | ctor: TypeCtor::Scalar(Scalar::Int(_)), | ||
566 | .. | ||
567 | }) | ||
568 | | Ty::Apply(ApplicationTy { | ||
569 | ctor: TypeCtor::Scalar(Scalar::Uint(_)), | ||
570 | .. | ||
571 | }) | ||
572 | | Ty::Infer(InferTy::IntVar(..)) => inner_ty, | 543 | | Ty::Infer(InferTy::IntVar(..)) => inner_ty, |
573 | // Otherwise we resolve via the std::ops::Not trait | 544 | // Otherwise we resolve via the std::ops::Not trait |
574 | _ => self | 545 | _ => self |
@@ -580,9 +551,7 @@ impl<'a> InferenceContext<'a> { | |||
580 | Expr::BinaryOp { lhs, rhs, op } => match op { | 551 | Expr::BinaryOp { lhs, rhs, op } => match op { |
581 | Some(op) => { | 552 | Some(op) => { |
582 | let lhs_expectation = match op { | 553 | let lhs_expectation = match op { |
583 | BinaryOp::LogicOp(..) => { | 554 | BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)), |
584 | Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))) | ||
585 | } | ||
586 | _ => Expectation::none(), | 555 | _ => Expectation::none(), |
587 | }; | 556 | }; |
588 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); | 557 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); |
@@ -613,31 +582,31 @@ impl<'a> InferenceContext<'a> { | |||
613 | let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); | 582 | let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); |
614 | match (range_type, lhs_ty, rhs_ty) { | 583 | match (range_type, lhs_ty, rhs_ty) { |
615 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { | 584 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { |
616 | Some(adt) => Ty::simple(TypeCtor::Adt(adt)), | 585 | Some(adt) => Ty::Adt(adt, Substs::empty()), |
617 | None => Ty::Unknown, | 586 | None => Ty::Unknown, |
618 | }, | 587 | }, |
619 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { | 588 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { |
620 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 589 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
621 | None => Ty::Unknown, | 590 | None => Ty::Unknown, |
622 | }, | 591 | }, |
623 | (RangeOp::Inclusive, None, Some(ty)) => { | 592 | (RangeOp::Inclusive, None, Some(ty)) => { |
624 | match self.resolve_range_to_inclusive() { | 593 | match self.resolve_range_to_inclusive() { |
625 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 594 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
626 | None => Ty::Unknown, | 595 | None => Ty::Unknown, |
627 | } | 596 | } |
628 | } | 597 | } |
629 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { | 598 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { |
630 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 599 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
631 | None => Ty::Unknown, | 600 | None => Ty::Unknown, |
632 | }, | 601 | }, |
633 | (RangeOp::Inclusive, Some(_), Some(ty)) => { | 602 | (RangeOp::Inclusive, Some(_), Some(ty)) => { |
634 | match self.resolve_range_inclusive() { | 603 | match self.resolve_range_inclusive() { |
635 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 604 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
636 | None => Ty::Unknown, | 605 | None => Ty::Unknown, |
637 | } | 606 | } |
638 | } | 607 | } |
639 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { | 608 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { |
640 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 609 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
641 | None => Ty::Unknown, | 610 | None => Ty::Unknown, |
642 | }, | 611 | }, |
643 | (RangeOp::Inclusive, _, None) => Ty::Unknown, | 612 | (RangeOp::Inclusive, _, None) => Ty::Unknown, |
@@ -671,7 +640,7 @@ impl<'a> InferenceContext<'a> { | |||
671 | } | 640 | } |
672 | Expr::Tuple { exprs } => { | 641 | Expr::Tuple { exprs } => { |
673 | let mut tys = match &expected.ty { | 642 | let mut tys = match &expected.ty { |
674 | ty_app!(TypeCtor::Tuple { .. }, st) => st | 643 | Ty::Tuple(_, substs) => substs |
675 | .iter() | 644 | .iter() |
676 | .cloned() | 645 | .cloned() |
677 | .chain(repeat_with(|| self.table.new_type_var())) | 646 | .chain(repeat_with(|| self.table.new_type_var())) |
@@ -684,15 +653,11 @@ impl<'a> InferenceContext<'a> { | |||
684 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); | 653 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); |
685 | } | 654 | } |
686 | 655 | ||
687 | Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into())) | 656 | Ty::Tuple(tys.len(), Substs(tys.into())) |
688 | } | 657 | } |
689 | Expr::Array(array) => { | 658 | Expr::Array(array) => { |
690 | let elem_ty = match &expected.ty { | 659 | let elem_ty = match &expected.ty { |
691 | // FIXME: remove when https://github.com/rust-lang/rust/issues/80501 is fixed | 660 | Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(), |
692 | #[allow(unreachable_patterns)] | ||
693 | ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => { | ||
694 | st.as_single().clone() | ||
695 | } | ||
696 | _ => self.table.new_type_var(), | 661 | _ => self.table.new_type_var(), |
697 | }; | 662 | }; |
698 | 663 | ||
@@ -709,42 +674,38 @@ impl<'a> InferenceContext<'a> { | |||
709 | ); | 674 | ); |
710 | self.infer_expr( | 675 | self.infer_expr( |
711 | *repeat, | 676 | *repeat, |
712 | &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Uint( | 677 | &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))), |
713 | UintTy::Usize, | ||
714 | )))), | ||
715 | ); | 678 | ); |
716 | } | 679 | } |
717 | } | 680 | } |
718 | 681 | ||
719 | Ty::apply_one(TypeCtor::Array, elem_ty) | 682 | Ty::Array(Substs::single(elem_ty)) |
720 | } | 683 | } |
721 | Expr::Literal(lit) => match lit { | 684 | Expr::Literal(lit) => match lit { |
722 | Literal::Bool(..) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)), | 685 | Literal::Bool(..) => Ty::Scalar(Scalar::Bool), |
723 | Literal::String(..) => { | 686 | Literal::String(..) => Ty::Ref(Mutability::Shared, Substs::single(Ty::Str)), |
724 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str)) | ||
725 | } | ||
726 | Literal::ByteString(..) => { | 687 | Literal::ByteString(..) => { |
727 | let byte_type = Ty::simple(TypeCtor::Scalar(Scalar::Uint(UintTy::U8))); | 688 | let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8)); |
728 | let array_type = Ty::apply_one(TypeCtor::Array, byte_type); | 689 | let array_type = Ty::Array(Substs::single(byte_type)); |
729 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) | 690 | Ty::Ref(Mutability::Shared, Substs::single(array_type)) |
730 | } | 691 | } |
731 | Literal::Char(..) => Ty::simple(TypeCtor::Scalar(Scalar::Char)), | 692 | Literal::Char(..) => Ty::Scalar(Scalar::Char), |
732 | Literal::Int(_v, ty) => match ty { | 693 | Literal::Int(_v, ty) => match ty { |
733 | Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Int( | 694 | Some(int_ty) => { |
734 | primitive::int_ty_from_builtin(*int_ty), | 695 | Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty))) |
735 | ))), | 696 | } |
736 | None => self.table.new_integer_var(), | 697 | None => self.table.new_integer_var(), |
737 | }, | 698 | }, |
738 | Literal::Uint(_v, ty) => match ty { | 699 | Literal::Uint(_v, ty) => match ty { |
739 | Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Uint( | 700 | Some(int_ty) => { |
740 | primitive::uint_ty_from_builtin(*int_ty), | 701 | Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty))) |
741 | ))), | 702 | } |
742 | None => self.table.new_integer_var(), | 703 | None => self.table.new_integer_var(), |
743 | }, | 704 | }, |
744 | Literal::Float(_v, ty) => match ty { | 705 | Literal::Float(_v, ty) => match ty { |
745 | Some(float_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Float( | 706 | Some(float_ty) => { |
746 | primitive::float_ty_from_builtin(*float_ty), | 707 | Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty))) |
747 | ))), | 708 | } |
748 | None => self.table.new_float_var(), | 709 | None => self.table.new_float_var(), |
749 | }, | 710 | }, |
750 | }, | 711 | }, |
@@ -857,7 +818,7 @@ impl<'a> InferenceContext<'a> { | |||
857 | // Apply autoref so the below unification works correctly | 818 | // Apply autoref so the below unification works correctly |
858 | // FIXME: return correct autorefs from lookup_method | 819 | // FIXME: return correct autorefs from lookup_method |
859 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { | 820 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { |
860 | Some((_, mutability)) => Ty::apply_one(TypeCtor::Ref(mutability), derefed_receiver_ty), | 821 | Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)), |
861 | _ => derefed_receiver_ty, | 822 | _ => derefed_receiver_ty, |
862 | }; | 823 | }; |
863 | self.unify(&expected_receiver_ty, &actual_receiver_ty); | 824 | self.unify(&expected_receiver_ty, &actual_receiver_ty); |
@@ -934,30 +895,26 @@ impl<'a> InferenceContext<'a> { | |||
934 | } | 895 | } |
935 | 896 | ||
936 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { | 897 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { |
937 | if let Ty::Apply(a_ty) = callable_ty { | 898 | if let &Ty::FnDef(def, ref parameters) = callable_ty { |
938 | if let TypeCtor::FnDef(def) = a_ty.ctor { | 899 | let generic_predicates = self.db.generic_predicates(def.into()); |
939 | let generic_predicates = self.db.generic_predicates(def.into()); | 900 | for predicate in generic_predicates.iter() { |
940 | for predicate in generic_predicates.iter() { | 901 | let predicate = predicate.clone().subst(parameters); |
941 | let predicate = predicate.clone().subst(&a_ty.parameters); | 902 | if let Some(obligation) = Obligation::from_predicate(predicate) { |
942 | if let Some(obligation) = Obligation::from_predicate(predicate) { | 903 | self.obligations.push(obligation); |
943 | self.obligations.push(obligation); | ||
944 | } | ||
945 | } | 904 | } |
946 | // add obligation for trait implementation, if this is a trait method | 905 | } |
947 | match def { | 906 | // add obligation for trait implementation, if this is a trait method |
948 | CallableDefId::FunctionId(f) => { | 907 | match def { |
949 | if let AssocContainerId::TraitId(trait_) = | 908 | CallableDefId::FunctionId(f) => { |
950 | f.lookup(self.db.upcast()).container | 909 | if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container |
951 | { | 910 | { |
952 | // construct a TraitDef | 911 | // construct a TraitDef |
953 | let substs = a_ty | 912 | let substs = |
954 | .parameters | 913 | parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); |
955 | .prefix(generics(self.db.upcast(), trait_.into()).len()); | 914 | self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); |
956 | self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); | ||
957 | } | ||
958 | } | 915 | } |
959 | CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {} | ||
960 | } | 916 | } |
917 | CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {} | ||
961 | } | 918 | } |
962 | } | 919 | } |
963 | } | 920 | } |
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index d974f805b..a318e47f3 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs | |||
@@ -13,7 +13,7 @@ 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::{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 { |
@@ -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() { |
@@ -165,7 +162,7 @@ impl<'a> InferenceContext<'a> { | |||
165 | _ => &Ty::Unknown, | 162 | _ => &Ty::Unknown, |
166 | }; | 163 | }; |
167 | let subty = self.infer_pat(*pat, expectation, default_bm); | 164 | let subty = self.infer_pat(*pat, expectation, default_bm); |
168 | Ty::apply_one(TypeCtor::Ref(*mutability), subty) | 165 | Ty::Ref(*mutability, Substs::single(subty)) |
169 | } | 166 | } |
170 | Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( | 167 | Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( |
171 | p.as_ref(), | 168 | p.as_ref(), |
@@ -198,7 +195,7 @@ impl<'a> InferenceContext<'a> { | |||
198 | 195 | ||
199 | let bound_ty = match mode { | 196 | let bound_ty = match mode { |
200 | BindingMode::Ref(mutability) => { | 197 | BindingMode::Ref(mutability) => { |
201 | Ty::apply_one(TypeCtor::Ref(mutability), inner_ty.clone()) | 198 | Ty::Ref(mutability, Substs::single(inner_ty.clone())) |
202 | } | 199 | } |
203 | BindingMode::Move => inner_ty.clone(), | 200 | BindingMode::Move => inner_ty.clone(), |
204 | }; | 201 | }; |
@@ -207,17 +204,17 @@ impl<'a> InferenceContext<'a> { | |||
207 | return inner_ty; | 204 | return inner_ty; |
208 | } | 205 | } |
209 | Pat::Slice { prefix, slice, suffix } => { | 206 | Pat::Slice { prefix, slice, suffix } => { |
210 | let (container_ty, elem_ty) = match &expected { | 207 | let (container_ty, elem_ty): (fn(_) -> _, _) = match &expected { |
211 | ty_app!(TypeCtor::Array, st) => (TypeCtor::Array, st.as_single().clone()), | 208 | Ty::Array(st) => (Ty::Array, st.as_single().clone()), |
212 | ty_app!(TypeCtor::Slice, st) => (TypeCtor::Slice, st.as_single().clone()), | 209 | Ty::Slice(st) => (Ty::Slice, st.as_single().clone()), |
213 | _ => (TypeCtor::Slice, Ty::Unknown), | 210 | _ => (Ty::Slice, Ty::Unknown), |
214 | }; | 211 | }; |
215 | 212 | ||
216 | for pat_id in prefix.iter().chain(suffix) { | 213 | for pat_id in prefix.iter().chain(suffix) { |
217 | self.infer_pat(*pat_id, &elem_ty, default_bm); | 214 | self.infer_pat(*pat_id, &elem_ty, default_bm); |
218 | } | 215 | } |
219 | 216 | ||
220 | let pat_ty = Ty::apply_one(container_ty, elem_ty); | 217 | let pat_ty = container_ty(Substs::single(elem_ty)); |
221 | if let Some(slice_pat_id) = slice { | 218 | if let Some(slice_pat_id) = slice { |
222 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); | 219 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); |
223 | } | 220 | } |
@@ -239,7 +236,7 @@ impl<'a> InferenceContext<'a> { | |||
239 | }; | 236 | }; |
240 | 237 | ||
241 | let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); | 238 | let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); |
242 | Ty::apply_one(TypeCtor::Adt(box_adt), inner_ty) | 239 | Ty::Adt(box_adt, Substs::single(inner_ty)) |
243 | } | 240 | } |
244 | None => Ty::Unknown, | 241 | None => Ty::Unknown, |
245 | }, | 242 | }, |
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 57eb8cede..2852ad5bf 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -9,7 +9,7 @@ use test_utils::mark; | |||
9 | use super::{InferenceContext, Obligation}; | 9 | use super::{InferenceContext, Obligation}; |
10 | use crate::{ | 10 | use crate::{ |
11 | BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Scalar, Substs, | 11 | BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Scalar, Substs, |
12 | Ty, TyKind, TypeCtor, TypeWalk, | 12 | Ty, TyKind, TypeWalk, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | impl<'a> InferenceContext<'a> { | 15 | impl<'a> InferenceContext<'a> { |
@@ -257,12 +257,14 @@ impl InferenceTable { | |||
257 | // try to resolve type vars first | 257 | // try to resolve type vars first |
258 | let ty1 = self.resolve_ty_shallow(ty1); | 258 | let ty1 = self.resolve_ty_shallow(ty1); |
259 | let ty2 = self.resolve_ty_shallow(ty2); | 259 | let ty2 = self.resolve_ty_shallow(ty2); |
260 | match (&*ty1, &*ty2) { | 260 | if ty1.equals_ctor(&ty2) { |
261 | (Ty::Apply(a_ty1), Ty::Apply(a_ty2)) if a_ty1.ctor == a_ty2.ctor => { | 261 | match (ty1.substs(), ty2.substs()) { |
262 | self.unify_substs(&a_ty1.parameters, &a_ty2.parameters, depth + 1) | 262 | (Some(st1), Some(st2)) => self.unify_substs(st1, st2, depth + 1), |
263 | (None, None) => true, | ||
264 | _ => false, | ||
263 | } | 265 | } |
264 | 266 | } else { | |
265 | _ => self.unify_inner_trivial(&ty1, &ty2, depth), | 267 | self.unify_inner_trivial(&ty1, &ty2, depth) |
266 | } | 268 | } |
267 | } | 269 | } |
268 | 270 | ||
@@ -300,24 +302,12 @@ impl InferenceTable { | |||
300 | | (other, Ty::Infer(InferTy::TypeVar(tv))) | 302 | | (other, Ty::Infer(InferTy::TypeVar(tv))) |
301 | | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other) | 303 | | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other) |
302 | | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv))) | 304 | | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv))) |
303 | | (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Scalar(Scalar::Int(_)))) | 305 | | (Ty::Infer(InferTy::IntVar(tv)), other @ Ty::Scalar(Scalar::Int(_))) |
304 | | (other @ ty_app!(TypeCtor::Scalar(Scalar::Int(_))), Ty::Infer(InferTy::IntVar(tv))) | 306 | | (other @ Ty::Scalar(Scalar::Int(_)), Ty::Infer(InferTy::IntVar(tv))) |
305 | | ( | 307 | | (Ty::Infer(InferTy::IntVar(tv)), other @ Ty::Scalar(Scalar::Uint(_))) |
306 | Ty::Infer(InferTy::IntVar(tv)), | 308 | | (other @ Ty::Scalar(Scalar::Uint(_)), Ty::Infer(InferTy::IntVar(tv))) |
307 | other @ ty_app!(TypeCtor::Scalar(Scalar::Uint(_))), | 309 | | (Ty::Infer(InferTy::FloatVar(tv)), other @ Ty::Scalar(Scalar::Float(_))) |
308 | ) | 310 | | (other @ Ty::Scalar(Scalar::Float(_)), Ty::Infer(InferTy::FloatVar(tv))) => { |
309 | | ( | ||
310 | other @ ty_app!(TypeCtor::Scalar(Scalar::Uint(_))), | ||
311 | Ty::Infer(InferTy::IntVar(tv)), | ||
312 | ) | ||
313 | | ( | ||
314 | Ty::Infer(InferTy::FloatVar(tv)), | ||
315 | other @ ty_app!(TypeCtor::Scalar(Scalar::Float(_))), | ||
316 | ) | ||
317 | | ( | ||
318 | other @ ty_app!(TypeCtor::Scalar(Scalar::Float(_))), | ||
319 | Ty::Infer(InferTy::FloatVar(tv)), | ||
320 | ) => { | ||
321 | // the type var is unknown since we tried to resolve it | 311 | // the type var is unknown since we tried to resolve it |
322 | self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); | 312 | self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); |
323 | true | 313 | true |