diff options
Diffstat (limited to 'crates/hir_ty/src/infer/expr.rs')
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 4ef847d3a..08c05c67c 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -138,13 +138,14 @@ impl<'a> InferenceContext<'a> { | |||
138 | let mut result_ty = self.table.new_type_var(); | 138 | let mut result_ty = self.table.new_type_var(); |
139 | let then_ty = self.infer_expr_inner(*then_branch, &expected); | 139 | let then_ty = self.infer_expr_inner(*then_branch, &expected); |
140 | both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe); | 140 | both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe); |
141 | result_ty = self.coerce_merge_branch(&result_ty, &then_ty); | 141 | result_ty = self.coerce_merge_branch(Some(*then_branch), &result_ty, &then_ty); |
142 | let else_ty = match else_branch { | 142 | let else_ty = match else_branch { |
143 | Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), | 143 | Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), |
144 | None => TyBuilder::unit(), | 144 | None => TyBuilder::unit(), |
145 | }; | 145 | }; |
146 | both_arms_diverge &= self.diverges; | 146 | both_arms_diverge &= self.diverges; |
147 | result_ty = self.coerce_merge_branch(&result_ty, &else_ty); | 147 | // FIXME: create a synthetic `else {}` so we have something to refer to here instead of None? |
148 | result_ty = self.coerce_merge_branch(*else_branch, &result_ty, &else_ty); | ||
148 | 149 | ||
149 | self.diverges = condition_diverges | both_arms_diverge; | 150 | self.diverges = condition_diverges | both_arms_diverge; |
150 | 151 | ||
@@ -358,7 +359,7 @@ impl<'a> InferenceContext<'a> { | |||
358 | 359 | ||
359 | let arm_ty = self.infer_expr_inner(arm.expr, &expected); | 360 | let arm_ty = self.infer_expr_inner(arm.expr, &expected); |
360 | all_arms_diverge &= self.diverges; | 361 | all_arms_diverge &= self.diverges; |
361 | result_ty = self.coerce_merge_branch(&result_ty, &arm_ty); | 362 | result_ty = self.coerce_merge_branch(Some(arm.expr), &result_ty, &arm_ty); |
362 | } | 363 | } |
363 | 364 | ||
364 | self.diverges = matchee_diverges | all_arms_diverge; | 365 | self.diverges = matchee_diverges | all_arms_diverge; |
@@ -372,12 +373,6 @@ impl<'a> InferenceContext<'a> { | |||
372 | } | 373 | } |
373 | Expr::Continue { .. } => TyKind::Never.intern(&Interner), | 374 | Expr::Continue { .. } => TyKind::Never.intern(&Interner), |
374 | Expr::Break { expr, label } => { | 375 | Expr::Break { expr, label } => { |
375 | let val_ty = if let Some(expr) = expr { | ||
376 | self.infer_expr(*expr, &Expectation::none()) | ||
377 | } else { | ||
378 | TyBuilder::unit() | ||
379 | }; | ||
380 | |||
381 | let last_ty = | 376 | let last_ty = |
382 | if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { | 377 | if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { |
383 | ctxt.break_ty.clone() | 378 | ctxt.break_ty.clone() |
@@ -385,7 +380,14 @@ impl<'a> InferenceContext<'a> { | |||
385 | self.err_ty() | 380 | self.err_ty() |
386 | }; | 381 | }; |
387 | 382 | ||
388 | let merged_type = self.coerce_merge_branch(&last_ty, &val_ty); | 383 | let val_ty = if let Some(expr) = expr { |
384 | self.infer_expr(*expr, &Expectation::none()) | ||
385 | } else { | ||
386 | TyBuilder::unit() | ||
387 | }; | ||
388 | |||
389 | // FIXME: create a synthetic `()` during lowering so we have something to refer to here? | ||
390 | let merged_type = self.coerce_merge_branch(*expr, &last_ty, &val_ty); | ||
389 | 391 | ||
390 | if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { | 392 | if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { |
391 | ctxt.break_ty = merged_type; | 393 | ctxt.break_ty = merged_type; |