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>
This commit is contained in:
2026-02-14 18:46:00 +00:00
parent 3bcb29bee8
commit 95044f9932

View File

@@ -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.