zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

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:
Mstage0/corpus.zig | 2+-
Mstage0/sema.c | 135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
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);