commit 52bfd87de71976773135e1204124c0180ed3a7c8 (tree)
parent befbe18ebc89b719e1f6ec9a6c48d2b588de8d02
Author: Motiejus Jakštys <motiejus@jakstys.lt>
Date: Fri, 13 Feb 2026 21:48:16 +0000
astgen: fix defer RL annotation, compile_error noreturn, block force_comptime
Three bugs found by auditing against upstream AstGen.zig/AstRlAnnotate.zig:
1. rlExpr: defer was recursing into nd.rhs (always 0) instead of nd.lhs
(the actual deferred expression), so the RL annotation pass never
visited defer bodies.
2. addEnsureResult: compile_error was missing from the noreturn
instruction list, causing spurious ensure_result_used instructions
to be emitted after @compileError calls.
3. blockExprExpr: force_comptime was derived from gz->is_comptime,
but upstream blockExpr always passes force_comptime=false to
labeledBlockExpr. This caused labeled blocks in comptime contexts
to incorrectly emit BLOCK_COMPTIME + BREAK_INLINE instead of
BLOCK + BREAK.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat:
| M | astgen.c | | | 38 | ++++++++++++-------------------------- |
1 file changed, 12 insertions(+), 26 deletions(-)
diff --git a/astgen.c b/astgen.c
@@ -4762,7 +4762,7 @@ static uint32_t blockExprExpr(
}
// Labeled block (AstGen.zig:2466-2536).
- bool force_comptime = gz->is_comptime;
+ // Note: upstream blockExpr always passes force_comptime=false.
uint32_t label_token = lbrace - 2;
// Compute break result info (AstGen.zig:2484-2492).
@@ -4771,15 +4771,10 @@ static uint32_t blockExprExpr(
bool need_result_rvalue = (break_ri.tag != rl.tag);
// Reserve the block instruction (AstGen.zig:2500-2501).
- ZirInstTag block_tag
- = force_comptime ? ZIR_INST_BLOCK_COMPTIME : ZIR_INST_BLOCK;
- uint32_t block_inst = makeBlockInst(ag, block_tag, gz, node);
+ uint32_t block_inst = makeBlockInst(ag, ZIR_INST_BLOCK, gz, node);
gzAppendInstruction(gz, block_inst);
GenZir block_scope = makeSubBlock(gz, scope);
- block_scope.is_inline = force_comptime; // AstGen.zig:2503
- if (force_comptime)
- block_scope.is_comptime = true;
// Set label on block_scope (AstGen.zig:2504-2508).
block_scope.label_token = label_token;
block_scope.label_block_inst = block_inst;
@@ -4790,29 +4785,19 @@ static uint32_t blockExprExpr(
if (!endsWithNoReturn(&block_scope)) {
// Emit restore_err_ret_index (AstGen.zig:2515).
- if (!force_comptime) {
- ZirInstData rdata;
- rdata.un_node.operand = block_inst + ZIR_REF_START_INDEX;
- rdata.un_node.src_node
- = (int32_t)node - (int32_t)gz->decl_node_index;
- addInstruction(
- gz, ZIR_INST_RESTORE_ERR_RET_INDEX_UNCONDITIONAL, rdata);
- }
+ ZirInstData rdata;
+ rdata.un_node.operand = block_inst + ZIR_REF_START_INDEX;
+ rdata.un_node.src_node = (int32_t)node - (int32_t)gz->decl_node_index;
+ addInstruction(
+ gz, ZIR_INST_RESTORE_ERR_RET_INDEX_UNCONDITIONAL, rdata);
// rvalue + break (AstGen.zig:2516-2518).
uint32_t result = rvalue(
gz, block_scope.break_result_info, ZIR_REF_VOID_VALUE, node);
- ZirInstTag break_tag
- = force_comptime ? ZIR_INST_BREAK_INLINE : ZIR_INST_BREAK;
- addBreak(
- &block_scope, break_tag, block_inst, result, AST_NODE_OFFSET_NONE);
+ addBreak(&block_scope, ZIR_INST_BREAK, block_inst, result,
+ AST_NODE_OFFSET_NONE);
}
- if (force_comptime) {
- setBlockComptimeBody(
- ag, &block_scope, block_inst, COMPTIME_REASON_COMPTIME_KEYWORD);
- } else {
- setBlockBody(ag, &block_scope, block_inst);
- }
+ setBlockBody(ag, &block_scope, block_inst);
// AstGen.zig:2531-2534.
if (need_result_rvalue)
@@ -6602,6 +6587,7 @@ static bool addEnsureResult(
case ZIR_INST_TRAP:
case ZIR_INST_CHECK_COMPTIME_CONTROL_FLOW:
case ZIR_INST_SWITCH_CONTINUE:
+ case ZIR_INST_COMPILE_ERROR:
is_noreturn = true;
elide_check = true;
break;
@@ -9577,7 +9563,7 @@ static bool rlExpr(
// defer (AstRlAnnotate.zig:148-151).
case AST_NODE_DEFER:
- (void)rlExpr(ag, nd.rhs, block, RL_RI_NONE);
+ (void)rlExpr(ag, nd.lhs, block, RL_RI_NONE);
return false;
// container_field (AstRlAnnotate.zig:153-167).