@@ -120,6 +120,42 @@ impl MirBuilder<'_> {
120120 }
121121 }
122122
123+ t:: ExprKind :: If { cond, then_branch, else_branch : Some ( else_branch) } => {
124+ let cond_place = Place { local : self . new_local ( expr. ty . clone ( ) ) , projection : Vec :: new ( ) } ;
125+ self . lower_expr ( cond_place. clone ( ) , * cond) ;
126+ let then_block = self . new_block ( ) ;
127+ let else_block = self . new_block ( ) ;
128+ let join_block = self . new_block ( ) ;
129+ self . set_terminator ( Terminator :: Branch ( Operand :: Move ( cond_place) , then_block, else_block) ) ;
130+
131+ self . switch_block ( then_block) ;
132+ self . lower_expr ( dest. clone ( ) , * then_branch) ;
133+ self . set_terminator ( Terminator :: Goto ( join_block) ) ;
134+
135+ self . switch_block ( else_block) ;
136+ self . lower_expr ( dest, * else_branch) ;
137+ self . set_terminator ( Terminator :: Goto ( join_block) ) ;
138+
139+ self . switch_block ( join_block) ;
140+ return ;
141+ }
142+
143+ t:: ExprKind :: If { cond, then_branch, else_branch : None } => {
144+ let cond_place = Place { local : self . new_local ( expr. ty . clone ( ) ) , projection : Vec :: new ( ) } ;
145+ self . lower_expr ( cond_place. clone ( ) , * cond) ;
146+ let then_block = self . new_block ( ) ;
147+ let join_block = self . new_block ( ) ;
148+ self . set_terminator ( Terminator :: Branch ( Operand :: Move ( cond_place) , then_block, join_block) ) ;
149+
150+ self . switch_block ( then_block) ;
151+ let fresh = Place { local : self . new_local ( then_branch. ty . clone ( ) ) , projection : Vec :: new ( ) } ;
152+ self . lower_expr ( fresh, * then_branch) ;
153+ self . set_terminator ( Terminator :: Goto ( join_block) ) ;
154+
155+ self . switch_block ( join_block) ;
156+ RValue :: Use ( Operand :: Const ( Const :: Unit ) )
157+ }
158+
123159 t:: ExprKind :: Error ( _) => RValue :: Poison ,
124160 } ;
125161
@@ -138,6 +174,22 @@ impl MirBuilder<'_> {
138174 let block = & mut self . blocks [ self . current_block . 0 as usize ] ;
139175 block. instrs . push ( instr) ;
140176 }
177+
178+ fn set_terminator ( & mut self , terminator : Terminator ) {
179+ let block = & mut self . blocks [ self . current_block . 0 as usize ] ;
180+ block. terminator = terminator;
181+ }
182+
183+ fn switch_block ( & mut self , block : BlockId ) {
184+ assert ! ( ( block. 0 as usize ) < self . blocks. len( ) , "[Lowerer] Internal error: switched to non-existing block" ) ;
185+ self . current_block = block;
186+ }
187+
188+ fn new_block ( & mut self ) -> BlockId {
189+ let id = BlockId ( self . blocks . len ( ) as u32 ) ;
190+ self . blocks . push ( Block { instrs : vec ! [ ] , terminator : Terminator :: Unreachable } ) ;
191+ id
192+ }
141193}
142194
143195
0 commit comments