diff options
author | Florian Diebold <[email protected]> | 2019-04-09 21:16:20 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-04-14 10:28:53 +0100 |
commit | 7650a44640a373e28f9eecc4623256ce6b9bbaa0 (patch) | |
tree | 82d405758889b42843d56c62c7a73bc06c411e7a /crates/ra_hir/src/ty | |
parent | 9339241b78ef7474e88de37738bdbece7767d333 (diff) |
Make callable signature handling a bit nicer
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 61 |
1 files changed, 14 insertions, 47 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index b28bb47c6..28459d750 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -41,7 +41,7 @@ use crate::{ | |||
41 | ty::infer::diagnostics::InferenceDiagnostic, | 41 | ty::infer::diagnostics::InferenceDiagnostic, |
42 | diagnostics::DiagnosticSink, | 42 | diagnostics::DiagnosticSink, |
43 | }; | 43 | }; |
44 | use super::{Ty, TypableDef, Substs, primitive, op, FnSig, ApplicationTy, TypeCtor, traits::{ Solution, Obligation, Guidance}, CallableDef, TraitRef}; | 44 | use super::{Ty, TypableDef, Substs, primitive, op, ApplicationTy, TypeCtor, traits::{ Solution, Obligation, Guidance}, CallableDef, TraitRef}; |
45 | 45 | ||
46 | /// The entry point of type inference. | 46 | /// The entry point of type inference. |
47 | pub fn infer(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { | 47 | pub fn infer(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { |
@@ -839,32 +839,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
839 | let method_ty = method_ty.apply_substs(substs); | 839 | let method_ty = method_ty.apply_substs(substs); |
840 | let method_ty = self.insert_type_vars(method_ty); | 840 | let method_ty = self.insert_type_vars(method_ty); |
841 | self.register_obligations_for_call(&method_ty); | 841 | self.register_obligations_for_call(&method_ty); |
842 | let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty { | 842 | let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) { |
843 | Ty::Apply(a_ty) => match a_ty.ctor { | 843 | Some(sig) => { |
844 | TypeCtor::FnPtr => { | 844 | if !sig.params().is_empty() { |
845 | let sig = FnSig::from_fn_ptr_substs(&a_ty.parameters); | 845 | (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone()) |
846 | if !sig.params().is_empty() { | 846 | } else { |
847 | (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone()) | 847 | (Ty::Unknown, Vec::new(), sig.ret().clone()) |
848 | } else { | ||
849 | (Ty::Unknown, Vec::new(), sig.ret().clone()) | ||
850 | } | ||
851 | } | ||
852 | TypeCtor::FnDef(def) => { | ||
853 | let sig = self.db.callable_item_signature(def); | ||
854 | let ret_ty = sig.ret().clone().subst(&a_ty.parameters); | ||
855 | |||
856 | if !sig.params().is_empty() { | ||
857 | let mut params_iter = | ||
858 | sig.params().iter().map(|ty| ty.clone().subst(&a_ty.parameters)); | ||
859 | let receiver_ty = params_iter.next().unwrap(); | ||
860 | (receiver_ty, params_iter.collect(), ret_ty) | ||
861 | } else { | ||
862 | (Ty::Unknown, Vec::new(), ret_ty) | ||
863 | } | ||
864 | } | 848 | } |
865 | _ => (Ty::Unknown, Vec::new(), Ty::Unknown), | 849 | } |
866 | }, | 850 | None => (Ty::Unknown, Vec::new(), Ty::Unknown), |
867 | _ => (Ty::Unknown, Vec::new(), Ty::Unknown), | ||
868 | }; | 851 | }; |
869 | // Apply autoref so the below unification works correctly | 852 | // Apply autoref so the below unification works correctly |
870 | // FIXME: return correct autorefs from lookup_method | 853 | // FIXME: return correct autorefs from lookup_method |
@@ -937,27 +920,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
937 | } | 920 | } |
938 | Expr::Call { callee, args } => { | 921 | Expr::Call { callee, args } => { |
939 | let callee_ty = self.infer_expr(*callee, &Expectation::none()); | 922 | let callee_ty = self.infer_expr(*callee, &Expectation::none()); |
940 | let (param_tys, ret_ty) = match &callee_ty { | 923 | let (param_tys, ret_ty) = match callee_ty.callable_sig(self.db) { |
941 | Ty::Apply(a_ty) => match a_ty.ctor { | 924 | Some(sig) => (sig.params().to_vec(), sig.ret().clone()), |
942 | TypeCtor::FnPtr => { | 925 | None => { |
943 | let sig = FnSig::from_fn_ptr_substs(&a_ty.parameters); | 926 | // Not callable |
944 | (sig.params().to_vec(), sig.ret().clone()) | 927 | // FIXME: report an error |
945 | } | ||
946 | TypeCtor::FnDef(def) => { | ||
947 | let sig = self.db.callable_item_signature(def); | ||
948 | let ret_ty = sig.ret().clone().subst(&a_ty.parameters); | ||
949 | let param_tys = sig | ||
950 | .params() | ||
951 | .iter() | ||
952 | .map(|ty| ty.clone().subst(&a_ty.parameters)) | ||
953 | .collect(); | ||
954 | (param_tys, ret_ty) | ||
955 | } | ||
956 | _ => (Vec::new(), Ty::Unknown), | ||
957 | }, | ||
958 | _ => { | ||
959 | // not callable | ||
960 | // FIXME report an error? | ||
961 | (Vec::new(), Ty::Unknown) | 928 | (Vec::new(), Ty::Unknown) |
962 | } | 929 | } |
963 | }; | 930 | }; |