Commit 27fa4bc2be
Changed files (3)
src/AstGen.zig
@@ -1300,40 +1300,28 @@ pub fn structInitExpr(
}
return Zir.Inst.Ref.void_value;
},
- .none, .none_or_ref => {
+ .ref => {
if (struct_init.ast.type_expr != 0) {
const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
- return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst);
- }
- const fields_list = try gpa.alloc(Zir.Inst.StructInitAnon.Item, struct_init.ast.fields.len);
- defer gpa.free(fields_list);
-
- for (struct_init.ast.fields) |field_init, i| {
- const name_token = tree.firstToken(field_init) - 2;
- const str_index = try gz.identAsString(name_token);
-
- fields_list[i] = .{
- .field_name = str_index,
- .init = try expr(gz, scope, .none, field_init),
- };
+ return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst, .struct_init_ref);
+ } else {
+ return structInitExprRlNone(gz, scope, rl, node, struct_init, .struct_init_anon_ref);
}
- const init_inst = try gz.addPlNode(.struct_init_anon, node, Zir.Inst.StructInitAnon{
- .fields_len = @intCast(u32, fields_list.len),
- });
- try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +
- fields_list.len * @typeInfo(Zir.Inst.StructInitAnon.Item).Struct.fields.len);
- for (fields_list) |field| {
- _ = gz.astgen.addExtraAssumeCapacity(field);
+ },
+ .none, .none_or_ref => {
+ if (struct_init.ast.type_expr != 0) {
+ const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
+ return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst, .struct_init);
+ } else {
+ return structInitExprRlNone(gz, scope, rl, node, struct_init, .struct_init_anon);
}
- return init_inst;
},
- .ref => return astgen.failNode(node, "cannot take address of struct literal", .{}),
.ty => |ty_inst| {
if (struct_init.ast.type_expr == 0) {
- return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst);
+ return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst, .struct_init);
}
const inner_ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
- const result = try structInitExprRlTy(gz, scope, rl, node, struct_init, inner_ty_inst);
+ const result = try structInitExprRlTy(gz, scope, rl, node, struct_init, inner_ty_inst, .struct_init);
return rvalue(gz, scope, rl, result, node);
},
.ptr, .inferred_ptr => |ptr_inst| return structInitExprRlPtr(gz, scope, rl, node, struct_init, ptr_inst),
@@ -1341,6 +1329,41 @@ pub fn structInitExpr(
}
}
+pub fn structInitExprRlNone(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ node: ast.Node.Index,
+ struct_init: ast.full.StructInit,
+ tag: Zir.Inst.Tag,
+) InnerError!Zir.Inst.Ref {
+ const astgen = gz.astgen;
+ const gpa = astgen.gpa;
+ const tree = &astgen.file.tree;
+
+ const fields_list = try gpa.alloc(Zir.Inst.StructInitAnon.Item, struct_init.ast.fields.len);
+ defer gpa.free(fields_list);
+
+ for (struct_init.ast.fields) |field_init, i| {
+ const name_token = tree.firstToken(field_init) - 2;
+ const str_index = try gz.identAsString(name_token);
+
+ fields_list[i] = .{
+ .field_name = str_index,
+ .init = try expr(gz, scope, .none, field_init),
+ };
+ }
+ const init_inst = try gz.addPlNode(tag, node, Zir.Inst.StructInitAnon{
+ .fields_len = @intCast(u32, fields_list.len),
+ });
+ try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +
+ fields_list.len * @typeInfo(Zir.Inst.StructInitAnon.Item).Struct.fields.len);
+ for (fields_list) |field| {
+ _ = gz.astgen.addExtraAssumeCapacity(field);
+ }
+ return init_inst;
+}
+
pub fn structInitExprRlPtr(
gz: *GenZir,
scope: *Scope,
@@ -1380,6 +1403,7 @@ pub fn structInitExprRlTy(
node: ast.Node.Index,
struct_init: ast.full.StructInit,
ty_inst: Zir.Inst.Ref,
+ tag: Zir.Inst.Tag,
) InnerError!Zir.Inst.Ref {
const astgen = gz.astgen;
const gpa = astgen.gpa;
@@ -1401,7 +1425,7 @@ pub fn structInitExprRlTy(
.init = try expr(gz, scope, .{ .ty = field_ty_inst }, field_init),
};
}
- const init_inst = try gz.addPlNode(.struct_init, node, Zir.Inst.StructInit{
+ const init_inst = try gz.addPlNode(tag, node, Zir.Inst.StructInit{
.fields_len = @intCast(u32, fields_list.len),
});
try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +
@@ -1886,7 +1910,9 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner
.switch_capture_else_ref,
.struct_init_empty,
.struct_init,
+ .struct_init_ref,
.struct_init_anon,
+ .struct_init_anon_ref,
.array_init,
.array_init_anon,
.array_init_ref,
src/Sema.zig
@@ -256,11 +256,13 @@ pub fn analyzeBody(
.typeof_log2_int_type => try sema.zirTypeofLog2IntType(block, inst),
.xor => try sema.zirBitwise(block, inst, .xor),
.struct_init_empty => try sema.zirStructInitEmpty(block, inst),
- .struct_init => try sema.zirStructInit(block, inst),
- .struct_init_anon => try sema.zirStructInitAnon(block, inst),
+ .struct_init => try sema.zirStructInit(block, inst, false),
+ .struct_init_ref => try sema.zirStructInit(block, inst, true),
+ .struct_init_anon => try sema.zirStructInitAnon(block, inst, false),
+ .struct_init_anon_ref => try sema.zirStructInitAnon(block, inst, true),
.array_init => try sema.zirArrayInit(block, inst, false),
- .array_init_anon => try sema.zirArrayInitAnon(block, inst, false),
.array_init_ref => try sema.zirArrayInit(block, inst, true),
+ .array_init_anon => try sema.zirArrayInitAnon(block, inst, false),
.array_init_anon_ref => try sema.zirArrayInitAnon(block, inst, true),
.union_init_ptr => try sema.zirUnionInitPtr(block, inst),
.field_type => try sema.zirFieldType(block, inst),
@@ -5078,13 +5080,13 @@ fn zirUnionInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner
return sema.mod.fail(&block.base, src, "TODO: Sema.zirUnionInitPtr", .{});
}
-fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
+fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: bool) InnerError!*Inst {
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
const src = inst_data.src();
return sema.mod.fail(&block.base, src, "TODO: Sema.zirStructInit", .{});
}
-fn zirStructInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
+fn zirStructInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: bool) InnerError!*Inst {
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
const src = inst_data.src();
return sema.mod.fail(&block.base, src, "TODO: Sema.zirStructInitAnon", .{});
src/Zir.zig
@@ -660,9 +660,15 @@ pub const Inst = struct {
/// struct value.
/// Uses the `pl_node` field. Payload is `StructInit`.
struct_init,
+ /// Struct initialization syntax, make the result a pointer.
+ /// Uses the `pl_node` field. Payload is `StructInit`.
+ struct_init_ref,
/// Struct initialization without a type.
/// Uses the `pl_node` field. Payload is `StructInitAnon`.
struct_init_anon,
+ /// Anonymous struct initialization syntax, make the result a pointer.
+ /// Uses the `pl_node` field. Payload is `StructInitAnon`.
+ struct_init_anon_ref,
/// Array initialization syntax.
/// Uses the `pl_node` field. Payload is `MultiOp`.
array_init,
@@ -1093,7 +1099,9 @@ pub const Inst = struct {
.validate_array_init_ptr,
.struct_init_empty,
.struct_init,
+ .struct_init_ref,
.struct_init_anon,
+ .struct_init_anon_ref,
.array_init,
.array_init_anon,
.array_init_ref,
@@ -2442,7 +2450,9 @@ const Writer = struct {
.slice_end,
.slice_sentinel,
.struct_init,
+ .struct_init_ref,
.struct_init_anon,
+ .struct_init_anon_ref,
.array_init,
.array_init_anon,
.array_init_ref,