aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/infer
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-12-20 15:41:32 +0000
committerFlorian Diebold <[email protected]>2019-12-20 17:16:11 +0000
commit2a8c9100bfb1294a469bc039a5b9597eabed7073 (patch)
treeae4e2dd0ae2c62baf79ec1197f5ec5f94a7645e5 /crates/ra_hir_ty/src/infer
parentcfc50ff160d0af2ce5cd931c6d41161abfdb2fbd (diff)
Handle closure return types
Fixes #2547.
Diffstat (limited to 'crates/ra_hir_ty/src/infer')
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs17
1 files changed, 14 insertions, 3 deletions
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index 8be567917..253332c30 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -102,7 +102,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
102 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 102 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
103 Ty::unit() 103 Ty::unit()
104 } 104 }
105 Expr::Lambda { body, args, arg_types } => { 105 Expr::Lambda { body, args, ret_type, arg_types } => {
106 assert_eq!(args.len(), arg_types.len()); 106 assert_eq!(args.len(), arg_types.len());
107 107
108 let mut sig_tys = Vec::new(); 108 let mut sig_tys = Vec::new();
@@ -118,7 +118,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
118 } 118 }
119 119
120 // add return type 120 // add return type
121 let ret_ty = self.table.new_type_var(); 121 let ret_ty = match ret_type {
122 Some(type_ref) => self.make_ty(type_ref),
123 None => self.table.new_type_var(),
124 };
122 sig_tys.push(ret_ty.clone()); 125 sig_tys.push(ret_ty.clone());
123 let sig_ty = Ty::apply( 126 let sig_ty = Ty::apply(
124 TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 }, 127 TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 },
@@ -134,7 +137,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
134 // infer the body. 137 // infer the body.
135 self.coerce(&closure_ty, &expected.ty); 138 self.coerce(&closure_ty, &expected.ty);
136 139
137 self.infer_expr(*body, &Expectation::has_type(ret_ty)); 140 let prev_ret_ty = std::mem::replace(&mut self.return_ty, ret_ty.clone());
141
142 self.infer_expr_coerce(*body, &Expectation::has_type(ret_ty));
143
144 self.return_ty = prev_ret_ty;
145
138 closure_ty 146 closure_ty
139 } 147 }
140 Expr::Call { callee, args } => { 148 Expr::Call { callee, args } => {
@@ -192,6 +200,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
192 Expr::Return { expr } => { 200 Expr::Return { expr } => {
193 if let Some(expr) = expr { 201 if let Some(expr) = expr {
194 self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone())); 202 self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone()));
203 } else {
204 let unit = Ty::unit();
205 self.coerce(&unit, &self.return_ty.clone());
195 } 206 }
196 Ty::simple(TypeCtor::Never) 207 Ty::simple(TypeCtor::Never)
197 } 208 }