commit 53b1108601371e9eda06a884b3ddebb090fb11d4 (tree)
parent 3e8281100f49763bbd58bdcb7a3c01f6d78500a5
Author: Motiejus Jakštys <motiejus@jakstys.lt>
Date: Sat, 14 Feb 2026 18:46:00 +0000
astgen: fix @TypeOf scope, add multi-arg @TypeOf
- Fix single-arg @TypeOf to use `scope` instead of `&gz->base` for the
sub-block parent, matching upstream (AstGen.zig:9104). This fixes
local variable visibility inside @TypeOf arguments.
- Implement multi-arg @TypeOf using ZIR_EXT_TYPEOF_PEER extended
instruction (AstGen.zig:9120-9146).
- Remove debug fprintf from SET_ERROR macro and structDeclInner.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat:
| M | stage0/astgen.c | | | 59 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- |
1 file changed, 58 insertions(+), 1 deletion(-)
diff --git a/stage0/astgen.c b/stage0/astgen.c
@@ -3605,7 +3605,7 @@ static uint32_t builtinCall(
AstData nd = tree->nodes.datas[node];
uint32_t typeof_inst
= makeBlockInst(ag, ZIR_INST_TYPEOF_BUILTIN, gz, node);
- GenZir typeof_scope = makeSubBlock(gz, &gz->base);
+ GenZir typeof_scope = makeSubBlock(gz, scope);
typeof_scope.is_comptime = false;
typeof_scope.is_typeof = true;
typeof_scope.c_import = false;
@@ -4293,6 +4293,63 @@ static uint32_t builtinCallMultiArg(GenZir* gz, Scope* scope, ResultLoc rl,
gz, ZIR_INST_SHUFFLE, node, payload_index);
return rvalue(gz, rl, result, node);
}
+ // @TypeOf multi-arg (AstGen.zig:9120-9146).
+ if (name_len == 6 && memcmp(source + name_start, "TypeOf", 6) == 0) {
+ // Reserve extra space: 3 (TypeOfPeer payload) + param_count (refs).
+ uint32_t payload_size = 3; // src_node, body_len, body_index
+ ensureExtraCapacity(ag, payload_size + param_count);
+ uint32_t payload_index = ag->extra_len;
+ ag->extra_len += payload_size + param_count;
+ uint32_t args_index = payload_index + payload_size;
+
+ // Create the extended instruction (AstGen.zig:9124).
+ uint32_t typeof_inst = ag->inst_len;
+ ensureInstCapacity(ag, 1);
+ ag->inst_tags[typeof_inst] = ZIR_INST_EXTENDED;
+ ZirInstData tdata;
+ memset(&tdata, 0, sizeof(tdata));
+ tdata.extended.opcode = (uint16_t)ZIR_EXT_TYPEOF_PEER;
+ tdata.extended.small = (uint16_t)param_count;
+ tdata.extended.operand = payload_index;
+ ag->inst_datas[typeof_inst] = tdata;
+ ag->inst_len++;
+ gzAppendInstruction(gz, typeof_inst);
+
+ // Create sub-block scope (AstGen.zig:9126-9128).
+ GenZir typeof_scope = makeSubBlock(gz, scope);
+ typeof_scope.is_comptime = false;
+
+ // Evaluate each arg (AstGen.zig:9129-9132).
+ for (uint32_t i = 0; i < param_count; i++) {
+ uint32_t param_ref = reachableExpr(
+ &typeof_scope, &typeof_scope.base, RL_NONE_VAL,
+ params[i], node);
+ ag->extra[args_index + i] = param_ref;
+ }
+
+ // Add break_inline (AstGen.zig:9133).
+ addBreak(&typeof_scope, ZIR_INST_BREAK_INLINE,
+ typeof_inst, ZIR_REF_VOID_VALUE,
+ (int32_t)node - (int32_t)gz->decl_node_index);
+
+ // Get body and fill in payload (AstGen.zig:9135-9141).
+ uint32_t raw_len = gzInstructionsLen(&typeof_scope);
+ const uint32_t* body = gzInstructionsSlice(&typeof_scope);
+ uint32_t body_len = countBodyLenAfterFixups(ag, body, raw_len);
+
+ ag->extra[payload_index + 0]
+ = (uint32_t)((int32_t)node - (int32_t)gz->decl_node_index);
+ ag->extra[payload_index + 1] = body_len;
+ ag->extra[payload_index + 2] = ag->extra_len;
+
+ // Append body with fixups (AstGen.zig:9142-9143).
+ ensureExtraCapacity(ag, body_len);
+ for (uint32_t j = 0; j < raw_len; j++)
+ appendPossiblyRefdBodyInst(ag, body[j]);
+
+ gzUnstack(&typeof_scope);
+ return rvalue(gz, rl, typeof_inst + ZIR_REF_START_INDEX, node);
+ }
// clang-format on
// TODO: handle other multi-arg builtins.