| ... | ... | @@ -5118,8 +5118,10 @@ fn setCondBrPayloadElideBlockStorePtr( |
| 5118 | 5118 | const astgen = then_scope.astgen; |
| 5119 | 5119 | const then_body = then_scope.instructionsSliceUpto(else_scope); |
| 5120 | 5120 | const else_body = else_scope.instructionsSlice(); |
| 5121 | | const then_body_len = @intCast(u32, then_body.len + @boolToInt(then_break != 0)); |
| 5122 | | const else_body_len = @intCast(u32, else_body.len + @boolToInt(else_break != 0)); |
| 5121 | const has_then_break = then_break != 0; |
| 5122 | const has_else_break = else_break != 0; |
| 5123 | const then_body_len = @intCast(u32, then_body.len + @boolToInt(has_then_break)); |
| 5124 | const else_body_len = @intCast(u32, else_body.len + @boolToInt(has_else_break)); |
| 5123 | 5125 | try astgen.extra.ensureUnusedCapacity(astgen.gpa, @typeInfo(Zir.Inst.CondBr).Struct.fields.len + |
| 5124 | 5126 | then_body_len + else_body_len); |
| 5125 | 5127 | |
| ... | ... | @@ -5135,26 +5137,49 @@ fn setCondBrPayloadElideBlockStorePtr( |
| 5135 | 5137 | const then_body_len_index = condbr_pl + 1; |
| 5136 | 5138 | const else_body_len_index = condbr_pl + 2; |
| 5137 | 5139 | |
| 5140 | // The break instructions need to have their operands coerced if the |
| 5141 | // switch's result location is a `ty`. In this case we overwrite the |
| 5142 | // `store_to_block_ptr` instruction with an `as` instruction and repurpose |
| 5143 | // it as the break operand. |
| 5138 | 5144 | for (then_body) |src_inst| { |
| 5139 | | if (zir_tags[src_inst] == .store_to_block_ptr) { |
| 5140 | | if (zir_datas[src_inst].bin.lhs == block_ptr) { |
| 5145 | if (zir_tags[src_inst] == .store_to_block_ptr and |
| 5146 | zir_datas[src_inst].bin.lhs == block_ptr) |
| 5147 | { |
| 5148 | if (then_scope.rl_ty_inst != .none and has_then_break) { |
| 5149 | zir_tags[src_inst] = .as; |
| 5150 | zir_datas[src_inst].bin = .{ |
| 5151 | .lhs = then_scope.rl_ty_inst, |
| 5152 | .rhs = zir_datas[then_break].@"break".operand, |
| 5153 | }; |
| 5154 | zir_datas[then_break].@"break".operand = indexToRef(src_inst); |
| 5155 | } else { |
| 5141 | 5156 | astgen.extra.items[then_body_len_index] -= 1; |
| 5142 | 5157 | continue; |
| 5143 | 5158 | } |
| 5144 | 5159 | } |
| 5145 | 5160 | astgen.extra.appendAssumeCapacity(src_inst); |
| 5146 | 5161 | } |
| 5147 | | if (then_break != 0) astgen.extra.appendAssumeCapacity(then_break); |
| 5162 | if (has_then_break) astgen.extra.appendAssumeCapacity(then_break); |
| 5163 | |
| 5148 | 5164 | for (else_body) |src_inst| { |
| 5149 | | if (zir_tags[src_inst] == .store_to_block_ptr) { |
| 5150 | | if (zir_datas[src_inst].bin.lhs == block_ptr) { |
| 5165 | if (zir_tags[src_inst] == .store_to_block_ptr and |
| 5166 | zir_datas[src_inst].bin.lhs == block_ptr) |
| 5167 | { |
| 5168 | if (else_scope.rl_ty_inst != .none and has_else_break) { |
| 5169 | zir_tags[src_inst] = .as; |
| 5170 | zir_datas[src_inst].bin = .{ |
| 5171 | .lhs = else_scope.rl_ty_inst, |
| 5172 | .rhs = zir_datas[else_break].@"break".operand, |
| 5173 | }; |
| 5174 | zir_datas[else_break].@"break".operand = indexToRef(src_inst); |
| 5175 | } else { |
| 5151 | 5176 | astgen.extra.items[else_body_len_index] -= 1; |
| 5152 | 5177 | continue; |
| 5153 | 5178 | } |
| 5154 | 5179 | } |
| 5155 | 5180 | astgen.extra.appendAssumeCapacity(src_inst); |
| 5156 | 5181 | } |
| 5157 | | if (else_break != 0) astgen.extra.appendAssumeCapacity(else_break); |
| 5182 | if (has_else_break) astgen.extra.appendAssumeCapacity(else_break); |
| 5158 | 5183 | } |
| 5159 | 5184 | |
| 5160 | 5185 | fn whileExpr( |
| ... | ... | @@ -9460,6 +9485,7 @@ const GenZir = struct { |
| 9460 | 9485 | .decl_node_index = gz.decl_node_index, |
| 9461 | 9486 | .decl_line = gz.decl_line, |
| 9462 | 9487 | .parent = scope, |
| 9488 | .rl_ty_inst = gz.rl_ty_inst, |
| 9463 | 9489 | .astgen = gz.astgen, |
| 9464 | 9490 | .suspend_node = gz.suspend_node, |
| 9465 | 9491 | .nosuspend_node = gz.nosuspend_node, |