aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer/expr.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-05-23 22:55:51 +0100
committerGitHub <[email protected]>2021-05-23 22:55:51 +0100
commit495c9586ec51e0cf9b06397d99ec4f65c55e7a28 (patch)
treec18eb1b1568ab0f0251339f7995b6ea177b3285f /crates/hir_ty/src/infer/expr.rs
parenta2ce091fd7e149f809bdf0ee0d960d9e185ee5fb (diff)
parentb8262099cc51065259daf10b4b23ff49ce74434f (diff)
Merge #8945
8945: fix: Make expected type work in more situations r=flodiebold a=flodiebold Also makes call info show the correct types for generic methods. ![2021-05-23-182952_1134x616_scrot](https://user-images.githubusercontent.com/906069/119269023-dd5a5b00-bbf5-11eb-993a-b6e122c3b9a6.png) ![2021-05-23-183117_922x696_scrot](https://user-images.githubusercontent.com/906069/119269025-dfbcb500-bbf5-11eb-983c-fc415b8428e0.png) Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/hir_ty/src/infer/expr.rs')
-rw-r--r--crates/hir_ty/src/infer/expr.rs34
1 files changed, 18 insertions, 16 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 08c05c67c..eab8fac91 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -891,17 +891,21 @@ impl<'a> InferenceContext<'a> {
891 method_name, 891 method_name,
892 ) 892 )
893 }); 893 });
894 let (derefed_receiver_ty, method_ty, def_generics) = match resolved { 894 let (derefed_receiver_ty, method_ty, substs) = match resolved {
895 Some((ty, func)) => { 895 Some((ty, func)) => {
896 let ty = canonicalized_receiver.decanonicalize_ty(ty); 896 let ty = canonicalized_receiver.decanonicalize_ty(ty);
897 self.write_method_resolution(tgt_expr, func); 897 let generics = generics(self.db.upcast(), func.into());
898 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) 898 let substs = self.substs_for_method_call(generics, generic_args, &ty);
899 self.write_method_resolution(tgt_expr, func, substs.clone());
900 (ty, self.db.value_ty(func.into()), substs)
899 } 901 }
900 None => (receiver_ty, Binders::empty(&Interner, self.err_ty()), None), 902 None => (
903 receiver_ty,
904 Binders::empty(&Interner, self.err_ty()),
905 Substitution::empty(&Interner),
906 ),
901 }; 907 };
902 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty);
903 let method_ty = method_ty.substitute(&Interner, &substs); 908 let method_ty = method_ty.substitute(&Interner, &substs);
904 let method_ty = self.insert_type_vars(method_ty);
905 self.register_obligations_for_call(&method_ty); 909 self.register_obligations_for_call(&method_ty);
906 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) { 910 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) {
907 Some(sig) => { 911 Some(sig) => {
@@ -950,23 +954,21 @@ impl<'a> InferenceContext<'a> {
950 954
951 fn substs_for_method_call( 955 fn substs_for_method_call(
952 &mut self, 956 &mut self,
953 def_generics: Option<Generics>, 957 def_generics: Generics,
954 generic_args: Option<&GenericArgs>, 958 generic_args: Option<&GenericArgs>,
955 receiver_ty: &Ty, 959 receiver_ty: &Ty,
956 ) -> Substitution { 960 ) -> Substitution {
957 let (parent_params, self_params, type_params, impl_trait_params) = 961 let (parent_params, self_params, type_params, impl_trait_params) =
958 def_generics.as_ref().map_or((0, 0, 0, 0), |g| g.provenance_split()); 962 def_generics.provenance_split();
959 assert_eq!(self_params, 0); // method shouldn't have another Self param 963 assert_eq!(self_params, 0); // method shouldn't have another Self param
960 let total_len = parent_params + type_params + impl_trait_params; 964 let total_len = parent_params + type_params + impl_trait_params;
961 let mut substs = Vec::with_capacity(total_len); 965 let mut substs = Vec::with_capacity(total_len);
962 // Parent arguments are unknown, except for the receiver type 966 // Parent arguments are unknown, except for the receiver type
963 if let Some(parent_generics) = def_generics.as_ref().map(|p| p.iter_parent()) { 967 for (_id, param) in def_generics.iter_parent() {
964 for (_id, param) in parent_generics { 968 if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf {
965 if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf { 969 substs.push(receiver_ty.clone());
966 substs.push(receiver_ty.clone()); 970 } else {
967 } else { 971 substs.push(self.table.new_type_var());
968 substs.push(self.err_ty());
969 }
970 } 972 }
971 } 973 }
972 // handle provided type arguments 974 // handle provided type arguments
@@ -989,7 +991,7 @@ impl<'a> InferenceContext<'a> {
989 }; 991 };
990 let supplied_params = substs.len(); 992 let supplied_params = substs.len();
991 for _ in supplied_params..total_len { 993 for _ in supplied_params..total_len {
992 substs.push(self.err_ty()); 994 substs.push(self.table.new_type_var());
993 } 995 }
994 assert_eq!(substs.len(), total_len); 996 assert_eq!(substs.len(), total_len);
995 Substitution::from_iter(&Interner, substs) 997 Substitution::from_iter(&Interner, substs)