diff options
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 47 |
1 files changed, 23 insertions, 24 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index ac0568a32..b880fb3d8 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -902,7 +902,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
902 | .get(i) | 902 | .get(i) |
903 | .and_then(|field| field.ty(self.db)) | 903 | .and_then(|field| field.ty(self.db)) |
904 | .unwrap_or(Ty::Unknown); | 904 | .unwrap_or(Ty::Unknown); |
905 | self.infer_pat(subpat, &Expectation::has_type(expected_ty)); | 905 | self.infer_pat(subpat, &expected_ty); |
906 | } | 906 | } |
907 | 907 | ||
908 | ty | 908 | ty |
@@ -918,45 +918,45 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
918 | let expected_ty = matching_field | 918 | let expected_ty = matching_field |
919 | .and_then(|field| field.ty(self.db)) | 919 | .and_then(|field| field.ty(self.db)) |
920 | .unwrap_or(Ty::Unknown); | 920 | .unwrap_or(Ty::Unknown); |
921 | self.infer_pat(subpat.pat, &Expectation::has_type(expected_ty)); | 921 | self.infer_pat(subpat.pat, &expected_ty); |
922 | } | 922 | } |
923 | 923 | ||
924 | ty | 924 | ty |
925 | } | 925 | } |
926 | 926 | ||
927 | fn infer_pat(&mut self, pat: PatId, expected: &Expectation) -> Ty { | 927 | fn infer_pat(&mut self, pat: PatId, expected: &Ty) -> Ty { |
928 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 928 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
929 | 929 | ||
930 | let ty = match &body[pat] { | 930 | let ty = match &body[pat] { |
931 | Pat::Tuple(ref args) => { | 931 | Pat::Tuple(ref args) => { |
932 | // this can probably be done without cloning/ collecting | 932 | let expectations = match *expected { |
933 | let expectations = match expected.ty { | 933 | Ty::Tuple(ref tuple_args) => &**tuple_args, |
934 | Ty::Tuple(ref tuple_args) if args.len() == tuple_args.len() => { | 934 | _ => &[], |
935 | tuple_args.iter().cloned().collect() | ||
936 | } | ||
937 | _ => vec![Ty::Unknown; args.len()], | ||
938 | }; | 935 | }; |
936 | let expectations_iter = expectations | ||
937 | .into_iter() | ||
938 | .chain(std::iter::repeat(&Ty::Unknown)); | ||
939 | 939 | ||
940 | let inner_tys = args | 940 | let inner_tys = args |
941 | .iter() | 941 | .iter() |
942 | .zip(expectations.into_iter()) | 942 | .zip(expectations_iter) |
943 | .map(|(&pat, ty)| self.infer_pat(pat, &Expectation::has_type(ty))) | 943 | .map(|(&pat, ty)| self.infer_pat(pat, ty)) |
944 | .collect::<Vec<_>>() | 944 | .collect::<Vec<_>>() |
945 | .into(); | 945 | .into(); |
946 | 946 | ||
947 | Ty::Tuple(inner_tys) | 947 | Ty::Tuple(inner_tys) |
948 | } | 948 | } |
949 | Pat::Ref { pat, mutability } => { | 949 | Pat::Ref { pat, mutability } => { |
950 | let expectation = match expected.ty { | 950 | let expectation = match *expected { |
951 | Ty::Ref(ref sub_ty, exp_mut) => { | 951 | Ty::Ref(ref sub_ty, exp_mut) => { |
952 | if *mutability != exp_mut { | 952 | if *mutability != exp_mut { |
953 | // TODO: emit type error? | 953 | // TODO: emit type error? |
954 | } | 954 | } |
955 | Expectation::has_type((&**sub_ty).clone()) | 955 | &**sub_ty |
956 | } | 956 | } |
957 | _ => Expectation::none(), | 957 | _ => &Ty::Unknown, |
958 | }; | 958 | }; |
959 | let subty = self.infer_pat(*pat, &expectation); | 959 | let subty = self.infer_pat(*pat, expectation); |
960 | Ty::Ref(subty.into(), *mutability) | 960 | Ty::Ref(subty.into(), *mutability) |
961 | } | 961 | } |
962 | Pat::TupleStruct { | 962 | Pat::TupleStruct { |
@@ -980,7 +980,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
980 | let subty = if let Some(subpat) = subpat { | 980 | let subty = if let Some(subpat) = subpat { |
981 | self.infer_pat(*subpat, expected) | 981 | self.infer_pat(*subpat, expected) |
982 | } else { | 982 | } else { |
983 | expected.ty.clone() | 983 | expected.clone() |
984 | }; | 984 | }; |
985 | 985 | ||
986 | match mode { | 986 | match mode { |
@@ -993,7 +993,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
993 | }; | 993 | }; |
994 | // use a new type variable if we got Ty::Unknown here | 994 | // use a new type variable if we got Ty::Unknown here |
995 | let ty = self.insert_type_vars_shallow(ty); | 995 | let ty = self.insert_type_vars_shallow(ty); |
996 | self.unify(&ty, &expected.ty); | 996 | self.unify(&ty, expected); |
997 | let ty = self.resolve_ty_as_possible(ty); | 997 | let ty = self.resolve_ty_as_possible(ty); |
998 | self.write_pat_ty(pat, ty.clone()); | 998 | self.write_pat_ty(pat, ty.clone()); |
999 | ty | 999 | ty |
@@ -1040,7 +1040,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1040 | pat, | 1040 | pat, |
1041 | } => { | 1041 | } => { |
1042 | let _iterable_ty = self.infer_expr(*iterable, &Expectation::none()); | 1042 | let _iterable_ty = self.infer_expr(*iterable, &Expectation::none()); |
1043 | self.infer_pat(*pat, &Expectation::none()); | 1043 | self.infer_pat(*pat, &Ty::Unknown); |
1044 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 1044 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
1045 | Ty::unit() | 1045 | Ty::unit() |
1046 | } | 1046 | } |
@@ -1054,9 +1054,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1054 | for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) { | 1054 | for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) { |
1055 | let expected = if let Some(type_ref) = arg_type { | 1055 | let expected = if let Some(type_ref) = arg_type { |
1056 | let ty = self.make_ty(type_ref); | 1056 | let ty = self.make_ty(type_ref); |
1057 | Expectation::has_type(ty) | 1057 | ty |
1058 | } else { | 1058 | } else { |
1059 | Expectation::none() | 1059 | Ty::Unknown |
1060 | }; | 1060 | }; |
1061 | self.infer_pat(*arg_pat, &expected); | 1061 | self.infer_pat(*arg_pat, &expected); |
1062 | } | 1062 | } |
@@ -1126,11 +1126,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1126 | expected.clone() | 1126 | expected.clone() |
1127 | }; | 1127 | }; |
1128 | let input_ty = self.infer_expr(*expr, &Expectation::none()); | 1128 | let input_ty = self.infer_expr(*expr, &Expectation::none()); |
1129 | let pat_expectation = Expectation::has_type(input_ty); | ||
1130 | 1129 | ||
1131 | for arm in arms { | 1130 | for arm in arms { |
1132 | for &pat in &arm.pats { | 1131 | for &pat in &arm.pats { |
1133 | let _pat_ty = self.infer_pat(pat, &pat_expectation); | 1132 | let _pat_ty = self.infer_pat(pat, &input_ty); |
1134 | } | 1133 | } |
1135 | // TODO type the guard | 1134 | // TODO type the guard |
1136 | self.infer_expr(arm.expr, &expected); | 1135 | self.infer_expr(arm.expr, &expected); |
@@ -1323,7 +1322,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1323 | decl_ty | 1322 | decl_ty |
1324 | }; | 1323 | }; |
1325 | 1324 | ||
1326 | self.infer_pat(*pat, &Expectation::has_type(ty)); | 1325 | self.infer_pat(*pat, &ty); |
1327 | } | 1326 | } |
1328 | Statement::Expr(expr) => { | 1327 | Statement::Expr(expr) => { |
1329 | self.infer_expr(*expr, &Expectation::none()); | 1328 | self.infer_expr(*expr, &Expectation::none()); |
@@ -1344,7 +1343,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1344 | let ty = self.make_ty(type_ref); | 1343 | let ty = self.make_ty(type_ref); |
1345 | let ty = self.insert_type_vars(ty); | 1344 | let ty = self.insert_type_vars(ty); |
1346 | 1345 | ||
1347 | self.infer_pat(*pat, &Expectation::has_type(ty)); | 1346 | self.infer_pat(*pat, &ty); |
1348 | } | 1347 | } |
1349 | self.return_ty = { | 1348 | self.return_ty = { |
1350 | let ty = self.make_ty(signature.ret_type()); | 1349 | let ty = self.make_ty(signature.ret_type()); |