Skip to content

Commit 39cf0b5

Browse files
use if only on lhs of binary logical exprs
1 parent d9ed118 commit 39cf0b5

File tree

1 file changed

+18
-16
lines changed
  • compiler/rustc_mir_build/src/build/expr

1 file changed

+18
-16
lines changed

compiler/rustc_mir_build/src/build/expr/into.rs

+18-16
Original file line numberDiff line numberDiff line change
@@ -158,42 +158,44 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
158158
end_block.unit()
159159
}
160160
}
161-
ExprKind::LogicalOp { .. } => {
161+
ExprKind::LogicalOp { op, lhs, rhs } => {
162162
let condition_scope = this.local_scope();
163163
let source_info = this.source_info(expr.span);
164+
// We first evaluate the left-hand side of the predicate ...
164165
let (then_block, else_block) =
165166
this.in_if_then_scope(condition_scope, expr.span, |this| {
166167
this.then_else_break(
167168
block,
168-
expr,
169+
&this.thir[lhs],
169170
Some(condition_scope),
170171
condition_scope,
171172
source_info,
172173
)
173174
});
175+
let (short_circuit, continuation, constant) = match op {
176+
LogicalOp::And => (else_block, then_block, false),
177+
LogicalOp::Or => (then_block, else_block, true),
178+
};
179+
// At this point, the control flow splits into a short-circuiting path
180+
// and a continuation path.
181+
// - If the operator is `&&`, passing `lhs` leads to continuation of evaluation on `rhs`;
182+
// failing it leads to the short-circuting path which assigns `false` to the place.
183+
// - If the operator is `||`, failing `lhs` leads to continuation of evaluation on `rhs`;
184+
// passing it leads to the short-circuting path which assigns `true` to the place.
174185
this.cfg.push_assign_constant(
175-
then_block,
176-
source_info,
177-
destination,
178-
Constant {
179-
span: expr.span,
180-
user_ty: None,
181-
literal: ConstantKind::from_bool(this.tcx, true),
182-
},
183-
);
184-
this.cfg.push_assign_constant(
185-
else_block,
186+
short_circuit,
186187
source_info,
187188
destination,
188189
Constant {
189190
span: expr.span,
190191
user_ty: None,
191-
literal: ConstantKind::from_bool(this.tcx, false),
192+
literal: ConstantKind::from_bool(this.tcx, constant),
192193
},
193194
);
195+
let rhs = unpack!(this.expr_into_dest(destination, continuation, &this.thir[rhs]));
194196
let target = this.cfg.start_new_block();
195-
this.cfg.goto(then_block, source_info, target);
196-
this.cfg.goto(else_block, source_info, target);
197+
this.cfg.goto(rhs, source_info, target);
198+
this.cfg.goto(short_circuit, source_info, target);
197199
target.unit()
198200
}
199201
ExprKind::Loop { body } => {

0 commit comments

Comments
 (0)