@@ -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