diff options
Diffstat (limited to 'crates/ra_hir_ty/src/infer/expr.rs')
-rw-r--r-- | crates/ra_hir_ty/src/infer/expr.rs | 17 |
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 | } |