提交 276bba90 编写于 作者: N Niko Matsakis

refactor if so that the "then type" is an expression

上级 fe151194
......@@ -195,7 +195,7 @@ fn expr(&mut self, expr: &hir::Expr, pred: CFGIndex) -> CFGIndex {
// [..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 @@ fn expr(&mut self, expr: &hir::Expr, pred: CFGIndex) -> CFGIndex {
// [..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 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
}
});
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 @@ fn print_else(&mut self, els: Option<&hir::Expr>) -> io::Result<()> {
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 @@ fn print_else(&mut self, els: Option<&hir::Expr>) -> io::Result<()> {
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 @@ pub fn walk_expr(&mut self, expr: &hir::Expr) {
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 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
// ( 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 @@ fn check_method_call(&self,
// 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 @@ fn check_then_else(&self,
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 @@ fn check_then_else(&self,
// 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 @@ fn check_expr_kind(&self,
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();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册