diff --git a/astgen.c b/astgen.c index c8d5293ffb..997e6d4707 100644 --- a/astgen.c +++ b/astgen.c @@ -3047,7 +3047,43 @@ static uint32_t structInitExpr( } if (type_expr_node == 0 && fields_len > 0) { - // Anonymous struct init (AstGen.zig:1864). + // Anonymous struct init with RL type (AstGen.zig:1706-1731). + if (rl.tag == RL_TY || rl.tag == RL_COERCED_TY) { + uint32_t ty_inst = rl.data; + // validate_struct_init_result_ty (AstGen.zig:1710-1713). + ensureExtraCapacity(ag, 2); + uint32_t val_payload = ag->extra_len; + ag->extra[ag->extra_len++] = ty_inst; + ag->extra[ag->extra_len++] = fields_len; + addPlNodePayloadIndex(gz, + ZIR_INST_VALIDATE_STRUCT_INIT_RESULT_TY, node, val_payload); + // structInitExprTyped (AstGen.zig:1896-1931). + ensureExtraCapacity(ag, 3 + fields_len * 2); + uint32_t payload_index = ag->extra_len; + ag->extra[ag->extra_len++] = node; + ag->extra[ag->extra_len++] = ag->source_line; + ag->extra[ag->extra_len++] = fields_len; + uint32_t items_start = ag->extra_len; + ag->extra_len += fields_len * 2; + for (uint32_t i = 0; i < fields_len; i++) { + uint32_t field_init = fields[i]; + uint32_t name_token = firstToken(tree, field_init) - 2; + uint32_t str_index = identAsString(ag, name_token); + uint32_t field_ty_inst = addPlNodeBin(gz, + ZIR_INST_STRUCT_INIT_FIELD_TYPE, field_init, ty_inst, + str_index); + ResultLoc elem_rl = { .tag = RL_COERCED_TY, + .data = field_ty_inst, .src_node = 0 }; + uint32_t init_ref + = exprRl(gz, scope, elem_rl, field_init); + ag->extra[items_start + i * 2] + = field_ty_inst - ZIR_REF_START_INDEX; + ag->extra[items_start + i * 2 + 1] = init_ref; + } + return addPlNodePayloadIndex( + gz, ZIR_INST_STRUCT_INIT, node, payload_index); + } + // Anonymous struct init without RL type (AstGen.zig:1864). // StructInitAnon payload: abs_node, abs_line, fields_len. ensureExtraCapacity(ag, 3 + fields_len * 2); uint32_t payload_index = ag->extra_len; diff --git a/astgen_test.zig b/astgen_test.zig index d18d976798..6d845250a0 100644 --- a/astgen_test.zig +++ b/astgen_test.zig @@ -500,6 +500,7 @@ fn expectEqualData( .struct_init_ref, .validate_array_init_ref_ty, .validate_array_init_ty, + .validate_struct_init_result_ty, => { const r = ref.pl_node; const g = got.pl_node; @@ -818,6 +819,7 @@ fn dataMatches(tag: Zir.Inst.Tag, ref: Zir.Inst.Data, got: c.ZirInstData) bool { .struct_init_ref, .validate_array_init_ref_ty, .validate_array_init_ty, + .validate_struct_init_result_ty, => { return @intFromEnum(ref.pl_node.src_node) == got.pl_node.src_node and ref.pl_node.payload_index == got.pl_node.payload_index; @@ -988,7 +990,7 @@ test "astgen: corpus test_all.zig" { } test "astgen: corpus build.zig" { - if (true) return error.SkipZigTest; // TODO: 25 inst diff, struct init result_ty + if (true) return error.SkipZigTest; // TODO: 3 inst diff (as_node coercion) const gpa = std.testing.allocator; try corpusCheck(gpa, "build.zig", @embedFile("build.zig")); }