authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-01 21:59:55+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-02 16:26:50+00:00
log252c2031011f80b35d01d5ba5a2a2577c870f90c
tree9c7ed95ecf01033b19bce941df2b320cb34dc376
parente6879e99e26fd11f659be3deec2b5de409b46547

Sema: correctly label `block_comptime` for restoring error return trace index

Resolves: #22384

2 files changed, 19 insertions(+), 6 deletions(-)

src/Sema.zig+12-6
......@@ -1658,13 +1658,17 @@ fn analyzeBodyInner(
16581658 const extra = sema.code.extraData(Zir.Inst.BlockComptime, pl_node.payload_index);
16591659 const block_body = sema.code.bodySlice(extra.end, extra.data.body_len);
16601660
1661 if (block.isComptime()) {
1662 // No need for a sub-block; just resolve the other body directly!
1663 break :inst try sema.resolveInlineBody(block, block_body, inst);
1664 }
1665
16661661 var child_block = block.makeSubBlock();
16671662 defer child_block.instructions.deinit(sema.gpa);
1663
1664 // We won't have any merges, but we must ensure this block is properly labeled for
1665 // any `.restore_err_ret_index_*` instructions.
1666 var label: Block.Label = .{
1667 .zir_block = inst,
1668 .merges = undefined,
1669 };
1670 child_block.label = &label;
1671
16681672 child_block.comptime_reason = .{ .reason = .{
16691673 .src = src,
16701674 .r = .{ .simple = extra.data.reason },
......@@ -1672,7 +1676,9 @@ fn analyzeBodyInner(
16721676
16731677 const result = try sema.resolveInlineBody(&child_block, block_body, inst);
16741678
1675 if (!try sema.isComptimeKnown(result)) {
1679 // Only check for the result being comptime-known in the outermost `block_comptime`.
1680 // That way, AstGen can safely elide redundant `block_comptime` without affecting semantics.
1681 if (!block.isComptime() and !try sema.isComptimeKnown(result)) {
16761682 return sema.failWithNeededComptime(&child_block, src, null);
16771683 }
16781684
test/behavior/eval.zig+7
......@@ -1744,3 +1744,10 @@ test "block with comptime-known result but possible runtime exit is comptime-kno
17441744 comptime assert(a == 123);
17451745 comptime assert(b == 456);
17461746}
1747
1748test "comptime labeled block implicit exit" {
1749 const result = comptime b: {
1750 if (false) break :b 123;
1751 };
1752 comptime assert(result == {});
1753}