diff options
Diffstat (limited to 'crates/ra_hir_ty/src/infer')
-rw-r--r-- | crates/ra_hir_ty/src/infer/coerce.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/expr.rs | 19 |
2 files changed, 19 insertions, 4 deletions
diff --git a/crates/ra_hir_ty/src/infer/coerce.rs b/crates/ra_hir_ty/src/infer/coerce.rs index 0f4dac45e..83c0c2c3f 100644 --- a/crates/ra_hir_ty/src/infer/coerce.rs +++ b/crates/ra_hir_ty/src/infer/coerce.rs | |||
@@ -134,6 +134,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
134 | } | 134 | } |
135 | } | 135 | } |
136 | 136 | ||
137 | (ty_app!(TypeCtor::Closure { .. }, params), ty_app!(TypeCtor::FnPtr { .. })) => { | ||
138 | from_ty = params[0].clone(); | ||
139 | } | ||
140 | |||
137 | _ => {} | 141 | _ => {} |
138 | } | 142 | } |
139 | 143 | ||
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index 8be567917..3af05394c 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs | |||
@@ -41,7 +41,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
41 | 41 | ||
42 | /// Infer type of expression with possibly implicit coerce to the expected type. | 42 | /// Infer type of expression with possibly implicit coerce to the expected type. |
43 | /// Return the type after possible coercion. | 43 | /// Return the type after possible coercion. |
44 | fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty { | 44 | pub(super) fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty { |
45 | let ty = self.infer_expr_inner(expr, &expected); | 45 | let ty = self.infer_expr_inner(expr, &expected); |
46 | let ty = if !self.coerce(&ty, &expected.ty) { | 46 | let ty = if !self.coerce(&ty, &expected.ty) { |
47 | self.result | 47 | self.result |
@@ -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 | } |