diff options
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 854d3e3d9..324df5ef9 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -36,7 +36,7 @@ use crate::{ | |||
36 | db::HirDatabase, | 36 | db::HirDatabase, |
37 | type_ref::{TypeRef, Mutability}, | 37 | type_ref::{TypeRef, Mutability}, |
38 | name::KnownName, | 38 | name::KnownName, |
39 | expr::{Body, Expr, Literal, ExprId, PatId, UnaryOp, BinaryOp, Statement}, | 39 | expr::{Body, Expr, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement}, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | /// The ID of a type variable. | 42 | /// The ID of a type variable. |
@@ -872,6 +872,35 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
872 | } | 872 | } |
873 | } | 873 | } |
874 | 874 | ||
875 | // FIXME: Expectation should probably contain a reference to a Ty instead of | ||
876 | // a Ty itself | ||
877 | fn infer_pat(&mut self, pat: PatId, expected: &Expectation) -> Ty { | ||
878 | let body = Arc::clone(&self.body); // avoid borrow checker problem | ||
879 | match (&body[pat], &expected.ty) { | ||
880 | (Pat::Tuple(ref args), &Ty::Tuple(ref tuple_args)) | ||
881 | if args.len() == tuple_args.len() => | ||
882 | { | ||
883 | for (&pat, ty) in args.iter().zip(tuple_args.iter()) { | ||
884 | // FIXME: can we do w/o cloning? | ||
885 | self.infer_pat(pat, &Expectation::has_type(ty.clone())); | ||
886 | } | ||
887 | } | ||
888 | (&Pat::Ref { pat, mutability }, &Ty::Ref(ref sub_ty, ty_mut)) | ||
889 | if mutability == ty_mut => | ||
890 | { | ||
891 | self.infer_pat(pat, &Expectation::has_type((&**sub_ty).clone())); | ||
892 | } | ||
893 | // TODO: implement more | ||
894 | (_, ref _expected_ty) => {} | ||
895 | }; | ||
896 | // use a new type variable if we got Ty::Unknown here | ||
897 | let ty = self.insert_type_vars_shallow(expected.ty.clone()); | ||
898 | self.unify(&ty, &expected.ty); | ||
899 | let ty = self.resolve_ty_as_possible(ty); | ||
900 | self.write_pat_ty(pat, ty.clone()); | ||
901 | ty | ||
902 | } | ||
903 | |||
875 | fn infer_expr(&mut self, expr: ExprId, expected: &Expectation) -> Ty { | 904 | fn infer_expr(&mut self, expr: ExprId, expected: &Expectation) -> Ty { |
876 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 905 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
877 | let ty = match &body[expr] { | 906 | let ty = match &body[expr] { |
@@ -1168,9 +1197,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1168 | decl_ty | 1197 | decl_ty |
1169 | }; | 1198 | }; |
1170 | 1199 | ||
1171 | // TODO: walk the pattern here? | 1200 | self.infer_pat(*pat, &Expectation::has_type(ty))?; |
1172 | |||
1173 | self.write_pat_ty(*pat, ty); | ||
1174 | } | 1201 | } |
1175 | Statement::Expr(expr) => { | 1202 | Statement::Expr(expr) => { |
1176 | self.infer_expr(*expr, &Expectation::none()); | 1203 | self.infer_expr(*expr, &Expectation::none()); |
@@ -1191,9 +1218,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1191 | let ty = self.make_ty(type_ref); | 1218 | let ty = self.make_ty(type_ref); |
1192 | let ty = self.insert_type_vars(ty); | 1219 | let ty = self.insert_type_vars(ty); |
1193 | 1220 | ||
1194 | // TODO: walk pattern? | 1221 | self.infer_pat(*pat, &Expectation::has_type(ty))?; |
1195 | |||
1196 | self.write_pat_ty(*pat, ty); | ||
1197 | } | 1222 | } |
1198 | self.return_ty = { | 1223 | self.return_ty = { |
1199 | let ty = self.make_ty(signature.ret_type()); | 1224 | let ty = self.make_ty(signature.ret_type()); |