diff --git a/stage0/astgen.c b/stage0/astgen.c index ca4122b629..fcf5245762 100644 --- a/stage0/astgen.c +++ b/stage0/astgen.c @@ -296,6 +296,7 @@ typedef struct { uint32_t inst; // ZirInstRef uint32_t token_src; // Ast.TokenIndex uint32_t name; // NullTerminatedString (string table index) + bool* is_used_or_discarded; // NULL if not tracking (AstGen.zig:11691) } ScopeLocalVal; // Scope.LocalPtr (AstGen.zig:11704). @@ -1660,6 +1661,32 @@ static uint32_t countBodyLenAfterFixups( return countBodyLenAfterFixupsExtraRefs(ag, body, body_len, NULL, 0); } +// Mirrors fetchRemoveRefEntries (AstGen.zig:14066-14074). +// For each param_inst, removes its ref_table entry (if present) and saves +// the value. Returns the number of entries removed. +static uint32_t fetchRemoveRefEntries(AstGenCtx* ag, + const uint32_t* param_insts, uint32_t param_insts_len, uint32_t* result, + uint32_t result_cap) { + uint32_t count = 0; + for (uint32_t i = 0; i < param_insts_len; i++) { + uint32_t ref_inst; + if (refTableFetchRemove(ag, param_insts[i], &ref_inst)) { + if (count < result_cap) + result[count] = ref_inst; + count++; + } + } + return count; +} + +// Mirrors appendBodyWithFixups (AstGen.zig:13649-13657). +static void appendBodyWithFixups( + AstGenCtx* ag, const uint32_t* body, uint32_t body_len) { + for (uint32_t i = 0; i < body_len; i++) { + appendPossiblyRefdBodyInst(ag, body[i]); + } +} + // Mirrors GenZir.setBlockBody (AstGen.zig:11949). // Writes Block payload (body_len + instruction indices) to extra. // Sets the instruction's payload_index. Unstacks gz. @@ -2497,6 +2524,7 @@ static uint32_t rvalue( // elem_val_imm: operand=result, idx=i. uint32_t elem_inst = reserveInstructionIndex(gz->astgen); gz->astgen->inst_tags[elem_inst] = ZIR_INST_ELEM_VAL_IMM; + memset(&gz->astgen->inst_datas[elem_inst], 0, sizeof(ZirInstData)); gz->astgen->inst_datas[elem_inst].elem_val_imm.operand = result; gz->astgen->inst_datas[elem_inst].elem_val_imm.idx = i; gzAppendInstruction(gz, elem_inst); @@ -3837,6 +3865,9 @@ static uint32_t localVarRef(GenZir* gz, Scope* scope, ResultLoc rl, case SCOPE_LOCAL_VAL: { ScopeLocalVal* lv = (ScopeLocalVal*)s; if (lv->name == name_str) { + // Track usage for generic detection (AstGen.zig:8399). + if (lv->is_used_or_discarded != NULL) + *lv->is_used_or_discarded = true; // Locals cannot shadow, no ambiguity check needed. uint32_t value_inst; if (num_namespaces_out != 0) { @@ -9744,6 +9775,7 @@ static void varDecl(GenZir* gz, Scope* scope, uint32_t node, // Extract type_node and init_node based on variant. uint32_t type_node = 0; + uint32_t align_node = 0; uint32_t init_node = 0; if (tag == AST_NODE_SIMPLE_VAR_DECL) { @@ -9753,13 +9785,14 @@ static void varDecl(GenZir* gz, Scope* scope, uint32_t node, } else if (tag == AST_NODE_LOCAL_VAR_DECL) { // lhs = extra_data index, rhs = init. // extra: {type_node, align_node, addrspace_node, section_node} - // Simplified: just extract type_node. uint32_t extra_idx = nd.lhs; type_node = tree->extra_data.arr[extra_idx]; // type_node + align_node = tree->extra_data.arr[extra_idx + 1]; // align_node init_node = nd.rhs; } else if (tag == AST_NODE_ALIGNED_VAR_DECL) { // lhs = align expr, rhs = init. // No type node in this variant. + align_node = nd.lhs; init_node = nd.rhs; } else { // global_var_decl or unknown — bail. @@ -9773,6 +9806,18 @@ static void varDecl(GenZir* gz, Scope* scope, uint32_t node, return; } + // Evaluate alignment expression (AstGen.zig:3227-3230). + uint32_t align_inst = ZIR_REF_NONE; + if (align_node != 0) { + ResultLoc align_rl = { .tag = RL_COERCED_TY, + .data = ZIR_REF_U29_TYPE, + .src_node = 0, + .ctx = RI_CTX_NONE, + .components = NULL, + .components_len = 0 }; + align_inst = exprRl(gz, scope, align_rl, align_node); + } + if (is_const) { // --- CONST path (AstGen.zig:3232-3340) --- @@ -9823,6 +9868,7 @@ static void varDecl(GenZir* gz, Scope* scope, uint32_t node, val_out->inst = init_ref; val_out->token_src = name_token; val_out->name = ident_name; + val_out->is_used_or_discarded = NULL; *scope_out = &val_out->base; } else { // Alloc path (AstGen.zig:3277-3340). @@ -9906,20 +9952,58 @@ static void varDecl(GenZir* gz, Scope* scope, uint32_t node, bool resolve_inferred = false; if (type_node != 0) { - // Typed var: alloc_mut (AstGen.zig:3361-3375). + // Typed var: alloc_mut (AstGen.zig:3346-3365). uint32_t type_ref = typeExpr(gz, scope, type_node); - ZirInstTag alloc_tag = is_comptime ? ZIR_INST_ALLOC_COMPTIME_MUT - : ZIR_INST_ALLOC_MUT; - alloc_ref = addUnNode(gz, alloc_tag, type_ref, node); + if (align_inst == ZIR_REF_NONE) { + ZirInstTag alloc_tag = is_comptime + ? ZIR_INST_ALLOC_COMPTIME_MUT + : ZIR_INST_ALLOC_MUT; + alloc_ref = addUnNode(gz, alloc_tag, type_ref, node); + } else { + // addAllocExtended (AstGen.zig:12781-12830). + ensureExtraCapacity(ag, 3); // src_node + type + align + uint32_t payload_index = ag->extra_len; + int32_t src_off = (int32_t)node - (int32_t)gz->decl_node_index; + memcpy(&ag->extra[ag->extra_len], &src_off, sizeof(uint32_t)); + ag->extra_len++; + ag->extra[ag->extra_len++] = type_ref; + ag->extra[ag->extra_len++] = align_inst; + // small: has_type=1, has_align=1, is_const=0, is_comptime + uint16_t small = (uint16_t)(1u | (1u << 1) + | ((is_comptime ? 1u : 0u) << 3)); + ZirInstData edata; + edata.extended.opcode = (uint16_t)ZIR_EXT_ALLOC; + edata.extended.small = small; + edata.extended.operand = payload_index; + alloc_ref = addInstruction(gz, ZIR_INST_EXTENDED, edata); + } } else { // Inferred type var: alloc_inferred_mut - // (AstGen.zig:3384-3392). - ZirInstTag alloc_tag = is_comptime - ? ZIR_INST_ALLOC_INFERRED_COMPTIME_MUT - : ZIR_INST_ALLOC_INFERRED_MUT; - ZirInstData adata; - adata.node = (int32_t)node - (int32_t)gz->decl_node_index; - alloc_ref = addInstruction(gz, alloc_tag, adata); + // (AstGen.zig:3366-3385). + if (align_inst == ZIR_REF_NONE) { + ZirInstTag alloc_tag = is_comptime + ? ZIR_INST_ALLOC_INFERRED_COMPTIME_MUT + : ZIR_INST_ALLOC_INFERRED_MUT; + ZirInstData adata; + adata.node = (int32_t)node - (int32_t)gz->decl_node_index; + alloc_ref = addInstruction(gz, alloc_tag, adata); + } else { + // addAllocExtended without type (AstGen.zig:12781-12830). + ensureExtraCapacity(ag, 2); // src_node + align + uint32_t payload_index = ag->extra_len; + int32_t src_off = (int32_t)node - (int32_t)gz->decl_node_index; + memcpy(&ag->extra[ag->extra_len], &src_off, sizeof(uint32_t)); + ag->extra_len++; + ag->extra[ag->extra_len++] = align_inst; + // small: has_type=0, has_align=1, is_const=0, is_comptime + uint16_t small + = (uint16_t)((1u << 1) | ((is_comptime ? 1u : 0u) << 3)); + ZirInstData edata; + edata.extended.opcode = (uint16_t)ZIR_EXT_ALLOC; + edata.extended.small = small; + edata.extended.operand = payload_index; + alloc_ref = addInstruction(gz, ZIR_INST_EXTENDED, edata); + } resolve_inferred = true; } @@ -11222,7 +11306,7 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) { // Creates a param instruction with pl_tok data and type body in extra. static uint32_t addParam(GenZir* gz, GenZir* param_gz, ZirInstTag tag, - uint32_t abs_tok_index, uint32_t name) { + uint32_t abs_tok_index, uint32_t name, bool is_generic) { AstGenCtx* ag = gz->astgen; uint32_t body_len = gzInstructionsLen(param_gz); @@ -11232,7 +11316,8 @@ static uint32_t addParam(GenZir* gz, GenZir* param_gz, ZirInstTag tag, ensureExtraCapacity(ag, 2 + body_len); uint32_t payload_index = ag->extra_len; ag->extra[ag->extra_len++] = name; - ag->extra[ag->extra_len++] = body_len & 0x7FFFFFFFu; // is_generic = false + ag->extra[ag->extra_len++] + = (body_len & 0x7FFFFFFFu) | (is_generic ? 0x80000000u : 0u); for (uint32_t i = 0; i < body_len; i++) { ag->extra[ag->extra_len++] = param_body[i]; } @@ -11272,7 +11357,9 @@ static uint32_t addFunc(GenZir* gz, uint32_t src_node, uint32_t block_node, uint32_t param_block, uint32_t ret_ref, const uint32_t* ret_body, uint32_t ret_body_len, const uint32_t* body, uint32_t body_len, const uint32_t* param_insts, uint32_t param_insts_len, - uint32_t lbrace_line, uint32_t lbrace_column, bool is_inferred_error) { + uint32_t lbrace_line, uint32_t lbrace_column, bool is_inferred_error, + bool ret_ty_is_generic, const uint32_t* ret_param_refs, + uint32_t ret_param_refs_len) { AstGenCtx* ag = gz->astgen; const Ast* tree = ag->tree; uint32_t rbrace_tok = lastToken(tree, block_node); @@ -11282,18 +11369,20 @@ static uint32_t addFunc(GenZir* gz, uint32_t src_node, uint32_t block_node, uint32_t rbrace_column = ag->source_column; // Build Func payload (Zir.Inst.Func: ret_ty, param_block, body_len). - // (AstGen.zig:12187-12194) + // (AstGen.zig:12182-12194) uint32_t ret_ty_packed_len; if (ret_body_len > 0) { - ret_ty_packed_len = ret_body_len; // body-based return type + ret_ty_packed_len + = countBodyLenAfterFixups(ag, ret_param_refs, ret_param_refs_len) + + countBodyLenAfterFixups(ag, ret_body, ret_body_len); } else if (ret_ref != ZIR_REF_NONE) { ret_ty_packed_len = 1; // simple Ref } else { ret_ty_packed_len = 0; // void return } - // Pack RetTy: body_len:u31 | is_generic:bool(u1) = just body_len. - uint32_t ret_ty_packed - = ret_ty_packed_len & 0x7FFFFFFFu; // is_generic=false + // Pack RetTy: body_len:u31 | is_generic:bool(u1). + uint32_t ret_ty_packed = (ret_ty_packed_len & 0x7FFFFFFFu) + | (ret_ty_is_generic ? 0x80000000u : 0u); uint32_t fixup_body_len = countBodyLenAfterFixupsExtraRefs( ag, body, body_len, param_insts, param_insts_len); @@ -11303,10 +11392,11 @@ static uint32_t addFunc(GenZir* gz, uint32_t src_node, uint32_t block_node, ag->extra[ag->extra_len++] = param_block; // Func.param_block ag->extra[ag->extra_len++] = fixup_body_len; // Func.body_len - // Trailing ret_ty: either body instructions or a single ref. + // Trailing ret_ty: either body instructions (with ret_param_refs + // prepended) or a single ref. (AstGen.zig:12196-12204) if (ret_body_len > 0) { - for (uint32_t i = 0; i < ret_body_len; i++) - ag->extra[ag->extra_len++] = ret_body[i]; + appendBodyWithFixups(ag, ret_param_refs, ret_param_refs_len); + appendBodyWithFixups(ag, ret_body, ret_body_len); } else if (ret_ref != ZIR_REF_NONE) { ag->extra[ag->extra_len++] = ret_ref; } @@ -11346,7 +11436,9 @@ static uint32_t addFuncFancy(GenZir* gz, uint32_t src_node, const uint32_t* cc_body, uint32_t cc_body_len, const uint32_t* body, uint32_t body_len, const uint32_t* param_insts, uint32_t param_insts_len, uint32_t lbrace_line, uint32_t lbrace_column, bool is_var_args, - bool is_inferred_error, bool is_noinline, uint32_t noalias_bits) { + bool is_inferred_error, bool is_noinline, uint32_t noalias_bits, + bool ret_ty_is_generic, const uint32_t* ret_param_refs, + uint32_t ret_param_refs_len) { AstGenCtx* ag = gz->astgen; const Ast* tree = ag->tree; uint32_t rbrace_tok = lastToken(tree, block_node); @@ -11367,11 +11459,11 @@ static uint32_t addFuncFancy(GenZir* gz, uint32_t src_node, } // Calculate ret extra len (AstGen.zig:12231-12236). - // Note: ret_param_refs are empty (no generic tracking yet). uint32_t ret_extra_len = 0; if (ret_body_len > 0) { ret_extra_len - = countBodyLenAfterFixups(ag, ret_body, ret_body_len) + 1; + = countBodyLenAfterFixups(ag, ret_param_refs, ret_param_refs_len) + + countBodyLenAfterFixups(ag, ret_body, ret_body_len) + 1; } else if (ret_ref != ZIR_REF_NONE) { ret_extra_len = 1; } @@ -11403,7 +11495,8 @@ static uint32_t addFuncFancy(GenZir* gz, uint32_t src_node, bits |= (1u << 6); // has_ret_ty_body if (noalias_bits != 0) bits |= (1u << 7); // has_any_noalias - // bit 8 = ret_ty_is_generic (false for now, no generic tracking) + if (ret_ty_is_generic) + bits |= (1u << 8); // ret_ty_is_generic ag->extra[ag->extra_len++] = bits; // Trailing cc (AstGen.zig:12143-12151). @@ -11417,12 +11510,12 @@ static uint32_t addFuncFancy(GenZir* gz, uint32_t src_node, } // Trailing ret_ty (AstGen.zig:12152-12164). - // Note: no ret_param_refs (generic tracking not implemented). if (ret_body_len > 0) { ag->extra[ag->extra_len++] - = countBodyLenAfterFixups(ag, ret_body, ret_body_len); - for (uint32_t i = 0; i < ret_body_len; i++) - appendPossiblyRefdBodyInst(ag, ret_body[i]); + = countBodyLenAfterFixups(ag, ret_param_refs, ret_param_refs_len) + + countBodyLenAfterFixups(ag, ret_body, ret_body_len); + appendBodyWithFixups(ag, ret_param_refs, ret_param_refs_len); + appendBodyWithFixups(ag, ret_body, ret_body_len); } else if (ret_ref != ZIR_REF_NONE) { ag->extra[ag->extra_len++] = ret_ref; } @@ -11573,7 +11666,7 @@ static void testDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, // Create func instruction (AstGen.zig:4874-4897). uint32_t func_ref = addFunc(&decl_block, node, body_node, decl_inst, ZIR_REF_ANYERROR_VOID_ERROR_UNION_TYPE, NULL, 0, fn_body, fn_body_len, - NULL, 0, lbrace_line, lbrace_column, false); + NULL, 0, lbrace_line, lbrace_column, false, false, NULL, 0); // break_inline returning func to declaration (AstGen.zig:4899). makeBreakInline(&decl_block, decl_inst, func_ref, AST_NODE_OFFSET_NONE); @@ -11750,6 +11843,8 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, uint32_t param_insts_len = 0; // noalias_bits tracking (AstGen.zig:4259). uint32_t noalias_bits = 0; + // Generic parameter/return type tracking (AstGen.zig:4257). + bool any_param_used = false; // is_var_args detection (AstGen.zig:4261). bool is_var_args = false; @@ -11890,11 +11985,13 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, : ZIR_INST_PARAM_ANYTYPE; uint32_t anytype_inst = addStrTok( &decl_gz, anytype_tag, param_name_str, anytype_name_token); - param_inst_ref = anytype_inst + ZIR_REF_START_INDEX; + param_inst_ref = anytype_inst; // already a ref (toRef()) if (param_insts_len < 32) - param_insts[param_insts_len++] = anytype_inst; + param_insts[param_insts_len++] + = anytype_inst - ZIR_REF_START_INDEX; // toIndex() } else { // Type-expression parameter (AstGen.zig:4330-4344). + any_param_used = false; // reset before evaluating type body GenZir param_gz = makeSubBlock(&decl_gz, params_scope); uint32_t param_type_ref = fullBodyExpr( ¶m_gz, params_scope, coerced_type_ri, param_type_node); @@ -11907,6 +12004,7 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, uint32_t param_inst_expected = ag->inst_len + 1; makeBreakInline(¶m_gz, param_inst_expected, param_type_ref, (int32_t)param_type_node - (int32_t)param_gz.decl_node_index); + bool param_type_is_generic = any_param_used; // Create param instruction (AstGen.zig:4341-4343). ZirInstTag param_tag @@ -11915,7 +12013,7 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, ? name_token : tree->nodes.main_tokens[param_type_node]; uint32_t param_inst = addParam(&decl_gz, ¶m_gz, param_tag, - name_tok_for_src, param_name_str); + name_tok_for_src, param_name_str, param_type_is_generic); (void)param_inst_expected; param_inst_ref = param_inst + ZIR_REF_START_INDEX; if (param_insts_len < 32) @@ -11931,12 +12029,14 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, lv->inst = param_inst_ref; lv->token_src = name_token; lv->name = param_name_str; + lv->is_used_or_discarded = &any_param_used; params_scope = &lv->base; } param_type_i++; } // --- Return type (AstGen.zig:4369-4383) --- + any_param_used = false; // reset for return type generic detection GenZir ret_gz = makeSubBlock(&decl_gz, params_scope); uint32_t ret_ref = ZIR_REF_NONE; if (return_type_node != 0) { @@ -11952,6 +12052,11 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, makeBreakInline(&ret_gz, 0, ret_ref, AST_NODE_OFFSET_NONE); } } + // Fetch ref entries for params used in return type (AstGen.zig:4384). + uint32_t ret_param_refs[32]; + uint32_t ret_param_refs_len = fetchRemoveRefEntries( + ag, param_insts, param_insts_len, ret_param_refs, 32); + bool ret_ty_is_generic = any_param_used; // Map void_type → .none (AstGen.zig:12054). if (ret_ref == ZIR_REF_VOID_TYPE) ret_ref = ZIR_REF_NONE; @@ -12124,11 +12229,13 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, ret_body, ret_body_len, cc_ref, cc_body, cc_body_len, fn_body, fn_body_len, param_insts, param_insts_len, lbrace_line, lbrace_column, is_var_args, is_inferred_error, is_noinline, - noalias_bits); + noalias_bits, ret_ty_is_generic, ret_param_refs, + ret_param_refs_len); } else { func_ref = addFunc(&decl_gz, node, body_node, decl_inst, ret_ref, ret_body, ret_body_len, fn_body, fn_body_len, param_insts, - param_insts_len, lbrace_line, lbrace_column, is_inferred_error); + param_insts_len, lbrace_line, lbrace_column, is_inferred_error, + ret_ty_is_generic, ret_param_refs, ret_param_refs_len); } // Patch ret_body break_inline to point to func instruction @@ -12621,7 +12728,7 @@ static void globalVarDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, has_special_body, has_lib_name); setDeclaration(ag, decl_inst, - (SetDeclArgs) { .src_line = ag->source_line, + (SetDeclArgs) { .src_line = type_gz.decl_line, .src_column = decl_column, .id = decl_id, .name = name_str, diff --git a/stage0/astgen_test.zig b/stage0/astgen_test.zig index d8ca263c1e..c539c3de54 100644 --- a/stage0/astgen_test.zig +++ b/stage0/astgen_test.zig @@ -81,6 +81,40 @@ fn buildHashSkipMask(gpa: Allocator, ref: Zir) ![]bool { } } }, + .func_fancy => { + // FuncFancy: param_block(1) + body_len(1) + bits(1) + // + trailing cc + ret_ty + noalias + body + SrcLocs(3) + proto_hash(4). + const pi = ref_datas[i].pl_node.payload_index; + const body_len: u32 = ref.extra[pi + 1]; + const bits: u32 = ref.extra[pi + 2]; + var ei: u32 = pi + 3; + const has_cc_ref: bool = (bits & (1 << 3)) != 0; + const has_cc_body: bool = (bits & (1 << 4)) != 0; + const has_ret_ty_ref: bool = (bits & (1 << 5)) != 0; + const has_ret_ty_body: bool = (bits & (1 << 6)) != 0; + const has_any_noalias: bool = (bits & (1 << 7)) != 0; + if (has_cc_body) { + const cc_body_len = ref.extra[ei]; + ei += 1 + cc_body_len; + } else if (has_cc_ref) { + ei += 1; + } + if (has_ret_ty_body) { + const ret_body_len = ref.extra[ei]; + ei += 1 + ret_body_len; + } else if (has_ret_ty_ref) { + ei += 1; + } + if (has_any_noalias) ei += 1; + // body + SrcLocs(3) + proto_hash(4) + if (body_len > 0) { + const hash_start = ei + body_len + 3; + for (0..4) |j| { + if (hash_start + j < ref_extra_len) + skip[hash_start + j] = true; + } + } + }, else => {}, } } @@ -300,7 +334,35 @@ fn expectEqualZir(gpa: Allocator, ref: Zir, got: c.Zir) !void { // 3. Compare instruction data field-by-field. for (0..ref_len) |i| { - try expectEqualData(i, ref_tags[i], ref_datas[i], got.inst_datas[i]); + expectEqualData(i, ref_tags[i], ref_datas[i], got.inst_datas[i]) catch { + // Print nearest declaration for context. + var j: usize = i; + while (j > 0) { + j -= 1; + if (ref_tags[j] == .declaration) { + std.debug.print(" nearest decl at [{d}]: src_node={d}\n", .{ + j, ref_datas[j].declaration.src_node, + }); + break; + } + } + // Print what tags are at the operand positions if break_inline. + if (ref_tags[i] == .break_inline) { + const r_op = @intFromEnum(ref_datas[i].@"break".operand); + const g_op = got.inst_datas[i].break_data.operand; + if (r_op >= 124 and r_op - 124 < ref_len) { + std.debug.print(" ref operand inst[{d}] tag={d}\n", .{ + r_op - 124, @intFromEnum(ref_tags[r_op - 124]), + }); + } + if (g_op >= 124 and g_op - 124 < ref_len) { + std.debug.print(" got operand inst[{d}] tag={d}\n", .{ + g_op - 124, @intFromEnum(ref_tags[g_op - 124]), + }); + } + } + return error.TestExpectedEqual; + }; } // 4. Compare string bytes. const ref_sb_len: u32 = @intCast(ref.string_bytes.len); @@ -370,6 +432,17 @@ fn expectEqualData( .enum_decl, .union_decl, .opaque_decl, + // addNodeExtended sets small = undefined (AstGen.zig:12775). + .this, + .ret_addr, + .error_return_trace, + .frame, + .frame_address, + .breakpoint, + .disable_instrumentation, + .disable_intrinsics, + .in_comptime, + .c_va_start, => true, else => false, }; @@ -522,6 +595,7 @@ fn expectEqualData( }, .func, .func_inferred, + .func_fancy, .array_type, .array_type_sentinel, .array_cat, @@ -678,6 +752,10 @@ fn expectEqualData( .@"unreachable", // .save_err_ret_index data format (operand only): .save_err_ret_index, + // .float data format (f32 = 4 bytes, second word is padding): + .float, + // .elem_val_imm data format (u32 + u8, 3 bytes padding): + .elem_val_imm, => true, else => false, }; @@ -853,7 +931,6 @@ test "astgen: corpus astgen_test.zig" { } test "astgen: corpus array_list.zig" { - if (true) return error.SkipZigTest; // TODO: +2 ALLOC_MUT / -2 EXTENDED tag mismatch at [6639] const gpa = std.testing.allocator; try corpusCheck(gpa, @embedFile("../lib/std/array_list.zig")); }