@@ -58,52 +58,61 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
5858 this. thir [ scrutinee] . span ,
5959 ) ,
6060 ExprKind :: If { cond, then, else_opt, if_then_scope } => {
61- let then_blk;
6261 let then_span = this. thir [ then] . span ;
6362 let then_source_info = this. source_info ( then_span) ;
6463 let condition_scope = this. local_scope ( ) ;
6564
66- let mut else_blk = unpack ! (
67- then_blk = this. in_scope(
68- ( if_then_scope, then_source_info) ,
69- LintLevel :: Inherited ,
70- |this| {
71- let source_info = if this. is_let( cond) {
72- let variable_scope =
73- this. new_source_scope( then_span, LintLevel :: Inherited , None ) ;
74- this. source_scope = variable_scope;
75- SourceInfo { span: then_span, scope: variable_scope }
76- } else {
77- this. source_info( then_span)
78- } ;
79- let ( then_block, else_block) =
80- this. in_if_then_scope( condition_scope, then_span, |this| {
81- let then_blk = unpack!( this. then_else_break(
82- block,
83- cond,
84- Some ( condition_scope) , // Temp scope
85- condition_scope,
86- source_info,
87- true , // Declare `let` bindings normally
88- ) ) ;
89-
90- this. expr_into_dest( destination, then_blk, then)
91- } ) ;
92- then_block. and( else_block)
93- } ,
94- )
65+ let then_and_else_blocks = this. in_scope (
66+ ( if_then_scope, then_source_info) ,
67+ LintLevel :: Inherited ,
68+ |this| {
69+ // FIXME: Does this need extra logic to handle let-chains?
70+ let source_info = if this. is_let ( cond) {
71+ let variable_scope =
72+ this. new_source_scope ( then_span, LintLevel :: Inherited , None ) ;
73+ this. source_scope = variable_scope;
74+ SourceInfo { span : then_span, scope : variable_scope }
75+ } else {
76+ this. source_info ( then_span)
77+ } ;
78+
79+ // Lower the condition, and have it branch into `then` and `else` blocks.
80+ let ( then_block, else_block) =
81+ this. in_if_then_scope ( condition_scope, then_span, |this| {
82+ let then_blk = unpack ! ( this. then_else_break(
83+ block,
84+ cond,
85+ Some ( condition_scope) , // Temp scope
86+ condition_scope,
87+ source_info,
88+ true , // Declare `let` bindings normally
89+ ) ) ;
90+
91+ // Lower the `then` arm into its block.
92+ this. expr_into_dest ( destination, then_blk, then)
93+ } ) ;
94+
95+ // Pack `(then_block, else_block)` into `BlockAnd<BasicBlock>`.
96+ then_block. and ( else_block)
97+ } ,
9598 ) ;
9699
97- else_blk = if let Some ( else_opt) = else_opt {
98- unpack ! ( this. expr_into_dest( destination, else_blk, else_opt) )
100+ // Unpack `BlockAnd<BasicBlock>` into `(then_blk, else_blk)`.
101+ let ( then_blk, mut else_blk) ;
102+ else_blk = unpack ! ( then_blk = then_and_else_blocks) ;
103+
104+ // If there is an `else` arm, lower it into `else_blk`.
105+ if let Some ( else_expr) = else_opt {
106+ unpack ! ( else_blk = this. expr_into_dest( destination, else_blk, else_expr) ) ;
99107 } else {
100- // Body of the `if` expression without an `else` clause must return `()`, thus
101- // we implicitly generate an `else {}` if it is not specified .
108+ // There is no `else` arm, so we know both arms have type `()`.
109+ // Generate the implicit `else {}` by assigning unit .
102110 let correct_si = this. source_info ( expr_span. shrink_to_hi ( ) ) ;
103111 this. cfg . push_assign_unit ( else_blk, correct_si, destination, this. tcx ) ;
104- else_blk
105- } ;
112+ }
106113
114+ // The `then` and `else` arms have been lowered into their respective
115+ // blocks, so make both of them meet up in a new block.
107116 let join_block = this. cfg . start_new_block ( ) ;
108117 this. cfg . goto ( then_blk, source_info, join_block) ;
109118 this. cfg . goto ( else_blk, source_info, join_block) ;
0 commit comments