diff options
author | Marcus Klaas de Vries <[email protected]> | 2019-01-17 09:28:10 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-01-19 12:37:25 +0000 |
commit | be1b4034a523081cfeea1c7a1d61130d5d1778e1 (patch) | |
tree | 3fe6d410c51b01ebdc89260f9c241edf8c90bda3 /crates/ra_hir/src | |
parent | 06d16a18f632711de588ccd12a6a1ed6f2b9ad69 (diff) |
Infer pattern types for lambdas and loops
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 44 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 10 |
2 files changed, 39 insertions, 15 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 74996dda5..75794b732 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -33,6 +33,7 @@ use rustc_hash::FxHashMap; | |||
33 | use crate::{ | 33 | use crate::{ |
34 | Def, DefId, Module, Function, Struct, Enum, EnumVariant, Path, Name, ImplBlock, | 34 | Def, DefId, Module, Function, Struct, Enum, EnumVariant, Path, Name, ImplBlock, |
35 | FnSignature, FnScopes, | 35 | FnSignature, FnScopes, |
36 | adt::StructField, | ||
36 | db::HirDatabase, | 37 | db::HirDatabase, |
37 | type_ref::{TypeRef, Mutability}, | 38 | type_ref::{TypeRef, Mutability}, |
38 | name::KnownName, | 39 | name::KnownName, |
@@ -872,7 +873,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
872 | } | 873 | } |
873 | } | 874 | } |
874 | 875 | ||
875 | fn resolve_fields(&self, path: Option<&Path>) -> Option<(Ty, Vec<crate::adt::StructField>)> { | 876 | fn resolve_fields(&self, path: Option<&Path>) -> Option<(Ty, Vec<StructField>)> { |
876 | let def = path | 877 | let def = path |
877 | .and_then(|path| self.module.resolve_path(self.db, &path).take_types()) | 878 | .and_then(|path| self.module.resolve_path(self.db, &path).take_types()) |
878 | .map(|def_id| def_id.resolve(self.db)); | 879 | .map(|def_id| def_id.resolve(self.db)); |
@@ -916,13 +917,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
916 | } | 917 | } |
917 | 918 | ||
918 | for (&sub_pat, field) in sub_pats.iter().zip(fields.iter()) { | 919 | for (&sub_pat, field) in sub_pats.iter().zip(fields.iter()) { |
919 | let sub_ty = Ty::from_hir( | 920 | let sub_ty = self.make_ty(&field.type_ref); |
920 | self.db, | ||
921 | &self.module, | ||
922 | self.impl_block.as_ref(), | ||
923 | &field.type_ref, | ||
924 | ); | ||
925 | |||
926 | self.infer_pat(sub_pat, &Expectation::has_type(sub_ty)); | 921 | self.infer_pat(sub_pat, &Expectation::has_type(sub_ty)); |
927 | } | 922 | } |
928 | 923 | ||
@@ -941,7 +936,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
941 | 936 | ||
942 | if let Some(field) = matching_field { | 937 | if let Some(field) = matching_field { |
943 | let typeref = &field.type_ref; | 938 | let typeref = &field.type_ref; |
944 | let sub_ty = Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), typeref); | 939 | let sub_ty = self.make_ty(typeref); |
945 | self.infer_pat(sub_pat.pat, &Expectation::has_type(sub_ty)); | 940 | self.infer_pat(sub_pat.pat, &Expectation::has_type(sub_ty)); |
946 | } | 941 | } |
947 | } | 942 | } |
@@ -1031,14 +1026,34 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1031 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 1026 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
1032 | Ty::unit() | 1027 | Ty::unit() |
1033 | } | 1028 | } |
1034 | Expr::For { iterable, body, .. } => { | 1029 | Expr::For { |
1030 | iterable, | ||
1031 | body, | ||
1032 | pat, | ||
1033 | } => { | ||
1035 | let _iterable_ty = self.infer_expr(*iterable, &Expectation::none()); | 1034 | let _iterable_ty = self.infer_expr(*iterable, &Expectation::none()); |
1036 | // TODO write type for pat | 1035 | self.infer_pat(*pat, &Expectation::none()); |
1037 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 1036 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
1038 | Ty::unit() | 1037 | Ty::unit() |
1039 | } | 1038 | } |
1040 | Expr::Lambda { body, .. } => { | 1039 | Expr::Lambda { |
1041 | // TODO write types for args, infer lambda type etc. | 1040 | body, |
1041 | args, | ||
1042 | arg_types, | ||
1043 | } => { | ||
1044 | assert_eq!(args.len(), arg_types.len()); | ||
1045 | |||
1046 | for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) { | ||
1047 | let expected = if let Some(tyref) = arg_type { | ||
1048 | let ty = self.make_ty(tyref); | ||
1049 | Expectation::has_type(ty) | ||
1050 | } else { | ||
1051 | Expectation::none() | ||
1052 | }; | ||
1053 | self.infer_pat(*arg_pat, &expected); | ||
1054 | } | ||
1055 | |||
1056 | // TODO: infer lambda type etc. | ||
1042 | let _body_ty = self.infer_expr(*body, &Expectation::none()); | 1057 | let _body_ty = self.infer_expr(*body, &Expectation::none()); |
1043 | Ty::Unknown | 1058 | Ty::Unknown |
1044 | } | 1059 | } |
@@ -1174,8 +1189,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1174 | } | 1189 | } |
1175 | Expr::Cast { expr, type_ref } => { | 1190 | Expr::Cast { expr, type_ref } => { |
1176 | let _inner_ty = self.infer_expr(*expr, &Expectation::none()); | 1191 | let _inner_ty = self.infer_expr(*expr, &Expectation::none()); |
1177 | let cast_ty = | 1192 | let cast_ty = self.make_ty(type_ref); |
1178 | Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), type_ref); | ||
1179 | let cast_ty = self.insert_type_vars(cast_ty); | 1193 | let cast_ty = self.insert_type_vars(cast_ty); |
1180 | // TODO check the cast... | 1194 | // TODO check the cast... |
1181 | cast_ty | 1195 | cast_ty |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 10842f967..dfc83bb17 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -367,6 +367,16 @@ fn test(x: &i32) { | |||
367 | let &z = x; | 367 | let &z = x; |
368 | let a = z; | 368 | let a = z; |
369 | let (c, d) = (1, "hello"); | 369 | let (c, d) = (1, "hello"); |
370 | |||
371 | for (e, f) in some_iter { | ||
372 | let g = e; | ||
373 | } | ||
374 | |||
375 | if let [val] = opt { | ||
376 | let h = val; | ||
377 | } | ||
378 | |||
379 | let lambda = |a: u64, b, c: i32| { a + b; c }; | ||
370 | } | 380 | } |
371 | "#, | 381 | "#, |
372 | "pattern.txt", | 382 | "pattern.txt", |