refactor if so that the "then type" is an expression
This commit is contained in:
parent
fe151194e9
commit
276bba9039
@ -195,7 +195,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
||||
// [..expr..]
|
||||
//
|
||||
let cond_exit = self.expr(&cond, pred); // 1
|
||||
let then_exit = self.block(&then, cond_exit); // 2
|
||||
let then_exit = self.expr(&then, cond_exit); // 2
|
||||
self.add_ast_node(expr.id, &[cond_exit, then_exit]) // 3,4
|
||||
}
|
||||
|
||||
@ -215,7 +215,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
||||
// [..expr..]
|
||||
//
|
||||
let cond_exit = self.expr(&cond, pred); // 1
|
||||
let then_exit = self.block(&then, cond_exit); // 2
|
||||
let then_exit = self.expr(&then, cond_exit); // 2
|
||||
let else_exit = self.expr(&otherwise, cond_exit); // 3
|
||||
self.add_ast_node(expr.id, &[then_exit, else_exit]) // 4, 5
|
||||
}
|
||||
|
@ -960,7 +960,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
|
||||
}
|
||||
ExprIf(ref head_expression, ref if_block, ref optional_else) => {
|
||||
visitor.visit_expr(head_expression);
|
||||
visitor.visit_block(if_block);
|
||||
visitor.visit_expr(if_block);
|
||||
walk_list!(visitor, visit_expr, optional_else);
|
||||
}
|
||||
ExprWhile(ref subexpression, ref block, ref opt_sp_name) => {
|
||||
|
@ -1856,7 +1856,10 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
});
|
||||
|
||||
hir::ExprIf(P(self.lower_expr(cond)), self.lower_block(blk, None), else_opt)
|
||||
let then_blk = self.lower_block(blk, None);
|
||||
let then_expr = self.expr_block(then_blk, ThinVec::new());
|
||||
|
||||
hir::ExprIf(P(self.lower_expr(cond)), P(then_expr), else_opt)
|
||||
}
|
||||
ExprKind::While(ref cond, ref body, opt_ident) => {
|
||||
self.with_loop_scope(e.id, |this|
|
||||
|
@ -994,7 +994,7 @@ pub enum Expr_ {
|
||||
/// An `if` block, with an optional else block
|
||||
///
|
||||
/// `if expr { block } else { expr }`
|
||||
ExprIf(P<Expr>, P<Block>, Option<P<Expr>>),
|
||||
ExprIf(P<Expr>, P<Expr>, Option<P<Expr>>),
|
||||
/// A while loop, with an optional label
|
||||
///
|
||||
/// `'label: while expr { block }`
|
||||
|
@ -1036,7 +1036,7 @@ impl<'a> State<'a> {
|
||||
word(&mut self.s, " else if ")?;
|
||||
self.print_expr(&i)?;
|
||||
space(&mut self.s)?;
|
||||
self.print_block(&then)?;
|
||||
self.print_expr(&then)?;
|
||||
self.print_else(e.as_ref().map(|e| &**e))
|
||||
}
|
||||
// "final else"
|
||||
@ -1058,13 +1058,13 @@ impl<'a> State<'a> {
|
||||
|
||||
pub fn print_if(&mut self,
|
||||
test: &hir::Expr,
|
||||
blk: &hir::Block,
|
||||
blk: &hir::Expr,
|
||||
elseopt: Option<&hir::Expr>)
|
||||
-> io::Result<()> {
|
||||
self.head("if")?;
|
||||
self.print_expr(test)?;
|
||||
space(&mut self.s)?;
|
||||
self.print_block(blk)?;
|
||||
self.print_expr(blk)?;
|
||||
self.print_else(elseopt)
|
||||
}
|
||||
|
||||
|
@ -414,9 +414,9 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||
self.consume_exprs(exprs);
|
||||
}
|
||||
|
||||
hir::ExprIf(ref cond_expr, ref then_blk, ref opt_else_expr) => {
|
||||
hir::ExprIf(ref cond_expr, ref then_expr, ref opt_else_expr) => {
|
||||
self.consume_expr(&cond_expr);
|
||||
self.walk_block(&then_blk);
|
||||
self.walk_expr(&then_expr);
|
||||
if let Some(ref else_expr) = *opt_else_expr {
|
||||
self.consume_expr(&else_expr);
|
||||
}
|
||||
|
@ -951,7 +951,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
// ( succ )
|
||||
//
|
||||
let else_ln = self.propagate_through_opt_expr(els.as_ref().map(|e| &**e), succ);
|
||||
let then_ln = self.propagate_through_block(&then, succ);
|
||||
let then_ln = self.propagate_through_expr(&then, succ);
|
||||
let ln = self.live_node(expr.id, expr.span);
|
||||
self.init_from_succ(ln, else_ln);
|
||||
self.merge_from_succ(ln, then_ln, false);
|
||||
|
@ -636,7 +636,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
hir::ExprIf(ref cond, ref then, ref otherwise) => {
|
||||
ExprKind::If {
|
||||
condition: cond.to_ref(),
|
||||
then: block::to_expr_ref(cx, then),
|
||||
then: then.to_ref(),
|
||||
otherwise: otherwise.to_ref(),
|
||||
}
|
||||
}
|
||||
|
@ -2739,7 +2739,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
// or if-else.
|
||||
fn check_then_else(&self,
|
||||
cond_expr: &'gcx hir::Expr,
|
||||
then_blk: &'gcx hir::Block,
|
||||
then_expr: &'gcx hir::Expr,
|
||||
opt_else_expr: Option<&'gcx hir::Expr>,
|
||||
sp: Span,
|
||||
expected: Expectation<'tcx>) -> Ty<'tcx> {
|
||||
@ -2748,7 +2748,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
self.diverges.set(Diverges::Maybe);
|
||||
|
||||
let expected = expected.adjust_for_branches(self);
|
||||
let then_ty = self.check_block_with_expected(then_blk, expected);
|
||||
let then_ty = self.check_expr_with_expectation(then_expr, expected);
|
||||
let then_diverges = self.diverges.get();
|
||||
self.diverges.set(Diverges::Maybe);
|
||||
|
||||
@ -2763,26 +2763,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
// to assign coercions to, otherwise it's () or diverging.
|
||||
expected_ty = then_ty;
|
||||
found_ty = else_ty;
|
||||
result = if let Some(ref then) = then_blk.expr {
|
||||
let res = self.try_find_coercion_lub(&cause, || Some(&**then),
|
||||
then_ty, else_expr, else_ty);
|
||||
|
||||
// In case we did perform an adjustment, we have to update
|
||||
// the type of the block, because old trans still uses it.
|
||||
if res.is_ok() {
|
||||
let adj = self.tables.borrow().adjustments.get(&then.id).cloned();
|
||||
if let Some(adj) = adj {
|
||||
self.write_ty(then_blk.id, adj.target);
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
} else {
|
||||
self.commit_if_ok(|_| {
|
||||
let trace = TypeTrace::types(&cause, true, then_ty, else_ty);
|
||||
self.lub(true, trace, &then_ty, &else_ty)
|
||||
.map(|ok| self.register_infer_ok_obligations(ok))
|
||||
})
|
||||
let coerce_to = expected.only_has_type(self).unwrap_or(then_ty);
|
||||
result = {
|
||||
self.try_coerce(then_expr, then_ty, coerce_to)
|
||||
.and_then(|t| {
|
||||
self.try_find_coercion_lub(&cause, || Some(then_expr), t, else_expr, else_ty)
|
||||
})
|
||||
};
|
||||
|
||||
// We won't diverge unless both branches do (or the condition does).
|
||||
@ -3587,9 +3574,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
tcx.mk_nil()
|
||||
}
|
||||
}
|
||||
hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
|
||||
self.check_then_else(&cond, &then_blk, opt_else_expr.as_ref().map(|e| &**e),
|
||||
expr.span, expected)
|
||||
hir::ExprIf(ref cond, ref then_expr, ref opt_else_expr) => {
|
||||
self.check_then_else(&cond, then_expr, opt_else_expr.as_ref().map(|e| &**e),
|
||||
expr.span, expected)
|
||||
}
|
||||
hir::ExprWhile(ref cond, ref body, _) => {
|
||||
let unified = self.tcx.mk_nil();
|
||||
|
Loading…
Reference in New Issue
Block a user