motiejus/zig

fork of https://codeberg.org/ziglang/zig
git clone https://git.jakstys.lt/motiejus/zig.git
Log | Tree | Refs | README | LICENSE

commit c3bef00f7499ea37cf5ae8d6f5e008ddf49ba583 (tree)
parent b4b778a10d8facc2fc1edb0581ba7428e1f1e937
Author: Motiejus Jakštys <motiejus@jakstys.lt>
Date:   Sun, 15 Mar 2026 16:08:56 +0000

zig0: fix 6 astgen test failures

1. globalVarDecl: type break_inline used gz->decl_node_index (parent)
   instead of type_gz.decl_node_index (=node), producing non-zero
   offset where Zig produces 0. Fixes extern var and union-with-var.

2. switchExprNone: used refIsNoReturn(parent_gz, result) to decide
   whether to emit break after switch prong body, but fullBodyExpr
   returns void_value for unlabeled blocks ending with break/noreturn.
   Changed to endsWithNoReturn(&scratch_scope) matching Zig. Also
   fixed the same bug in switchExprErrUnionInner inline case handling.

3. switchExprNone/switchExprErrUnionInner: dbg_var_val was emitted
   after save_err_ret_index, but Zig emits dbg_var_val first. Swapped
   order to match.

4. switchExprErrUnionInner: identAsString for error payload was called
   after operand evaluation, but Zig calls it before the first-pass
   counting loop. Moved to match string_bytes ordering.

5. switchExprNone/switchExprErrUnionInner: is_simple_noreturn for else
   prong didn't detect |e| return e pattern. Added identAsString
   comparison matching Zig's logic (AstGen.zig:7775-7780).

All 441 tests now pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Diffstat:
Mstage0/astgen.c | 42++++++++++++++++++++++++------------------
1 file changed, 24 insertions(+), 18 deletions(-)

diff --git a/stage0/astgen.c b/stage0/astgen.c @@ -6748,8 +6748,7 @@ static void globalVarDecl(AstGen* ag, GenZir* gz, Scope* scope, .ctx = RI_CTX_NONE }; uint32_t type_inst = expr(&type_gz, &type_gz.base, coerced_type_rl, vd.type_node); - genZir_makeBreak(&type_gz, decl_inst, type_inst, - (int32_t)node - (int32_t)gz->decl_node_index); + genZir_makeBreak(&type_gz, decl_inst, type_inst, 0); } // Record type_gz boundary for slicing. @@ -10324,6 +10323,10 @@ static uint32_t switchExprErrUnionInner(GenZir* parent_gz, Scope* scope, non_err_is_ref = (ri.tag == RL_REF || ri.tag == RL_REF_COERCED_TY); } + // Error capture name (AstGen.zig:7106-7112). + // Must be before first pass to match string_bytes ordering. + uint32_t err_name = identAsString(ag, error_payload); + // First pass: count cases. uint32_t scalar_cases_len = 0; uint32_t multi_cases_len = 0; @@ -10402,9 +10405,6 @@ static uint32_t switchExprErrUnionInner(GenZir* parent_gz, Scope* scope, payload_capture_inst_is_placeholder = true; } - // Error capture name. - uint32_t err_name = identAsString(ag, error_payload); - // Item result info. ResultInfo item_ri = { .tag = RL_COERCED_TY, .data = switch_inst + ZIR_REF_START_INDEX, @@ -10588,7 +10588,7 @@ static uint32_t switchExprErrUnionInner(GenZir* parent_gz, Scope* scope, scratch_scope.instructions_top = ag->scratch_inst_len; uint32_t item_result = fullBodyExpr( &scratch_scope, scope, item_ri, item); - if (!genZir_refIsNoReturn(parent_gz, item_result)) + if (!genZir_endsWithNoReturn(&scratch_scope)) genZir_addBreak(&scratch_scope, ZIR_INST_BREAK_INLINE, switch_inst, item_result, @@ -10677,13 +10677,13 @@ static uint32_t switchExprErrUnionInner(GenZir* parent_gz, Scope* scope, scratch_scope.instructions_top = ag->scratch_inst_len; - if (do_err_trace && nodeMayAppendToErrorTrace(tree, operand_node)) - genZir_addSaveErrRetIndex(&scratch_scope, ZIR_REF_NONE); - if (dbg_var_name != 0) genZir_addDbgVar(&scratch_scope, ZIR_INST_DBG_VAR_VAL, dbg_var_name, dbg_var_inst); + if (do_err_trace && nodeMayAppendToErrorTrace(tree, operand_node)) + genZir_addSaveErrRetIndex(&scratch_scope, ZIR_REF_NONE); + uint32_t body_node = cd.rhs; uint32_t result = fullBodyExpr(&scratch_scope, sub_scope, block_scope.break_result_info, body_node); @@ -10729,6 +10729,15 @@ static uint32_t switchExprErrUnionInner(GenZir* parent_gz, Scope* scope, AstData retd = tree->nodes.datas[body_node]; if (retd.lhs == 0) is_simple_noreturn = true; + else if (capture == 1 + && tree->nodes.tags[retd.lhs] == AST_NODE_IDENTIFIER) { + // Check |e| return e pattern (AstGen.zig:7775-7780). + uint32_t payload_token = arrow_token + 2; + uint32_t ret_ident = tree->nodes.main_tokens[retd.lhs]; + uint32_t payload_name = identAsString(ag, payload_token); + uint32_t retval_name = identAsString(ag, ret_ident); + is_simple_noreturn = (payload_name == retval_name); + } } else_info_val = (body_len & 0x07FFFFFFu) | ((capture & 3u) << 27) | ((is_inline ? 1u : 0u) << 29) @@ -11150,7 +11159,7 @@ static uint32_t switchExprNone( scratch_scope.instructions_top = ag->scratch_inst_len; uint32_t item_result = fullBodyExpr( &scratch_scope, scope, item_ri, item); - if (!genZir_refIsNoReturn(parent_gz, item_result)) { + if (!genZir_endsWithNoReturn(&scratch_scope)) { genZir_addBreak(&scratch_scope, ZIR_INST_BREAK_INLINE, switch_inst, item_result, @@ -11274,7 +11283,7 @@ static uint32_t switchExprNone( uint32_t body_node = cd.rhs; uint32_t result = fullBodyExpr(&scratch_scope, sub_scope, block_scope.break_result_info, body_node); - if (!genZir_refIsNoReturn(parent_gz, result)) { + if (!genZir_endsWithNoReturn(&scratch_scope)) { genZir_addBreak(&scratch_scope, ZIR_INST_BREAK, switch_inst, result, (int32_t)body_node - (int32_t)parent_gz->decl_node_index); @@ -11305,15 +11314,12 @@ static uint32_t switchExprNone( is_simple_noreturn = true; else if (capture == 1 && tree->nodes.tags[retd.lhs] == AST_NODE_IDENTIFIER) { - // Check |e| return e pattern. - // Simplified: just check if token slices match. + // Check |e| return e pattern (AstGen.zig:7775-7780). uint32_t payload_token = arrow_token + 2; uint32_t ret_ident = tree->nodes.main_tokens[retd.lhs]; - if (tree->tokens.starts[payload_token] - != tree->tokens.starts[ret_ident]) { - // Different tokens, check content. - // (Simplified: compare strings) - } + uint32_t payload_name = identAsString(ag, payload_token); + uint32_t retval_name = identAsString(ag, ret_ident); + is_simple_noreturn = (payload_name == retval_name); } } else_info_val = (body_len & 0x07FFFFFFu) | ((capture & 3u) << 27)