aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/infer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r--crates/ra_hir/src/ty/infer.rs36
1 files changed, 26 insertions, 10 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 4784fad85..378d2f829 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -790,11 +790,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
790 }; 790 };
791 self.unify(&expected_receiver_ty, &actual_receiver_ty); 791 self.unify(&expected_receiver_ty, &actual_receiver_ty);
792 792
793 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown)); 793 self.check_call_arguments(args, &param_tys);
794 for (arg, param_ty) in args.iter().zip(param_iter) {
795 let param_ty = self.normalize_associated_types_in(param_ty);
796 self.infer_expr(*arg, &Expectation::has_type(param_ty));
797 }
798 let ret_ty = self.normalize_associated_types_in(ret_ty); 794 let ret_ty = self.normalize_associated_types_in(ret_ty);
799 ret_ty 795 ret_ty
800 } 796 }
@@ -928,11 +924,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
928 } 924 }
929 }; 925 };
930 self.register_obligations_for_call(&callee_ty); 926 self.register_obligations_for_call(&callee_ty);
931 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown)); 927 self.check_call_arguments(args, &param_tys);
932 for (arg, param_ty) in args.iter().zip(param_iter) {
933 let param_ty = self.normalize_associated_types_in(param_ty);
934 self.infer_expr(*arg, &Expectation::has_type(param_ty));
935 }
936 let ret_ty = self.normalize_associated_types_in(ret_ty); 928 let ret_ty = self.normalize_associated_types_in(ret_ty);
937 ret_ty 929 ret_ty
938 } 930 }
@@ -1274,6 +1266,30 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1274 ty 1266 ty
1275 } 1267 }
1276 1268
1269 fn check_call_arguments(&mut self, args: &[ExprId], param_tys: &[Ty]) {
1270 // Quoting https://github.com/rust-lang/rust/blob/6ef275e6c3cb1384ec78128eceeb4963ff788dca/src/librustc_typeck/check/mod.rs#L3325 --
1271 // We do this in a pretty awful way: first we type-check any arguments
1272 // that are not closures, then we type-check the closures. This is so
1273 // that we have more information about the types of arguments when we
1274 // type-check the functions. This isn't really the right way to do this.
1275 for &check_closures in &[false, true] {
1276 let param_iter = param_tys.iter().cloned().chain(repeat(Ty::Unknown));
1277 for (&arg, param_ty) in args.iter().zip(param_iter) {
1278 let is_closure = match &self.body[arg] {
1279 Expr::Lambda { .. } => true,
1280 _ => false,
1281 };
1282
1283 if is_closure != check_closures {
1284 continue;
1285 }
1286
1287 let param_ty = self.normalize_associated_types_in(param_ty);
1288 self.infer_expr(arg, &Expectation::has_type(param_ty));
1289 }
1290 }
1291 }
1292
1277 fn collect_const(&mut self, data: &ConstData) { 1293 fn collect_const(&mut self, data: &ConstData) {
1278 self.return_ty = self.make_ty(data.type_ref()); 1294 self.return_ty = self.make_ty(data.type_ref());
1279 } 1295 }