From c3d477753602fea1ebd962386794b4f1ae69b7ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Motiejus=20Jak=C5=A1tys?= Date: Fri, 13 Feb 2026 16:28:34 +0000 Subject: [PATCH] astgen: fix lastToken for BREAK/CONTINUE and ERROR_VALUE - BREAK/CONTINUE: lhs is opt_token (null=UINT32_MAX), not opt_node (null=0). Check nd.lhs != UINT32_MAX instead of != 0. - ERROR_VALUE: last token is main_token + 2 (error.name has 3 tokens), not main_token. - advanceSourceCursor: replace silent return on backward movement with assert, matching upstream behavior. Co-Authored-By: Claude Opus 4.6 --- astgen.c | 14 +++++++++----- astgen_test.zig | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/astgen.c b/astgen.c index 46588944e9..cac642f070 100644 --- a/astgen.c +++ b/astgen.c @@ -580,9 +580,7 @@ static void advanceSourceCursor(AstGenCtx* ag, uint32_t end) { uint32_t i = ag->source_offset; uint32_t line = ag->source_line; uint32_t column = ag->source_column; - if (i > end) { - return; // Cursor already past target; skip (cursor ordering issue). - } + assert(i <= end); while (i < end) { if (source[i] == '\n') { line++; @@ -7017,6 +7015,11 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) { } continue; + // error_value: main_token is `error`, last token is name (+2) + // (Ast.zig:986). + case AST_NODE_ERROR_VALUE: + return tree->nodes.main_tokens[n] + 2 + end_offset; + // Terminals: return main_token + end_offset (Ast.zig:988-996). case AST_NODE_NUMBER_LITERAL: case AST_NODE_STRING_LITERAL: @@ -7025,7 +7028,6 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) { case AST_NODE_CHAR_LITERAL: case AST_NODE_UNREACHABLE_LITERAL: case AST_NODE_ANYFRAME_LITERAL: - case AST_NODE_ERROR_VALUE: return tree->nodes.main_tokens[n] + end_offset; // call_one: recurse into lhs, +1 for ')'. @@ -7354,11 +7356,13 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) { return nd.rhs + end_offset; // break/continue (Ast.zig:1275-1283). + // lhs is opt_token (null_token = UINT32_MAX), rhs is opt_node (0 = + // none). case AST_NODE_BREAK: case AST_NODE_CONTINUE: if (nd.rhs != 0) { n = nd.rhs; // optional rhs expression - } else if (nd.lhs != 0) { + } else if (nd.lhs != UINT32_MAX) { return nd.lhs + end_offset; // label token } else { return tree->nodes.main_tokens[n] + end_offset; diff --git a/astgen_test.zig b/astgen_test.zig index 666fbfb936..5c8fc6856d 100644 --- a/astgen_test.zig +++ b/astgen_test.zig @@ -798,7 +798,7 @@ test "astgen: corpus tokenizer_test.zig" { } test "astgen: corpus astgen_test.zig" { - if (true) return error.SkipZigTest; // TODO: dbg_stmt cursor backward at inst 1557 + if (true) return error.SkipZigTest; // TODO: store_node ref off-by-1 at inst 1764 const gpa = std.testing.allocator; try corpusCheck(gpa, @embedFile("astgen_test.zig")); }