diff options
author | Florian Diebold <[email protected]> | 2019-01-07 12:44:54 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-01-12 14:01:19 +0000 |
commit | 082ef52bcb15d779c6aff78d9860d328bf7df9b2 (patch) | |
tree | a4a123ad491e15c8d17bdc815675d43bb33811b5 /crates/ra_hir/src/ty.rs | |
parent | e9e397e705ad0bec9775067b10109e35ebefc493 (diff) |
Implement basic inherent method resolution
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 2d533eb6a..2dcba5283 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; |
@@ -891,14 +892,38 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
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, arg_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(arg_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())?; |