commit 72706fb3a8c0307033dd70ba62d7e3850ef846bf (tree)
parent c59d8cec39f123c8fd5d1f7da420af3cb5e8c5ea
Author: Motiejus <motiejus@jakstys.lt>
Date: Sat, 7 Mar 2026 17:53:34 +0000
sema: port ptr_type, optional_type, builtin_value for num_passing=4
Add zirPtrType handler for comptime blocks using resolveInst-based
element type resolution (unlike resolveZirPtrTypeInst which uses ZIR).
Add optional_type handler for comptime blocks.
Generalize builtin_value handler with name table mapping all 12 type
kinds, and call ensureNavValUpToDate for unresolved navs.
Fix resolveStructFieldInitsC to skip pre-interned default values
(void, true, false, etc.) instead of crashing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat:
2 files changed, 110 insertions(+), 27 deletions(-)
diff --git a/stage0/corpus.zig b/stage0/corpus.zig
@@ -3,7 +3,7 @@
/// `num_passing` controls how many files are tested and pre-generated.
/// Both build.zig and stages_test.zig import this file.
/// To enable more tests: just increment `num_passing`.
-pub const num_passing: usize = 1;
+pub const num_passing: usize = 4;
pub const files = [_][]const u8{
"stage0/sema_tests/empty.zig",
diff --git a/stage0/sema.c b/stage0/sema.c
@@ -1413,6 +1413,65 @@ static AirInstRef zirBoolNot(Sema* sema, SemaBlock* block, uint32_t inst) {
return semaAddInst(block, AIR_INST_NOT, data);
}
+// zirPtrType: handle ptr_type ZIR instruction in comptime blocks.
+// Ported from Sema.zig zirPtrType (simplified: no align/addrspace/bitrange).
+// Creates pointer or slice type IP entries.
+static AirInstRef zirPtrType(Sema* sema, SemaBlock* block, uint32_t inst) {
+ (void)block;
+ uint8_t flags = sema->code.inst_datas[inst].ptr_type.flags;
+ uint8_t size = sema->code.inst_datas[inst].ptr_type.size;
+ uint32_t pi = sema->code.inst_datas[inst].ptr_type.payload_index;
+
+ // extra[pi] = elem_type Ref.
+ ZirInstRef elem_ref = sema->code.extra[pi];
+ bool has_sentinel = (flags & (1 << 3)) != 0;
+ bool is_mutable = (flags & (1 << 1)) != 0;
+
+ // Resolve element type through inst_map (comptime evaluation).
+ AirInstRef elem_air = resolveInst(sema, elem_ref);
+ InternPoolIndex child_ip = elem_air;
+
+ // Read trailing sentinel if present.
+ uint32_t trail = pi + 2;
+ InternPoolIndex sentinel_ip = IP_INDEX_NONE;
+ if (has_sentinel) {
+ ZirInstRef sent_ref = sema->code.extra[trail];
+ AirInstRef sent_air = resolveInst(sema, sent_ref);
+ sentinel_ip = sent_air;
+ trail++;
+ }
+ (void)trail;
+
+ // Build pointer flags.
+ uint32_t ptr_flags = 0;
+ if (size == 2)
+ ptr_flags = PTR_FLAGS_SIZE_MANY;
+ else
+ ptr_flags = (uint32_t)size;
+ if (!is_mutable)
+ ptr_flags |= PTR_FLAGS_IS_CONST;
+
+ // Create pointer type.
+ InternPoolKey ptr_key;
+ memset(&ptr_key, 0, sizeof(ptr_key));
+ ptr_key.tag = IP_KEY_PTR_TYPE;
+ ptr_key.data.ptr_type.child = child_ip;
+ ptr_key.data.ptr_type.sentinel = sentinel_ip;
+ ptr_key.data.ptr_type.flags = ptr_flags;
+ ptr_key.data.ptr_type.packed_offset = 0;
+ InternPoolIndex ptr_ip = ipIntern(sema->ip, ptr_key);
+
+ if (size == 2) {
+ // Slice type wrapping the many-pointer.
+ InternPoolKey slice_key;
+ memset(&slice_key, 0, sizeof(slice_key));
+ slice_key.tag = IP_KEY_SLICE;
+ slice_key.data.slice = ptr_ip;
+ return AIR_REF_FROM_IP(ipIntern(sema->ip, slice_key));
+ }
+ return AIR_REF_FROM_IP(ptr_ip);
+}
+
// zirHasDecl: handle has_decl ZIR instruction (@hasDecl).
// Ported from src/Sema.zig zirHasDecl.
// Returns bool_true if the container type's namespace has the named decl.
@@ -4451,10 +4510,9 @@ static void resolveStructFieldInitsC(Sema* sema, const Zir* zir,
continue;
}
- // Must be a ZIR instruction ref.
+ // Pre-interned ref (void, true, false, etc.) — already in IP.
if (operand < ZIR_REF_START_INDEX)
- UNIMPLEMENTED(
- "resolveStructFieldInitsC: pre-interned default value");
+ continue;
uint32_t operand_inst = operand - ZIR_REF_START_INDEX;
if (operand_inst >= zir->inst_len)
continue;
@@ -10840,33 +10898,35 @@ static AirInstRef zirExtended(Sema* sema, SemaBlock* block, uint32_t inst) {
return AIR_REF_FROM_IP(lhs_ty);
}
// builtin_value: return the type from std.builtin.
- // Ported from src/Sema.zig builtinValue.
+ // Ported from src/Sema.zig zirBuiltinValue.
if (opcode == ZIR_EXT_BUILTIN_VALUE) {
uint16_t bv_kind = sema->code.inst_datas[inst].extended.small;
- if (bv_kind == ZIR_BUILTIN_VALUE_CALLING_CONVENTION
- && sema->zcu->builtin_file_idx != UINT32_MAX) {
+ // Map BuiltinValue enum → std.builtin type name.
+ static const char* const bv_names[] = {
+ "AtomicOrder", /* 0 atomic_order */
+ "AtomicRmwOp", /* 1 atomic_rmw_op */
+ "CallingConvention", /* 2 calling_convention */
+ "AddressSpace", /* 3 address_space */
+ "FloatMode", /* 4 float_mode */
+ "ReduceOp", /* 5 reduce_op */
+ "CallModifier", /* 6 call_modifier */
+ "PrefetchOptions", /* 7 prefetch_options */
+ "ExportOptions", /* 8 export_options */
+ "ExternOptions", /* 9 extern_options */
+ "Type", /* 10 type_info */
+ "BranchHint", /* 11 branch_hint */
+ };
+ if (bv_kind < 12 && sema->zcu->builtin_file_idx != UINT32_MAX) {
uint32_t builtin_ns
= sema->zcu->file_namespaces[sema->zcu->builtin_file_idx];
- uint32_t cc_nav
- = findNavInNamespace(sema, builtin_ns, "CallingConvention");
- if (cc_nav != UINT32_MAX) {
- InternPoolIndex cc_type
- = ipGetNav(sema->ip, cc_nav)->resolved_type;
- if (cc_type != IP_INDEX_NONE)
- return AIR_REF_FROM_IP(cc_type);
- }
- }
- if (bv_kind == ZIR_BUILTIN_VALUE_EXPORT_OPTIONS
- && sema->zcu->builtin_file_idx != UINT32_MAX) {
- uint32_t builtin_ns
- = sema->zcu->file_namespaces[sema->zcu->builtin_file_idx];
- uint32_t eo_nav
- = findNavInNamespace(sema, builtin_ns, "ExportOptions");
- if (eo_nav != UINT32_MAX) {
- InternPoolIndex eo_type
- = ipGetNav(sema->ip, eo_nav)->resolved_type;
- if (eo_type != IP_INDEX_NONE)
- return AIR_REF_FROM_IP(eo_type);
+ uint32_t nav
+ = findNavInNamespace(sema, builtin_ns, bv_names[bv_kind]);
+ if (nav != UINT32_MAX) {
+ InternPoolIndex ty = ipGetNav(sema->ip, nav)->resolved_type;
+ if (ty == IP_INDEX_NONE)
+ ty = ensureNavValUpToDate(sema, nav);
+ if (ty != IP_INDEX_NONE)
+ return AIR_REF_FROM_IP(ty);
}
}
UNIMPLEMENTED("zirExtended: builtin_value kind not found");
@@ -13329,6 +13389,29 @@ bool analyzeBodyInner(
continue;
}
+ // ptr_type: create pointer/slice type in comptime blocks.
+ // Ported from Sema.zig zirPtrType (simplified for comptime).
+ case ZIR_INST_PTR_TYPE: {
+ instMapPut(&sema->inst_map, inst, zirPtrType(sema, block, inst));
+ i++;
+ continue;
+ }
+
+ // optional_type: create optional type in comptime blocks.
+ // Ported from Sema.zig zirOptionalType.
+ case ZIR_INST_OPTIONAL_TYPE: {
+ ZirInstRef child_ref = sema->code.inst_datas[inst].un_node.operand;
+ AirInstRef child_air = resolveInst(sema, child_ref);
+ InternPoolKey key;
+ memset(&key, 0, sizeof(key));
+ key.tag = IP_KEY_OPT_TYPE;
+ key.data.opt_type = child_air;
+ instMapPut(&sema->inst_map, inst,
+ AIR_REF_FROM_IP(ipIntern(sema->ip, key)));
+ i++;
+ continue;
+ }
+
default:
fprintf(stderr, "UNIMPLEMENTED: %s:%d: ZIR instruction tag %d\n",
__FILE__, __LINE__, (int)inst_tag);