aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/infer.rs
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-04-09 21:04:59 +0100
committerFlorian Diebold <[email protected]>2019-04-14 10:28:53 +0100
commit9339241b78ef7474e88de37738bdbece7767d333 (patch)
treec253d26db406b0f6cac5db67a054f4334b016486 /crates/ra_hir/src/ty/infer.rs
parenta1ed53a4f183b5826162eb9e998207b92be9c57f (diff)
Some cleanup
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r--crates/ra_hir/src/ty/infer.rs189
1 files changed, 99 insertions, 90 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 3dec5936a..b28bb47c6 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -461,6 +461,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
461 for segment in &path.segments[remaining_index..] { 461 for segment in &path.segments[remaining_index..] {
462 let ty = match resolved { 462 let ty = match resolved {
463 Resolution::Def(def) => { 463 Resolution::Def(def) => {
464 // FIXME resolve associated items from traits as well
464 let typable: Option<TypableDef> = def.into(); 465 let typable: Option<TypableDef> = def.into();
465 let typable = typable?; 466 let typable = typable?;
466 467
@@ -750,12 +751,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
750 fn substs_for_method_call( 751 fn substs_for_method_call(
751 &mut self, 752 &mut self,
752 def_generics: Option<Arc<GenericParams>>, 753 def_generics: Option<Arc<GenericParams>>,
753 generic_args: &Option<GenericArgs>, 754 generic_args: Option<&GenericArgs>,
754 receiver_ty: &Ty, 755 receiver_ty: &Ty,
755 ) -> Substs { 756 ) -> Substs {
756 let (parent_param_count, param_count) = 757 let (parent_param_count, param_count) =
757 def_generics.as_ref().map_or((0, 0), |g| (g.count_parent_params(), g.params.len())); 758 def_generics.as_ref().map_or((0, 0), |g| (g.count_parent_params(), g.params.len()));
758 let mut substs = Vec::with_capacity(parent_param_count + param_count); 759 let mut substs = Vec::with_capacity(parent_param_count + param_count);
760 // Parent arguments are unknown, except for the receiver type
759 if let Some(parent_generics) = def_generics.and_then(|p| p.parent_params.clone()) { 761 if let Some(parent_generics) = def_generics.and_then(|p| p.parent_params.clone()) {
760 for param in &parent_generics.params { 762 for param in &parent_generics.params {
761 if param.name.as_known_name() == Some(crate::KnownName::SelfType) { 763 if param.name.as_known_name() == Some(crate::KnownName::SelfType) {
@@ -785,6 +787,100 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
785 Substs(substs.into()) 787 Substs(substs.into())
786 } 788 }
787 789
790 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
791 match callable_ty {
792 Ty::Apply(a_ty) => match a_ty.ctor {
793 TypeCtor::FnDef(def) => {
794 // add obligation for trait implementation, if this is a trait method
795 // FIXME also register obligations from where clauses from the trait or impl and method
796 match def {
797 CallableDef::Function(f) => {
798 if let Some(trait_) = f.parent_trait(self.db) {
799 // construct a TraitDef
800 let substs = a_ty.parameters.prefix(
801 trait_.generic_params(self.db).count_params_including_parent(),
802 );
803 self.obligations
804 .push(Obligation::Trait(TraitRef { trait_, substs }));
805 }
806 }
807 CallableDef::Struct(_) | CallableDef::EnumVariant(_) => {}
808 }
809 }
810 _ => {}
811 },
812 _ => {}
813 }
814 }
815
816 fn infer_method_call(
817 &mut self,
818 tgt_expr: ExprId,
819 receiver: ExprId,
820 args: &[ExprId],
821 method_name: &Name,
822 generic_args: Option<&GenericArgs>,
823 ) -> Ty {
824 let receiver_ty = self.infer_expr(receiver, &Expectation::none());
825 let resolved = receiver_ty.clone().lookup_method(self.db, method_name, &self.resolver);
826 let (derefed_receiver_ty, method_ty, def_generics) = match resolved {
827 Some((ty, func)) => {
828 self.write_method_resolution(tgt_expr, func);
829 (
830 ty,
831 self.db.type_for_def(func.into(), Namespace::Values),
832 Some(func.generic_params(self.db)),
833 )
834 }
835 None => (receiver_ty, Ty::Unknown, None),
836 };
837 let substs =
838 self.substs_for_method_call(def_generics.clone(), generic_args, &derefed_receiver_ty);
839 let method_ty = method_ty.apply_substs(substs);
840 let method_ty = self.insert_type_vars(method_ty);
841 self.register_obligations_for_call(&method_ty);
842 let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty {
843 Ty::Apply(a_ty) => match a_ty.ctor {
844 TypeCtor::FnPtr => {
845 let sig = FnSig::from_fn_ptr_substs(&a_ty.parameters);
846 if !sig.params().is_empty() {
847 (sig.params()[0].clone(), sig.params()[1..].to_vec(), 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 }
865 _ => (Ty::Unknown, Vec::new(), Ty::Unknown),
866 },
867 _ => (Ty::Unknown, Vec::new(), Ty::Unknown),
868 };
869 // Apply autoref so the below unification works correctly
870 // FIXME: return correct autorefs from lookup_method
871 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
872 Some((_, mutability)) => Ty::apply_one(TypeCtor::Ref(mutability), derefed_receiver_ty),
873 _ => derefed_receiver_ty,
874 };
875 self.unify(&expected_receiver_ty, &actual_receiver_ty);
876
877 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown));
878 for (arg, param) in args.iter().zip(param_iter) {
879 self.infer_expr(*arg, &Expectation::has_type(param));
880 }
881 ret_ty
882 }
883
788 fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { 884 fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
789 let body = Arc::clone(&self.body); // avoid borrow checker problem 885 let body = Arc::clone(&self.body); // avoid borrow checker problem
790 let ty = match &body[tgt_expr] { 886 let ty = match &body[tgt_expr] {
@@ -872,95 +968,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
872 } 968 }
873 ret_ty 969 ret_ty
874 } 970 }
875 Expr::MethodCall { receiver, args, method_name, generic_args } => { 971 Expr::MethodCall { receiver, args, method_name, generic_args } => self
876 let receiver_ty = self.infer_expr(*receiver, &Expectation::none()); 972 .infer_method_call(tgt_expr, *receiver, &args, &method_name, generic_args.as_ref()),
877 let resolved =
878 receiver_ty.clone().lookup_method(self.db, method_name, &self.resolver);
879 let (derefed_receiver_ty, method_ty, def_generics) = match resolved {
880 Some((ty, func)) => {
881 self.write_method_resolution(tgt_expr, func);
882 (
883 ty,
884 self.db.type_for_def(func.into(), Namespace::Values),
885 Some(func.generic_params(self.db)),
886 )
887 }
888 None => (receiver_ty, Ty::Unknown, None),
889 };
890 let substs = self.substs_for_method_call(
891 def_generics.clone(),
892 generic_args,
893 &derefed_receiver_ty,
894 );
895 let method_ty = method_ty.apply_substs(substs);
896 let method_ty = self.insert_type_vars(method_ty);
897 let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty {
898 Ty::Apply(a_ty) => match a_ty.ctor {
899 TypeCtor::FnPtr => {
900 let sig = FnSig::from_fn_ptr_substs(&a_ty.parameters);
901 if !sig.params().is_empty() {
902 (
903 sig.params()[0].clone(),
904 sig.params()[1..].to_vec(),
905 sig.ret().clone(),
906 )
907 } else {
908 (Ty::Unknown, Vec::new(), sig.ret().clone())
909 }
910 }
911 TypeCtor::FnDef(def) => {
912 let sig = self.db.callable_item_signature(def);
913 let ret_ty = sig.ret().clone().subst(&a_ty.parameters);
914
915 // add obligation for trait implementation, if this is a trait method
916 // FIXME also register obligations from where clauses from the trait or impl and method
917 match def {
918 CallableDef::Function(f) => {
919 if let Some(trait_) = f.parent_trait(self.db) {
920 // construct a TraitDef
921 let substs = a_ty.parameters.prefix(
922 def_generics
923 .expect("trait parent should always have generics")
924 .count_parent_params(),
925 );
926 self.obligations
927 .push(Obligation::Trait(TraitRef { trait_, substs }));
928 }
929 }
930 CallableDef::Struct(_) | CallableDef::EnumVariant(_) => {}
931 }
932
933 if !sig.params().is_empty() {
934 let mut params_iter = sig
935 .params()
936 .iter()
937 .map(|ty| ty.clone().subst(&a_ty.parameters));
938 let receiver_ty = params_iter.next().unwrap();
939 (receiver_ty, params_iter.collect(), ret_ty)
940 } else {
941 (Ty::Unknown, Vec::new(), ret_ty)
942 }
943 }
944 _ => (Ty::Unknown, Vec::new(), Ty::Unknown),
945 },
946 _ => (Ty::Unknown, Vec::new(), Ty::Unknown),
947 };
948 // Apply autoref so the below unification works correctly
949 // FIXME: return correct autorefs/derefs from lookup_method
950 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
951 Some((_, mutability)) => {
952 Ty::apply_one(TypeCtor::Ref(mutability), derefed_receiver_ty)
953 }
954 _ => derefed_receiver_ty,
955 };
956 self.unify(&expected_receiver_ty, &actual_receiver_ty);
957
958 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown));
959 for (arg, param) in args.iter().zip(param_iter) {
960 self.infer_expr(*arg, &Expectation::has_type(param));
961 }
962 ret_ty
963 }
964 Expr::Match { expr, arms } => { 973 Expr::Match { expr, arms } => {
965 let expected = if expected.ty == Ty::Unknown { 974 let expected = if expected.ty == Ty::Unknown {
966 Expectation::has_type(self.new_type_var()) 975 Expectation::has_type(self.new_type_var())