aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r--crates/ra_hir/src/ty.rs47
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());