ExprKind::LogicalOp { op, lhs, rhs } => {
// And:
//
- // [block: If(lhs)] -true-> [else_block: If(rhs)] -true-> [true_block]
- // | | (false)
- // +----------false-----------+------------------> [false_block]
+ // [block: If(lhs)] -true-> [else_block: dest = (rhs)]
+ // | (false)
+ // [shortcurcuit_block: dest = false]
//
// Or:
//
- // [block: If(lhs)] -false-> [else_block: If(rhs)] -true-> [true_block]
- // | (true) | (false)
- // [true_block] [false_block]
+ // [block: If(lhs)] -false-> [else_block: dest = (rhs)]
+ // | (true)
+ // [shortcurcuit_block: dest = true]
- let (true_block, false_block, mut else_block, join_block) = (
- this.cfg.start_new_block(),
+ let (shortcircuit_block, mut else_block, join_block) = (
this.cfg.start_new_block(),
this.cfg.start_new_block(),
this.cfg.start_new_block(),
let lhs = unpack!(block = this.as_local_operand(block, lhs));
let blocks = match op {
- LogicalOp::And => (else_block, false_block),
- LogicalOp::Or => (true_block, else_block),
+ LogicalOp::And => (else_block, shortcircuit_block),
+ LogicalOp::Or => (shortcircuit_block, else_block),
};
let term = TerminatorKind::if_(this.hir.tcx(), lhs, blocks.0, blocks.1);
this.cfg.terminate(block, source_info, term);
- let rhs = unpack!(else_block = this.as_local_operand(else_block, rhs));
- let term = TerminatorKind::if_(this.hir.tcx(), rhs, true_block, false_block);
- this.cfg.terminate(else_block, source_info, term);
-
this.cfg.push_assign_constant(
- true_block,
+ shortcircuit_block,
source_info,
destination,
Constant {
span: expr_span,
ty: this.hir.bool_ty(),
user_ty: None,
- literal: this.hir.true_literal(),
+ literal: match op {
+ LogicalOp::And => this.hir.false_literal(),
+ LogicalOp::Or => this.hir.true_literal(),
+ },
},
);
-
- this.cfg.push_assign_constant(
- false_block,
+ this.cfg.terminate(
+ shortcircuit_block,
source_info,
- destination,
- Constant {
- span: expr_span,
- ty: this.hir.bool_ty(),
- user_ty: None,
- literal: this.hir.false_literal(),
- },
+ TerminatorKind::Goto { target: join_block },
);
- this.cfg.terminate(
- true_block,
+ let rhs = unpack!(else_block = this.as_local_operand(else_block, rhs));
+ this.cfg.push_assign(
+ else_block,
source_info,
- TerminatorKind::Goto { target: join_block },
+ destination,
+ Rvalue::Use(rhs),
);
this.cfg.terminate(
- false_block,
+ else_block,
source_info,
TerminatorKind::Goto { target: join_block },
);