| ... | @@ -5287,33 +5287,51 @@ fn resolveBlockBody( | ... | @@ -5287,33 +5287,51 @@ fn resolveBlockBody( |
| 5287 | return sema.resolveAnalyzedBlock(parent_block, src, child_block, merges, need_debug_scope); | 5287 | return sema.resolveAnalyzedBlock(parent_block, src, child_block, merges, need_debug_scope); |
| 5288 | } else |err| switch (err) { | 5288 | } else |err| switch (err) { |
| 5289 | error.ComptimeBreak => { | 5289 | error.ComptimeBreak => { |
| | 5290 | const break_inst = sema.comptime_break_inst; |
| | 5291 | const break_data = sema.code.instructions.items(.data)[@intFromEnum(break_inst)].@"break"; |
| | 5292 | const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data; |
| | 5293 | const breaks_to_body = extra.block_inst == body_inst; |
| | 5294 | |
| 5290 | // Comptime control flow is happening, however child_block may still contain | 5295 | // Comptime control flow is happening, however child_block may still contain |
| 5291 | // runtime instructions which need to be copied to the parent block. | 5296 | // runtime instructions which need to be copied to the parent block. |
| 5292 | if (need_debug_scope and child_block.instructions.items.len > 0) { | 5297 | if (need_debug_scope and child_block.instructions.items.len > 0) { |
| 5293 | // We need a runtime block for scoping reasons. | 5298 | // We need a runtime block for scoping reasons. The break |
| 5294 | _ = try child_block.addBr(merges.block_inst, .void_value); | 5299 | // operand may have been produced by a runtime instruction |
| | 5300 | // inside `child_blocks`. |
| | 5301 | const operand = sema.resolveInst(break_data.operand); |
| | 5302 | const operand_ty = sema.typeOf(operand); |
| | 5303 | _ = try child_block.addBr(merges.block_inst, operand); |
| 5295 | try parent_block.instructions.append(sema.gpa, merges.block_inst); | 5304 | try parent_block.instructions.append(sema.gpa, merges.block_inst); |
| 5296 | try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Block).@"struct".field_names.len + | 5305 | try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Block).@"struct".field_names.len + |
| 5297 | child_block.instructions.items.len); | 5306 | child_block.instructions.items.len); |
| 5298 | sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{ | 5307 | sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{ |
| 5299 | .ty = .void_type, | 5308 | .ty = Air.internedToRef(operand_ty.toIntern()), |
| 5300 | .payload = sema.addExtraAssumeCapacity(Air.Block{ | 5309 | .payload = sema.addExtraAssumeCapacity(Air.Block{ |
| 5301 | .body_len = @intCast(child_block.instructions.items.len), | 5310 | .body_len = @intCast(child_block.instructions.items.len), |
| 5302 | }), | 5311 | }), |
| 5303 | } }; | 5312 | } }; |
| 5304 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(child_block.instructions.items)); | 5313 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(child_block.instructions.items)); |
| | 5314 | |
| | 5315 | // The block result now holds the operand value, so we remap |
| | 5316 | // the operand such that an enclosing scope which resolves |
| | 5317 | // it picks up the block result rather than the internal |
| | 5318 | // block instruction. |
| | 5319 | if (break_data.operand.toIndex()) |operand_zir| { |
| | 5320 | sema.inst_map.putAssumeCapacity(operand_zir, merges.block_inst.toRef()); |
| | 5321 | } |
| | 5322 | if (breaks_to_body) { |
| | 5323 | return merges.block_inst.toRef(); |
| | 5324 | } else { |
| | 5325 | return error.ComptimeBreak; |
| | 5326 | } |
| 5305 | } else { | 5327 | } else { |
| 5306 | // We can copy instructions directly to the parent block. | 5328 | // We can copy instructions directly to the parent block. |
| 5307 | try parent_block.instructions.appendSlice(sema.gpa, child_block.instructions.items); | 5329 | try parent_block.instructions.appendSlice(sema.gpa, child_block.instructions.items); |
| 5308 | } | 5330 | if (breaks_to_body) { |
| 5309 | | 5331 | return sema.resolveInst(break_data.operand); |
| 5310 | const break_inst = sema.comptime_break_inst; | 5332 | } else { |
| 5311 | const break_data = sema.code.instructions.items(.data)[@intFromEnum(break_inst)].@"break"; | 5333 | return error.ComptimeBreak; |
| 5312 | const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data; | 5334 | } |
| 5313 | if (extra.block_inst == body_inst) { | | |
| 5314 | return sema.resolveInst(break_data.operand); | | |
| 5315 | } else { | | |
| 5316 | return error.ComptimeBreak; | | |
| 5317 | } | 5335 | } |
| 5318 | }, | 5336 | }, |
| 5319 | else => |e| return e, | 5337 | else => |e| return e, |