1
Fork 0

lower bare boolean expression with if-construct

This commit is contained in:
Ding Xiang Fei 2023-06-20 16:29:39 +08:00
parent e5453b4806
commit d9ed11872f
No known key found for this signature in database
GPG key ID: 3CD748647EEF6359
3 changed files with 32 additions and 54 deletions

View file

@ -158,53 +158,43 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
end_block.unit() end_block.unit()
} }
} }
ExprKind::LogicalOp { op, lhs, rhs } => { ExprKind::LogicalOp { .. } => {
// And: let condition_scope = this.local_scope();
// let source_info = this.source_info(expr.span);
// [block: If(lhs)] -true-> [else_block: dest = (rhs)] let (then_block, else_block) =
// | (false) this.in_if_then_scope(condition_scope, expr.span, |this| {
// [shortcircuit_block: dest = false] this.then_else_break(
// block,
// Or: expr,
// Some(condition_scope),
// [block: If(lhs)] -false-> [else_block: dest = (rhs)] condition_scope,
// | (true) source_info,
// [shortcircuit_block: dest = true] )
});
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, &this.thir[lhs]));
let blocks = match op {
LogicalOp::And => (else_block, shortcircuit_block),
LogicalOp::Or => (shortcircuit_block, else_block),
};
let term = TerminatorKind::if_(lhs, blocks.0, blocks.1);
this.cfg.terminate(block, source_info, term);
this.cfg.push_assign_constant( this.cfg.push_assign_constant(
shortcircuit_block, then_block,
source_info, source_info,
destination, destination,
Constant { Constant {
span: expr_span, span: expr.span,
user_ty: None, user_ty: None,
literal: match op { literal: ConstantKind::from_bool(this.tcx, true),
LogicalOp::And => ConstantKind::from_bool(this.tcx, false),
LogicalOp::Or => ConstantKind::from_bool(this.tcx, true),
},
}, },
); );
this.cfg.goto(shortcircuit_block, source_info, join_block); this.cfg.push_assign_constant(
else_block,
let rhs = unpack!(else_block = this.as_local_operand(else_block, &this.thir[rhs])); source_info,
this.cfg.push_assign(else_block, source_info, destination, Rvalue::Use(rhs)); destination,
this.cfg.goto(else_block, source_info, join_block); Constant {
span: expr.span,
join_block.unit() user_ty: None,
literal: ConstantKind::from_bool(this.tcx, false),
},
);
let target = this.cfg.start_new_block();
this.cfg.goto(then_block, source_info, target);
this.cfg.goto(else_block, source_info, target);
target.unit()
} }
ExprKind::Loop { body } => { ExprKind::Loop { body } => {
// [block] // [block]

View file

@ -1,3 +1,5 @@
// check-pass
fn and_chain() { fn and_chain() {
let z; let z;
if true && { z = 3; true} && z == 3 {} if true && { z = 3; true} && z == 3 {}
@ -6,7 +8,6 @@ fn and_chain() {
fn and_chain_2() { fn and_chain_2() {
let z; let z;
true && { z = 3; true} && z == 3; true && { z = 3; true} && z == 3;
//~^ ERROR E0381
} }
fn or_chain() { fn or_chain() {

View file

@ -1,13 +0,0 @@
error[E0381]: used binding `z` is possibly-uninitialized
--> $DIR/chains-without-let.rs:8:31
|
LL | let z;
| - binding declared here but left uninitialized
LL | true && { z = 3; true} && z == 3;
| ----- ^ `z` used here but it is possibly-uninitialized
| |
| binding initialized here in some conditions
error: aborting due to previous error
For more information about this error, try `rustc --explain E0381`.