From 6a316287cc61c57c48c6dadad99922f7fbe2aaf8 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 9 Mar 2017 09:53:00 -0500 Subject: [PATCH 1/2] refactor if so that the "then type" is an expression --- src/librustc/cfg/construct.rs | 4 +-- src/librustc/hir/intravisit.rs | 2 +- src/librustc/hir/lowering.rs | 6 +++-- src/librustc/hir/mod.rs | 2 +- src/librustc/hir/print.rs | 6 ++--- src/librustc/middle/expr_use_visitor.rs | 4 +-- src/librustc/middle/liveness.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 2 +- src/librustc_typeck/check/mod.rs | 35 ++++++++----------------- 9 files changed, 26 insertions(+), 37 deletions(-) diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 4567795184e4d..71ac663e7e4e1 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -169,7 +169,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 } @@ -189,7 +189,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 } diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index fd6796ccc0bf2..168573ebdd28d 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -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) => { diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 257cdb960d529..6df1b8d9815ee 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1645,7 +1645,9 @@ impl<'a> LoweringContext<'a> { } }); - hir::ExprIf(P(self.lower_expr(cond)), self.lower_block(blk), else_opt) + let then_blk = self.lower_block(blk); + 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| @@ -1852,7 +1854,7 @@ impl<'a> LoweringContext<'a> { attrs: hir_vec![], pats: hir_vec![pat_under], guard: Some(cond), - body: P(self.expr_block(then, ThinVec::new())), + body: then, }); else_opt.map(|else_opt| (else_opt, true)) } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 22bc28eb3fec0..4c911fa9fed86 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -927,7 +927,7 @@ pub enum Expr_ { /// An `if` block, with an optional else block /// /// `if expr { block } else { expr }` - ExprIf(P, P, Option>), + ExprIf(P, P, Option>), /// A while loop, with an optional label /// /// `'label: while expr { block }` diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 3411de9bb5df1..04a65fd5e3aa4 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -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) } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index a44679b0b3e0e..c7cf4a35a4bc7 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -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); } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index a8c1559ae2373..8f91d0d289de4 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -943,7 +943,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); diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index c67bb8ec6c585..786b4ef05c5a7 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -633,7 +633,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(), } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 2b9ccf6d3e246..0b752677cb188 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2733,7 +2733,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> { @@ -2742,7 +2742,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); @@ -2757,26 +2757,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). @@ -3566,9 +3553,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(); From 002950b05c82299a7e3b26434628f5a665e122b5 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 9 Mar 2017 09:57:26 -0500 Subject: [PATCH 2/2] update comment --- src/librustc/hir/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 4c911fa9fed86..d6ad2ceb163b6 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -926,7 +926,7 @@ pub enum Expr_ { ExprType(P, P), /// An `if` block, with an optional else block /// - /// `if expr { block } else { expr }` + /// `if expr { expr } else { expr }` ExprIf(P, P, Option>), /// A while loop, with an optional label ///