aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer/expr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/infer/expr.rs')
-rw-r--r--crates/hir_ty/src/infer/expr.rs49
1 files changed, 25 insertions, 24 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 08c05c67c..41ef45326 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -44,7 +44,7 @@ impl<'a> InferenceContext<'a> {
44 if !could_unify { 44 if !could_unify {
45 self.result.type_mismatches.insert( 45 self.result.type_mismatches.insert(
46 tgt_expr.into(), 46 tgt_expr.into(),
47 TypeMismatch { expected: expected_ty.clone(), actual: ty.clone() }, 47 TypeMismatch { expected: expected_ty, actual: ty.clone() },
48 ); 48 );
49 } 49 }
50 } 50 }
@@ -57,15 +57,14 @@ impl<'a> InferenceContext<'a> {
57 let ty = self.infer_expr_inner(expr, &expected); 57 let ty = self.infer_expr_inner(expr, &expected);
58 let ty = if let Some(target) = expected.only_has_type(&mut self.table) { 58 let ty = if let Some(target) = expected.only_has_type(&mut self.table) {
59 if !self.coerce(&ty, &target) { 59 if !self.coerce(&ty, &target) {
60 self.result.type_mismatches.insert( 60 self.result
61 expr.into(), 61 .type_mismatches
62 TypeMismatch { expected: target.clone(), actual: ty.clone() }, 62 .insert(expr.into(), TypeMismatch { expected: target, actual: ty.clone() });
63 );
64 // Return actual type when type mismatch. 63 // Return actual type when type mismatch.
65 // This is needed for diagnostic when return type mismatch. 64 // This is needed for diagnostic when return type mismatch.
66 ty 65 ty
67 } else { 66 } else {
68 target.clone() 67 target
69 } 68 }
70 } else { 69 } else {
71 ty 70 ty
@@ -120,7 +119,7 @@ impl<'a> InferenceContext<'a> {
120 } 119 }
121 120
122 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { 121 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
123 self.db.check_canceled(); 122 self.db.unwind_if_cancelled();
124 123
125 let body = Arc::clone(&self.body); // avoid borrow checker problem 124 let body = Arc::clone(&self.body); // avoid borrow checker problem
126 let ty = match &body[tgt_expr] { 125 let ty = match &body[tgt_expr] {
@@ -805,7 +804,7 @@ impl<'a> InferenceContext<'a> {
805 None => self.table.new_float_var(), 804 None => self.table.new_float_var(),
806 }, 805 },
807 }, 806 },
808 Expr::MacroStmts { tail } => self.infer_expr(*tail, expected), 807 Expr::MacroStmts { tail } => self.infer_expr_inner(*tail, expected),
809 }; 808 };
810 // use a new type variable if we got unknown here 809 // use a new type variable if we got unknown here
811 let ty = self.insert_type_vars_shallow(ty); 810 let ty = self.insert_type_vars_shallow(ty);
@@ -891,17 +890,21 @@ impl<'a> InferenceContext<'a> {
891 method_name, 890 method_name,
892 ) 891 )
893 }); 892 });
894 let (derefed_receiver_ty, method_ty, def_generics) = match resolved { 893 let (derefed_receiver_ty, method_ty, substs) = match resolved {
895 Some((ty, func)) => { 894 Some((ty, func)) => {
896 let ty = canonicalized_receiver.decanonicalize_ty(ty); 895 let ty = canonicalized_receiver.decanonicalize_ty(ty);
897 self.write_method_resolution(tgt_expr, func); 896 let generics = generics(self.db.upcast(), func.into());
898 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) 897 let substs = self.substs_for_method_call(generics, generic_args, &ty);
898 self.write_method_resolution(tgt_expr, func, substs.clone());
899 (ty, self.db.value_ty(func.into()), substs)
899 } 900 }
900 None => (receiver_ty, Binders::empty(&Interner, self.err_ty()), None), 901 None => (
902 receiver_ty,
903 Binders::empty(&Interner, self.err_ty()),
904 Substitution::empty(&Interner),
905 ),
901 }; 906 };
902 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty);
903 let method_ty = method_ty.substitute(&Interner, &substs); 907 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); 908 self.register_obligations_for_call(&method_ty);
906 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) { 909 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) {
907 Some(sig) => { 910 Some(sig) => {
@@ -950,23 +953,21 @@ impl<'a> InferenceContext<'a> {
950 953
951 fn substs_for_method_call( 954 fn substs_for_method_call(
952 &mut self, 955 &mut self,
953 def_generics: Option<Generics>, 956 def_generics: Generics,
954 generic_args: Option<&GenericArgs>, 957 generic_args: Option<&GenericArgs>,
955 receiver_ty: &Ty, 958 receiver_ty: &Ty,
956 ) -> Substitution { 959 ) -> Substitution {
957 let (parent_params, self_params, type_params, impl_trait_params) = 960 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()); 961 def_generics.provenance_split();
959 assert_eq!(self_params, 0); // method shouldn't have another Self param 962 assert_eq!(self_params, 0); // method shouldn't have another Self param
960 let total_len = parent_params + type_params + impl_trait_params; 963 let total_len = parent_params + type_params + impl_trait_params;
961 let mut substs = Vec::with_capacity(total_len); 964 let mut substs = Vec::with_capacity(total_len);
962 // Parent arguments are unknown, except for the receiver type 965 // Parent arguments are unknown, except for the receiver type
963 if let Some(parent_generics) = def_generics.as_ref().map(|p| p.iter_parent()) { 966 for (_id, param) in def_generics.iter_parent() {
964 for (_id, param) in parent_generics { 967 if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf {
965 if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf { 968 substs.push(receiver_ty.clone());
966 substs.push(receiver_ty.clone()); 969 } else {
967 } else { 970 substs.push(self.table.new_type_var());
968 substs.push(self.err_ty());
969 }
970 } 971 }
971 } 972 }
972 // handle provided type arguments 973 // handle provided type arguments
@@ -989,7 +990,7 @@ impl<'a> InferenceContext<'a> {
989 }; 990 };
990 let supplied_params = substs.len(); 991 let supplied_params = substs.len();
991 for _ in supplied_params..total_len { 992 for _ in supplied_params..total_len {
992 substs.push(self.err_ty()); 993 substs.push(self.table.new_type_var());
993 } 994 }
994 assert_eq!(substs.len(), total_len); 995 assert_eq!(substs.len(), total_len);
995 Substitution::from_iter(&Interner, substs) 996 Substitution::from_iter(&Interner, substs)