diff options
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 2d533eb6a..5d5568d69 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -17,6 +17,7 @@ mod autoderef; | |||
17 | mod primitive; | 17 | mod primitive; |
18 | #[cfg(test)] | 18 | #[cfg(test)] |
19 | mod tests; | 19 | mod tests; |
20 | pub(crate) mod method_resolution; | ||
20 | 21 | ||
21 | use std::borrow::Cow; | 22 | use std::borrow::Cow; |
22 | use std::ops::Index; | 23 | use std::ops::Index; |
@@ -431,7 +432,7 @@ fn type_for_fn(db: &impl HirDatabase, f: Function) -> Cancelable<Ty> { | |||
431 | let impl_block = f.impl_block(db)?; | 432 | let impl_block = f.impl_block(db)?; |
432 | // TODO we ignore type parameters for now | 433 | // TODO we ignore type parameters for now |
433 | let input = signature | 434 | let input = signature |
434 | .args() | 435 | .params() |
435 | .iter() | 436 | .iter() |
436 | .map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), tr)) | 437 | .map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), tr)) |
437 | .collect::<Cancelable<Vec<_>>>()?; | 438 | .collect::<Cancelable<Vec<_>>>()?; |
@@ -875,7 +876,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
875 | } | 876 | } |
876 | Expr::Call { callee, args } => { | 877 | Expr::Call { callee, args } => { |
877 | let callee_ty = self.infer_expr(*callee, &Expectation::none())?; | 878 | let callee_ty = self.infer_expr(*callee, &Expectation::none())?; |
878 | let (arg_tys, ret_ty) = match &callee_ty { | 879 | let (param_tys, ret_ty) = match &callee_ty { |
879 | Ty::FnPtr(sig) => (&sig.input[..], sig.output.clone()), | 880 | Ty::FnPtr(sig) => (&sig.input[..], sig.output.clone()), |
880 | _ => { | 881 | _ => { |
881 | // not callable | 882 | // not callable |
@@ -886,19 +887,43 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
886 | for (i, arg) in args.iter().enumerate() { | 887 | for (i, arg) in args.iter().enumerate() { |
887 | self.infer_expr( | 888 | self.infer_expr( |
888 | *arg, | 889 | *arg, |
889 | &Expectation::has_type(arg_tys.get(i).cloned().unwrap_or(Ty::Unknown)), | 890 | &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)), |
890 | )?; | 891 | )?; |
891 | } | 892 | } |
892 | ret_ty | 893 | ret_ty |
893 | } | 894 | } |
894 | Expr::MethodCall { receiver, args, .. } => { | 895 | Expr::MethodCall { |
895 | let _receiver_ty = self.infer_expr(*receiver, &Expectation::none())?; | 896 | receiver, |
896 | // TODO resolve method... | 897 | args, |
897 | for (_i, arg) in args.iter().enumerate() { | 898 | method_name, |
898 | // TODO unify / expect argument type | 899 | } => { |
899 | self.infer_expr(*arg, &Expectation::none())?; | 900 | let receiver_ty = self.infer_expr(*receiver, &Expectation::none())?; |
901 | let resolved = receiver_ty.clone().lookup_method(self.db, method_name)?; | ||
902 | let method_ty = match resolved { | ||
903 | Some(def_id) => self.db.type_for_def(def_id)?, | ||
904 | None => Ty::Unknown, | ||
905 | }; | ||
906 | let method_ty = self.insert_type_vars(method_ty); | ||
907 | let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty { | ||
908 | Ty::FnPtr(sig) => { | ||
909 | if sig.input.len() > 0 { | ||
910 | (&sig.input[0], &sig.input[1..], sig.output.clone()) | ||
911 | } else { | ||
912 | (&Ty::Unknown, &[][..], sig.output.clone()) | ||
913 | } | ||
914 | } | ||
915 | _ => (&Ty::Unknown, &[][..], Ty::Unknown), | ||
916 | }; | ||
917 | // TODO we would have to apply the autoderef/autoref steps here | ||
918 | // to get the correct receiver type to unify... | ||
919 | self.unify(expected_receiver_ty, &receiver_ty); | ||
920 | for (i, arg) in args.iter().enumerate() { | ||
921 | self.infer_expr( | ||
922 | *arg, | ||
923 | &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)), | ||
924 | )?; | ||
900 | } | 925 | } |
901 | Ty::Unknown | 926 | ret_ty |
902 | } | 927 | } |
903 | Expr::Match { expr, arms } => { | 928 | Expr::Match { expr, arms } => { |
904 | let _ty = self.infer_expr(*expr, &Expectation::none())?; | 929 | let _ty = self.infer_expr(*expr, &Expectation::none())?; |
@@ -1068,7 +1093,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1068 | 1093 | ||
1069 | fn collect_fn_signature(&mut self, signature: &FnSignature) -> Cancelable<()> { | 1094 | fn collect_fn_signature(&mut self, signature: &FnSignature) -> Cancelable<()> { |
1070 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 1095 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
1071 | for (type_ref, pat) in signature.args().iter().zip(body.args()) { | 1096 | for (type_ref, pat) in signature.params().iter().zip(body.params()) { |
1072 | let ty = self.make_ty(type_ref)?; | 1097 | let ty = self.make_ty(type_ref)?; |
1073 | let ty = self.insert_type_vars(ty); | 1098 | let ty = self.insert_type_vars(ty); |
1074 | self.write_pat_ty(*pat, ty); | 1099 | self.write_pat_ty(*pat, ty); |