authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-11 16:20:32-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-11 16:25:21-07:00
log29c9d5896c0f3349b37eff4cbce280fffa7e2924
tree82aebe8095bc7dcafc6cca525b14ab82c5382278
parent5cc2e500e68a60cb99b48755af39856ff60198b6
parentbace1181b2f6d63e51b6e511aa8318481e2eafee

Merge branch 'Stage2 begin implementing container types'


9 files changed, 647 insertions(+), 11 deletions(-)

src/Module.zig+48-6
...@@ -460,7 +460,7 @@ pub const Scope = struct {...@@ -460,7 +460,7 @@ pub const Scope = struct {
460 };460 };
461 }461 }
462462
463 /// Asserts the scope has a parent which is a ZIRModule, Contaienr or File and463 /// Asserts the scope has a parent which is a ZIRModule, Container or File and
464 /// returns the sub_file_path field.464 /// returns the sub_file_path field.
465 pub fn subFilePath(base: *Scope) []const u8 {465 pub fn subFilePath(base: *Scope) []const u8 {
466 switch (base.tag) {466 switch (base.tag) {
...@@ -501,12 +501,12 @@ pub const Scope = struct {...@@ -501,12 +501,12 @@ pub const Scope = struct {
501 }501 }
502 }502 }
503503
504 pub fn getOwnerPkg(base: *Scope) *Package {504 pub fn getFileScope(base: *Scope) *Scope.File {
505 var cur = base;505 var cur = base;
506 while (true) {506 while (true) {
507 cur = switch (cur.tag) {507 cur = switch (cur.tag) {
508 .container => return @fieldParentPtr(Container, "base", cur).file_scope.pkg,508 .container => return @fieldParentPtr(Container, "base", cur).file_scope,
509 .file => return @fieldParentPtr(File, "base", cur).pkg,509 .file => return @fieldParentPtr(File, "base", cur),
510 .zir_module => unreachable, // TODO are zir modules allowed to import packages?510 .zir_module => unreachable, // TODO are zir modules allowed to import packages?
511 .gen_zir => @fieldParentPtr(GenZIR, "base", cur).parent,511 .gen_zir => @fieldParentPtr(GenZIR, "base", cur).parent,
512 .local_val => @fieldParentPtr(LocalVal, "base", cur).parent,512 .local_val => @fieldParentPtr(LocalVal, "base", cur).parent,
...@@ -582,7 +582,7 @@ pub const Scope = struct {...@@ -582,7 +582,7 @@ pub const Scope = struct {
582 file_scope: *Scope.File,582 file_scope: *Scope.File,
583583
584 /// Direct children of the file.584 /// Direct children of the file.
585 decls: std.AutoArrayHashMapUnmanaged(*Decl, void),585 decls: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{},
586 ty: Type,586 ty: Type,
587587
588 pub fn deinit(self: *Container, gpa: *Allocator) void {588 pub fn deinit(self: *Container, gpa: *Allocator) void {
...@@ -2464,6 +2464,48 @@ pub fn createAnonymousDecl(...@@ -2464,6 +2464,48 @@ pub fn createAnonymousDecl(
2464 return new_decl;2464 return new_decl;
2465}2465}
24662466
2467pub fn createContainerDecl(
2468 self: *Module,
2469 scope: *Scope,
2470 base_token: std.zig.ast.TokenIndex,
2471 decl_arena: *std.heap.ArenaAllocator,
2472 typed_value: TypedValue,
2473) !*Decl {
2474 const scope_decl = scope.decl().?;
2475 const name = try self.getAnonTypeName(scope, base_token);
2476 defer self.gpa.free(name);
2477 const name_hash = scope.namespace().fullyQualifiedNameHash(name);
2478 const src_hash: std.zig.SrcHash = undefined;
2479 const new_decl = try self.createNewDecl(scope, name, scope_decl.src_index, name_hash, src_hash);
2480 const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State);
2481
2482 decl_arena_state.* = decl_arena.state;
2483 new_decl.typed_value = .{
2484 .most_recent = .{
2485 .typed_value = typed_value,
2486 .arena = decl_arena_state,
2487 },
2488 };
2489 new_decl.analysis = .complete;
2490 new_decl.generation = self.generation;
2491
2492 return new_decl;
2493}
2494
2495fn getAnonTypeName(self: *Module, scope: *Scope, base_token: std.zig.ast.TokenIndex) ![]u8 {
2496 // TODO add namespaces, generic function signatrues
2497 const tree = scope.tree();
2498 const base_name = switch (tree.token_ids[base_token]) {
2499 .Keyword_struct => "struct",
2500 .Keyword_enum => "enum",
2501 .Keyword_union => "union",
2502 .Keyword_opaque => "opaque",
2503 else => unreachable,
2504 };
2505 const loc = tree.tokenLocationLoc(0, tree.token_locs[base_token]);
2506 return std.fmt.allocPrint(self.gpa, "{}:{}:{}", .{ base_name, loc.line, loc.column });
2507}
2508
2467fn getNextAnonNameIndex(self: *Module) usize {2509fn getNextAnonNameIndex(self: *Module) usize {
2468 return @atomicRmw(usize, &self.next_anon_name_index, .Add, 1, .Monotonic);2510 return @atomicRmw(usize, &self.next_anon_name_index, .Add, 1, .Monotonic);
2469}2511}
...@@ -2645,7 +2687,7 @@ pub fn analyzeSlice(self: *Module, scope: *Scope, src: usize, array_ptr: *Inst,...@@ -2645,7 +2687,7 @@ pub fn analyzeSlice(self: *Module, scope: *Scope, src: usize, array_ptr: *Inst,
2645}2687}
26462688
2647pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: []const u8) !*Scope.File {2689pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: []const u8) !*Scope.File {
2648 const cur_pkg = scope.getOwnerPkg();2690 const cur_pkg = scope.getFileScope().pkg;
2649 const cur_pkg_dir_path = cur_pkg.root_src_directory.path orelse ".";2691 const cur_pkg_dir_path = cur_pkg.root_src_directory.path orelse ".";
2650 const found_pkg = cur_pkg.table.get(target_string);2692 const found_pkg = cur_pkg.table.get(target_string);
26512693
src/astgen.zig+176-1
...@@ -282,6 +282,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr...@@ -282,6 +282,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
282 .Comptime => return comptimeKeyword(mod, scope, rl, node.castTag(.Comptime).?),282 .Comptime => return comptimeKeyword(mod, scope, rl, node.castTag(.Comptime).?),
283 .OrElse => return orelseExpr(mod, scope, rl, node.castTag(.OrElse).?),283 .OrElse => return orelseExpr(mod, scope, rl, node.castTag(.OrElse).?),
284 .Switch => return switchExpr(mod, scope, rl, node.castTag(.Switch).?),284 .Switch => return switchExpr(mod, scope, rl, node.castTag(.Switch).?),
285 .ContainerDecl => return containerDecl(mod, scope, rl, node.castTag(.ContainerDecl).?),
285286
286 .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}),287 .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}),
287 .Await => return mod.failNode(scope, node, "TODO implement astgen.expr for .Await", .{}),288 .Await => return mod.failNode(scope, node, "TODO implement astgen.expr for .Await", .{}),
...@@ -294,7 +295,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr...@@ -294,7 +295,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
294 .Suspend => return mod.failNode(scope, node, "TODO implement astgen.expr for .Suspend", .{}),295 .Suspend => return mod.failNode(scope, node, "TODO implement astgen.expr for .Suspend", .{}),
295 .AnyType => return mod.failNode(scope, node, "TODO implement astgen.expr for .AnyType", .{}),296 .AnyType => return mod.failNode(scope, node, "TODO implement astgen.expr for .AnyType", .{}),
296 .FnProto => return mod.failNode(scope, node, "TODO implement astgen.expr for .FnProto", .{}),297 .FnProto => return mod.failNode(scope, node, "TODO implement astgen.expr for .FnProto", .{}),
297 .ContainerDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ContainerDecl", .{}),
298 .Nosuspend => return mod.failNode(scope, node, "TODO implement astgen.expr for .Nosuspend", .{}),298 .Nosuspend => return mod.failNode(scope, node, "TODO implement astgen.expr for .Nosuspend", .{}),
299 }299 }
300}300}
...@@ -856,6 +856,181 @@ fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Si...@@ -856,6 +856,181 @@ fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Si
856 return rlWrapPtr(mod, scope, rl, try addZIRUnOp(mod, scope, src, .unwrap_optional_safe, operand));856 return rlWrapPtr(mod, scope, rl, try addZIRUnOp(mod, scope, src, .unwrap_optional_safe, operand));
857}857}
858858
859fn containerField(
860 mod: *Module,
861 scope: *Scope,
862 node: *ast.Node.ContainerField,
863) InnerError!*zir.Inst {
864 const tree = scope.tree();
865 const src = tree.token_locs[node.firstToken()].start;
866 const name = try mod.identifierTokenString(scope, node.name_token);
867
868 if (node.comptime_token == null and node.value_expr == null and node.align_expr == null) {
869 if (node.type_expr) |some| {
870 const ty = try typeExpr(mod, scope, some);
871 return addZIRInst(mod, scope, src, zir.Inst.ContainerFieldTyped, .{
872 .bytes = name,
873 .ty = ty,
874 }, .{});
875 } else {
876 return addZIRInst(mod, scope, src, zir.Inst.ContainerFieldNamed, .{
877 .bytes = name,
878 }, .{});
879 }
880 }
881
882 const ty = if (node.type_expr) |some| try typeExpr(mod, scope, some) else null;
883 const alignment = if (node.align_expr) |some| try expr(mod, scope, .none, some) else null;
884 const init = if (node.value_expr) |some| try expr(mod, scope, .none, some) else null;
885
886 return addZIRInst(mod, scope, src, zir.Inst.ContainerField, .{
887 .bytes = name,
888 }, .{
889 .ty = ty,
890 .init = init,
891 .alignment = alignment,
892 .is_comptime = node.comptime_token != null,
893 });
894}
895
896fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.ContainerDecl) InnerError!*zir.Inst {
897 const tree = scope.tree();
898 const src = tree.token_locs[node.kind_token].start;
899
900 var gen_scope: Scope.GenZIR = .{
901 .parent = scope,
902 .decl = scope.decl().?,
903 .arena = scope.arena(),
904 .instructions = .{},
905 };
906 defer gen_scope.instructions.deinit(mod.gpa);
907
908 var fields = std.ArrayList(*zir.Inst).init(mod.gpa);
909 defer fields.deinit();
910
911 for (node.fieldsAndDecls()) |fd| {
912 if (fd.castTag(.ContainerField)) |f| {
913 try fields.append(try containerField(mod, &gen_scope.base, f));
914 }
915 }
916
917 var decl_arena = std.heap.ArenaAllocator.init(mod.gpa);
918 errdefer decl_arena.deinit();
919 const arena = &decl_arena.allocator;
920
921 var layout: std.builtin.TypeInfo.ContainerLayout = .Auto;
922 if (node.layout_token) |some| switch (tree.token_ids[some]) {
923 .Keyword_extern => layout = .Extern,
924 .Keyword_packed => layout = .Packed,
925 else => unreachable,
926 };
927
928 const container_type = switch (tree.token_ids[node.kind_token]) {
929 .Keyword_enum => blk: {
930 const tag_type: ?*zir.Inst = switch (node.init_arg_expr) {
931 .Type => |t| try typeExpr(mod, &gen_scope.base, t),
932 .None => null,
933 .Enum => unreachable,
934 };
935 const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.EnumType, .{
936 .fields = try arena.dupe(*zir.Inst, fields.items),
937 }, .{
938 .layout = layout,
939 .tag_type = tag_type,
940 });
941 const enum_type = try arena.create(Type.Payload.Enum);
942 enum_type.* = .{
943 .analysis = .{
944 .queued = .{
945 .body = .{ .instructions = try arena.dupe(*zir.Inst, gen_scope.instructions.items) },
946 .inst = inst,
947 },
948 },
949 .scope = .{
950 .file_scope = scope.getFileScope(),
951 .ty = Type.initPayload(&enum_type.base),
952 },
953 };
954 break :blk Type.initPayload(&enum_type.base);
955 },
956 .Keyword_struct => blk: {
957 assert(node.init_arg_expr == .None);
958 const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.StructType, .{
959 .fields = try arena.dupe(*zir.Inst, fields.items),
960 }, .{
961 .layout = layout,
962 });
963 const struct_type = try arena.create(Type.Payload.Struct);
964 struct_type.* = .{
965 .analysis = .{
966 .queued = .{
967 .body = .{ .instructions = try arena.dupe(*zir.Inst, gen_scope.instructions.items) },
968 .inst = inst,
969 },
970 },
971 .scope = .{
972 .file_scope = scope.getFileScope(),
973 .ty = Type.initPayload(&struct_type.base),
974 },
975 };
976 break :blk Type.initPayload(&struct_type.base);
977 },
978 .Keyword_union => blk: {
979 const init_inst = switch (node.init_arg_expr) {
980 .Enum => |e| if (e) |t| try typeExpr(mod, &gen_scope.base, t) else null,
981 .None => null,
982 .Type => |t| try typeExpr(mod, &gen_scope.base, t),
983 };
984 const init_kind: zir.Inst.UnionType.InitKind = switch (node.init_arg_expr) {
985 .Enum => .enum_type,
986 .None => .none,
987 .Type => .tag_type,
988 };
989 const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.UnionType, .{
990 .fields = try arena.dupe(*zir.Inst, fields.items),
991 }, .{
992 .layout = layout,
993 .init_kind = init_kind,
994 .init_inst = init_inst,
995 });
996 const union_type = try arena.create(Type.Payload.Union);
997 union_type.* = .{
998 .analysis = .{
999 .queued = .{
1000 .body = .{ .instructions = try arena.dupe(*zir.Inst, gen_scope.instructions.items) },
1001 .inst = inst,
1002 },
1003 },
1004 .scope = .{
1005 .file_scope = scope.getFileScope(),
1006 .ty = Type.initPayload(&union_type.base),
1007 },
1008 };
1009 break :blk Type.initPayload(&union_type.base);
1010 },
1011 .Keyword_opaque => blk: {
1012 if (fields.items.len > 0) {
1013 return mod.fail(scope, fields.items[0].src, "opaque types cannot have fields", .{});
1014 }
1015 const opaque_type = try arena.create(Type.Payload.Opaque);
1016 opaque_type.* = .{
1017 .scope = .{
1018 .file_scope = scope.getFileScope(),
1019 .ty = Type.initPayload(&opaque_type.base),
1020 },
1021 };
1022 break :blk Type.initPayload(&opaque_type.base);
1023 },
1024 else => unreachable,
1025 };
1026 const val = try Value.Tag.ty.create(arena, container_type);
1027 const decl = try mod.createContainerDecl(scope, node.kind_token, &decl_arena, .{
1028 .ty = Type.initTag(.type),
1029 .val = val,
1030 });
1031 return rlWrapPtr(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.DeclValInModule, .{ .decl = decl }, .{}));
1032}
1033
859fn errorSetDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.ErrorSetDecl) InnerError!*zir.Inst {1034fn errorSetDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.ErrorSetDecl) InnerError!*zir.Inst {
860 const tree = scope.tree();1035 const tree = scope.tree();
861 const src = tree.token_locs[node.error_token].start;1036 const src = tree.token_locs[node.error_token].start;
src/type.zig+140-2
...@@ -49,7 +49,7 @@ pub const Type = extern union {...@@ -49,7 +49,7 @@ pub const Type = extern union {
49 .c_longdouble,49 .c_longdouble,
50 => return .Float,50 => return .Float,
5151
52 .c_void => return .Opaque,52 .c_void, .@"opaque" => return .Opaque,
53 .bool => return .Bool,53 .bool => return .Bool,
54 .void => return .Void,54 .void => return .Void,
55 .type => return .Type,55 .type => return .Type,
...@@ -92,7 +92,9 @@ pub const Type = extern union {...@@ -92,7 +92,9 @@ pub const Type = extern union {
9292
93 .anyframe_T, .@"anyframe" => return .AnyFrame,93 .anyframe_T, .@"anyframe" => return .AnyFrame,
9494
95 .empty_struct => return .Struct,95 .@"struct", .empty_struct => return .Struct,
96 .@"enum" => return .Enum,
97 .@"union" => return .Union,
96 }98 }
97 }99 }
98100
...@@ -470,6 +472,11 @@ pub const Type = extern union {...@@ -470,6 +472,11 @@ pub const Type = extern union {
470 .error_set => return self.copyPayloadShallow(allocator, Payload.Decl),472 .error_set => return self.copyPayloadShallow(allocator, Payload.Decl),
471 .error_set_single => return self.copyPayloadShallow(allocator, Payload.Name),473 .error_set_single => return self.copyPayloadShallow(allocator, Payload.Name),
472 .empty_struct => return self.copyPayloadShallow(allocator, Payload.ContainerScope),474 .empty_struct => return self.copyPayloadShallow(allocator, Payload.ContainerScope),
475
476 .@"enum" => return self.copyPayloadShallow(allocator, Payload.Enum),
477 .@"struct" => return self.copyPayloadShallow(allocator, Payload.Struct),
478 .@"union" => return self.copyPayloadShallow(allocator, Payload.Union),
479 .@"opaque" => return self.copyPayloadShallow(allocator, Payload.Opaque),
473 }480 }
474 }481 }
475482
...@@ -695,6 +702,11 @@ pub const Type = extern union {...@@ -695,6 +702,11 @@ pub const Type = extern union {
695 },702 },
696 .inferred_alloc_const => return out_stream.writeAll("(inferred_alloc_const)"),703 .inferred_alloc_const => return out_stream.writeAll("(inferred_alloc_const)"),
697 .inferred_alloc_mut => return out_stream.writeAll("(inferred_alloc_mut)"),704 .inferred_alloc_mut => return out_stream.writeAll("(inferred_alloc_mut)"),
705 // TODO use declaration name
706 .@"enum" => return out_stream.writeAll("enum {}"),
707 .@"struct" => return out_stream.writeAll("struct {}"),
708 .@"union" => return out_stream.writeAll("union {}"),
709 .@"opaque" => return out_stream.writeAll("opaque {}"),
698 }710 }
699 unreachable;711 unreachable;
700 }712 }
...@@ -803,6 +815,10 @@ pub const Type = extern union {...@@ -803,6 +815,10 @@ pub const Type = extern union {
803 return payload.error_set.hasCodeGenBits() or payload.payload.hasCodeGenBits();815 return payload.error_set.hasCodeGenBits() or payload.payload.hasCodeGenBits();
804 },816 },
805817
818 .@"enum" => @panic("TODO"),
819 .@"struct" => @panic("TODO"),
820 .@"union" => @panic("TODO"),
821
806 .c_void,822 .c_void,
807 .void,823 .void,
808 .type,824 .type,
...@@ -813,6 +829,7 @@ pub const Type = extern union {...@@ -813,6 +829,7 @@ pub const Type = extern union {
813 .@"undefined",829 .@"undefined",
814 .enum_literal,830 .enum_literal,
815 .empty_struct,831 .empty_struct,
832 .@"opaque",
816 => false,833 => false,
817834
818 .inferred_alloc_const => unreachable,835 .inferred_alloc_const => unreachable,
...@@ -924,6 +941,10 @@ pub const Type = extern union {...@@ -924,6 +941,10 @@ pub const Type = extern union {
924 @panic("TODO abiAlignment error union");941 @panic("TODO abiAlignment error union");
925 },942 },
926943
944 .@"enum" => self.cast(Payload.Enum).?.abiAlignment(target),
945 .@"struct" => @panic("TODO"),
946 .@"union" => @panic("TODO"),
947
927 .c_void,948 .c_void,
928 .void,949 .void,
929 .type,950 .type,
...@@ -936,6 +957,7 @@ pub const Type = extern union {...@@ -936,6 +957,7 @@ pub const Type = extern union {
936 .empty_struct,957 .empty_struct,
937 .inferred_alloc_const,958 .inferred_alloc_const,
938 .inferred_alloc_mut,959 .inferred_alloc_mut,
960 .@"opaque",
939 => unreachable,961 => unreachable,
940 };962 };
941 }963 }
...@@ -961,6 +983,7 @@ pub const Type = extern union {...@@ -961,6 +983,7 @@ pub const Type = extern union {
961 .empty_struct => unreachable,983 .empty_struct => unreachable,
962 .inferred_alloc_const => unreachable,984 .inferred_alloc_const => unreachable,
963 .inferred_alloc_mut => unreachable,985 .inferred_alloc_mut => unreachable,
986 .@"opaque" => unreachable,
964987
965 .u8,988 .u8,
966 .i8,989 .i8,
...@@ -1067,6 +1090,10 @@ pub const Type = extern union {...@@ -1067,6 +1090,10 @@ pub const Type = extern union {
1067 }1090 }
1068 @panic("TODO abiSize error union");1091 @panic("TODO abiSize error union");
1069 },1092 },
1093
1094 .@"enum" => @panic("TODO"),
1095 .@"struct" => @panic("TODO"),
1096 .@"union" => @panic("TODO"),
1070 };1097 };
1071 }1098 }
10721099
...@@ -1134,6 +1161,10 @@ pub const Type = extern union {...@@ -1134,6 +1161,10 @@ pub const Type = extern union {
1134 .error_set,1161 .error_set,
1135 .error_set_single,1162 .error_set_single,
1136 .empty_struct,1163 .empty_struct,
1164 .@"enum",
1165 .@"struct",
1166 .@"union",
1167 .@"opaque",
1137 => false,1168 => false,
11381169
1139 .single_const_pointer,1170 .single_const_pointer,
...@@ -1205,6 +1236,10 @@ pub const Type = extern union {...@@ -1205,6 +1236,10 @@ pub const Type = extern union {
1205 .error_set,1236 .error_set,
1206 .error_set_single,1237 .error_set_single,
1207 .empty_struct,1238 .empty_struct,
1239 .@"enum",
1240 .@"struct",
1241 .@"union",
1242 .@"opaque",
1208 => unreachable,1243 => unreachable,
12091244
1210 .const_slice,1245 .const_slice,
...@@ -1297,6 +1332,10 @@ pub const Type = extern union {...@@ -1297,6 +1332,10 @@ pub const Type = extern union {
1297 .empty_struct,1332 .empty_struct,
1298 .inferred_alloc_const,1333 .inferred_alloc_const,
1299 .inferred_alloc_mut,1334 .inferred_alloc_mut,
1335 .@"enum",
1336 .@"struct",
1337 .@"union",
1338 .@"opaque",
1300 => false,1339 => false,
13011340
1302 .const_slice,1341 .const_slice,
...@@ -1371,6 +1410,10 @@ pub const Type = extern union {...@@ -1371,6 +1410,10 @@ pub const Type = extern union {
1371 .empty_struct,1410 .empty_struct,
1372 .inferred_alloc_const,1411 .inferred_alloc_const,
1373 .inferred_alloc_mut,1412 .inferred_alloc_mut,
1413 .@"enum",
1414 .@"struct",
1415 .@"union",
1416 .@"opaque",
1374 => false,1417 => false,
13751418
1376 .single_const_pointer,1419 .single_const_pointer,
...@@ -1454,6 +1497,10 @@ pub const Type = extern union {...@@ -1454,6 +1497,10 @@ pub const Type = extern union {
1454 .empty_struct,1497 .empty_struct,
1455 .inferred_alloc_const,1498 .inferred_alloc_const,
1456 .inferred_alloc_mut,1499 .inferred_alloc_mut,
1500 .@"enum",
1501 .@"struct",
1502 .@"union",
1503 .@"opaque",
1457 => false,1504 => false,
14581505
1459 .pointer => {1506 .pointer => {
...@@ -1532,6 +1579,10 @@ pub const Type = extern union {...@@ -1532,6 +1579,10 @@ pub const Type = extern union {
1532 .empty_struct,1579 .empty_struct,
1533 .inferred_alloc_const,1580 .inferred_alloc_const,
1534 .inferred_alloc_mut,1581 .inferred_alloc_mut,
1582 .@"enum",
1583 .@"struct",
1584 .@"union",
1585 .@"opaque",
1535 => false,1586 => false,
15361587
1537 .pointer => {1588 .pointer => {
...@@ -1652,6 +1703,10 @@ pub const Type = extern union {...@@ -1652,6 +1703,10 @@ pub const Type = extern union {
1652 .empty_struct => unreachable,1703 .empty_struct => unreachable,
1653 .inferred_alloc_const => unreachable,1704 .inferred_alloc_const => unreachable,
1654 .inferred_alloc_mut => unreachable,1705 .inferred_alloc_mut => unreachable,
1706 .@"enum" => unreachable,
1707 .@"struct" => unreachable,
1708 .@"union" => unreachable,
1709 .@"opaque" => unreachable,
16551710
1656 .array => self.castTag(.array).?.data.elem_type,1711 .array => self.castTag(.array).?.data.elem_type,
1657 .array_sentinel => self.castTag(.array_sentinel).?.data.elem_type,1712 .array_sentinel => self.castTag(.array_sentinel).?.data.elem_type,
...@@ -1775,6 +1830,10 @@ pub const Type = extern union {...@@ -1775,6 +1830,10 @@ pub const Type = extern union {
1775 .empty_struct,1830 .empty_struct,
1776 .inferred_alloc_const,1831 .inferred_alloc_const,
1777 .inferred_alloc_mut,1832 .inferred_alloc_mut,
1833 .@"enum",
1834 .@"struct",
1835 .@"union",
1836 .@"opaque",
1778 => unreachable,1837 => unreachable,
17791838
1780 .array => self.castTag(.array).?.data.len,1839 .array => self.castTag(.array).?.data.len,
...@@ -1843,6 +1902,10 @@ pub const Type = extern union {...@@ -1843,6 +1902,10 @@ pub const Type = extern union {
1843 .empty_struct,1902 .empty_struct,
1844 .inferred_alloc_const,1903 .inferred_alloc_const,
1845 .inferred_alloc_mut,1904 .inferred_alloc_mut,
1905 .@"enum",
1906 .@"struct",
1907 .@"union",
1908 .@"opaque",
1846 => unreachable,1909 => unreachable,
18471910
1848 .single_const_pointer,1911 .single_const_pointer,
...@@ -1928,6 +1991,10 @@ pub const Type = extern union {...@@ -1928,6 +1991,10 @@ pub const Type = extern union {
1928 .empty_struct,1991 .empty_struct,
1929 .inferred_alloc_const,1992 .inferred_alloc_const,
1930 .inferred_alloc_mut,1993 .inferred_alloc_mut,
1994 .@"enum",
1995 .@"struct",
1996 .@"union",
1997 .@"opaque",
1931 => false,1998 => false,
19321999
1933 .int_signed,2000 .int_signed,
...@@ -2005,6 +2072,10 @@ pub const Type = extern union {...@@ -2005,6 +2072,10 @@ pub const Type = extern union {
2005 .empty_struct,2072 .empty_struct,
2006 .inferred_alloc_const,2073 .inferred_alloc_const,
2007 .inferred_alloc_mut,2074 .inferred_alloc_mut,
2075 .@"enum",
2076 .@"struct",
2077 .@"union",
2078 .@"opaque",
2008 => false,2079 => false,
20092080
2010 .int_unsigned,2081 .int_unsigned,
...@@ -2072,6 +2143,10 @@ pub const Type = extern union {...@@ -2072,6 +2143,10 @@ pub const Type = extern union {
2072 .empty_struct,2143 .empty_struct,
2073 .inferred_alloc_const,2144 .inferred_alloc_const,
2074 .inferred_alloc_mut,2145 .inferred_alloc_mut,
2146 .@"enum",
2147 .@"struct",
2148 .@"union",
2149 .@"opaque",
2075 => unreachable,2150 => unreachable,
20762151
2077 .int_unsigned => .{2152 .int_unsigned => .{
...@@ -2163,6 +2238,10 @@ pub const Type = extern union {...@@ -2163,6 +2238,10 @@ pub const Type = extern union {
2163 .empty_struct,2238 .empty_struct,
2164 .inferred_alloc_const,2239 .inferred_alloc_const,
2165 .inferred_alloc_mut,2240 .inferred_alloc_mut,
2241 .@"enum",
2242 .@"struct",
2243 .@"union",
2244 .@"opaque",
2166 => false,2245 => false,
21672246
2168 .usize,2247 .usize,
...@@ -2277,6 +2356,10 @@ pub const Type = extern union {...@@ -2277,6 +2356,10 @@ pub const Type = extern union {
2277 .empty_struct,2356 .empty_struct,
2278 .inferred_alloc_const,2357 .inferred_alloc_const,
2279 .inferred_alloc_mut,2358 .inferred_alloc_mut,
2359 .@"enum",
2360 .@"struct",
2361 .@"union",
2362 .@"opaque",
2280 => unreachable,2363 => unreachable,
2281 };2364 };
2282 }2365 }
...@@ -2357,6 +2440,10 @@ pub const Type = extern union {...@@ -2357,6 +2440,10 @@ pub const Type = extern union {
2357 .empty_struct,2440 .empty_struct,
2358 .inferred_alloc_const,2441 .inferred_alloc_const,
2359 .inferred_alloc_mut,2442 .inferred_alloc_mut,
2443 .@"enum",
2444 .@"struct",
2445 .@"union",
2446 .@"opaque",
2360 => unreachable,2447 => unreachable,
2361 }2448 }
2362 }2449 }
...@@ -2436,6 +2523,10 @@ pub const Type = extern union {...@@ -2436,6 +2523,10 @@ pub const Type = extern union {
2436 .empty_struct,2523 .empty_struct,
2437 .inferred_alloc_const,2524 .inferred_alloc_const,
2438 .inferred_alloc_mut,2525 .inferred_alloc_mut,
2526 .@"enum",
2527 .@"struct",
2528 .@"union",
2529 .@"opaque",
2439 => unreachable,2530 => unreachable,
2440 }2531 }
2441 }2532 }
...@@ -2515,6 +2606,10 @@ pub const Type = extern union {...@@ -2515,6 +2606,10 @@ pub const Type = extern union {
2515 .empty_struct,2606 .empty_struct,
2516 .inferred_alloc_const,2607 .inferred_alloc_const,
2517 .inferred_alloc_mut,2608 .inferred_alloc_mut,
2609 .@"enum",
2610 .@"struct",
2611 .@"union",
2612 .@"opaque",
2518 => unreachable,2613 => unreachable,
2519 };2614 };
2520 }2615 }
...@@ -2591,6 +2686,10 @@ pub const Type = extern union {...@@ -2591,6 +2686,10 @@ pub const Type = extern union {
2591 .empty_struct,2686 .empty_struct,
2592 .inferred_alloc_const,2687 .inferred_alloc_const,
2593 .inferred_alloc_mut,2688 .inferred_alloc_mut,
2689 .@"enum",
2690 .@"struct",
2691 .@"union",
2692 .@"opaque",
2594 => unreachable,2693 => unreachable,
2595 };2694 };
2596 }2695 }
...@@ -2667,6 +2766,10 @@ pub const Type = extern union {...@@ -2667,6 +2766,10 @@ pub const Type = extern union {
2667 .empty_struct,2766 .empty_struct,
2668 .inferred_alloc_const,2767 .inferred_alloc_const,
2669 .inferred_alloc_mut,2768 .inferred_alloc_mut,
2769 .@"enum",
2770 .@"struct",
2771 .@"union",
2772 .@"opaque",
2670 => unreachable,2773 => unreachable,
2671 };2774 };
2672 }2775 }
...@@ -2743,6 +2846,10 @@ pub const Type = extern union {...@@ -2743,6 +2846,10 @@ pub const Type = extern union {
2743 .empty_struct,2846 .empty_struct,
2744 .inferred_alloc_const,2847 .inferred_alloc_const,
2745 .inferred_alloc_mut,2848 .inferred_alloc_mut,
2849 .@"enum",
2850 .@"struct",
2851 .@"union",
2852 .@"opaque",
2746 => false,2853 => false,
2747 };2854 };
2748 }2855 }
...@@ -2800,8 +2907,13 @@ pub const Type = extern union {...@@ -2800,8 +2907,13 @@ pub const Type = extern union {
2800 .error_union,2907 .error_union,
2801 .error_set,2908 .error_set,
2802 .error_set_single,2909 .error_set_single,
2910 .@"opaque",
2803 => return null,2911 => return null,
28042912
2913 .@"enum" => @panic("TODO onePossibleValue enum"),
2914 .@"struct" => @panic("TODO onePossibleValue struct"),
2915 .@"union" => @panic("TODO onePossibleValue union"),
2916
2805 .empty_struct => return Value.initTag(.empty_struct_value),2917 .empty_struct => return Value.initTag(.empty_struct_value),
2806 .void => return Value.initTag(.void_value),2918 .void => return Value.initTag(.void_value),
2807 .noreturn => return Value.initTag(.unreachable_value),2919 .noreturn => return Value.initTag(.unreachable_value),
...@@ -2907,6 +3019,10 @@ pub const Type = extern union {...@@ -2907,6 +3019,10 @@ pub const Type = extern union {
2907 .empty_struct,3019 .empty_struct,
2908 .inferred_alloc_const,3020 .inferred_alloc_const,
2909 .inferred_alloc_mut,3021 .inferred_alloc_mut,
3022 .@"enum",
3023 .@"struct",
3024 .@"union",
3025 .@"opaque",
2910 => return false,3026 => return false,
29113027
2912 .c_const_pointer,3028 .c_const_pointer,
...@@ -2997,6 +3113,10 @@ pub const Type = extern union {...@@ -2997,6 +3113,10 @@ pub const Type = extern union {
2997 => unreachable,3113 => unreachable,
29983114
2999 .empty_struct => self.castTag(.empty_struct).?.data,3115 .empty_struct => self.castTag(.empty_struct).?.data,
3116 .@"enum" => &self.castTag(.@"enum").?.scope,
3117 .@"struct" => &self.castTag(.@"struct").?.scope,
3118 .@"union" => &self.castTag(.@"union").?.scope,
3119 .@"opaque" => &self.castTag(.@"opaque").?.scope,
3000 };3120 };
3001 }3121 }
30023122
...@@ -3137,6 +3257,10 @@ pub const Type = extern union {...@@ -3137,6 +3257,10 @@ pub const Type = extern union {
3137 error_set,3257 error_set,
3138 error_set_single,3258 error_set_single,
3139 empty_struct,3259 empty_struct,
3260 @"enum",
3261 @"struct",
3262 @"union",
3263 @"opaque",
31403264
3141 pub const last_no_payload_tag = Tag.inferred_alloc_const;3265 pub const last_no_payload_tag = Tag.inferred_alloc_const;
3142 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;3266 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
...@@ -3219,6 +3343,10 @@ pub const Type = extern union {...@@ -3219,6 +3343,10 @@ pub const Type = extern union {
3219 .error_set => Payload.Decl,3343 .error_set => Payload.Decl,
3220 .error_set_single => Payload.Name,3344 .error_set_single => Payload.Name,
3221 .empty_struct => Payload.ContainerScope,3345 .empty_struct => Payload.ContainerScope,
3346 .@"enum" => Payload.Enum,
3347 .@"struct" => Payload.Struct,
3348 .@"union" => Payload.Union,
3349 .@"opaque" => Payload.Opaque,
3222 };3350 };
3223 }3351 }
32243352
...@@ -3332,6 +3460,16 @@ pub const Type = extern union {...@@ -3332,6 +3460,16 @@ pub const Type = extern union {
3332 base: Payload,3460 base: Payload,
3333 data: *Module.Scope.Container,3461 data: *Module.Scope.Container,
3334 };3462 };
3463
3464 pub const Opaque = struct {
3465 base: Payload = .{ .tag = .@"opaque" },
3466
3467 scope: Module.Scope.Container,
3468 };
3469
3470 pub const Enum = @import("type/Enum.zig");
3471 pub const Struct = @import("type/Struct.zig");
3472 pub const Union = @import("type/Union.zig");
3335 };3473 };
3336};3474};
33373475
src/type/Enum.zig created+55
...@@ -0,0 +1,55 @@
1const std = @import("std");
2const zir = @import("../zir.zig");
3const Value = @import("../value.zig").Value;
4const Type = @import("../type.zig").Type;
5const Module = @import("../Module.zig");
6const Scope = Module.Scope;
7const Enum = @This();
8
9base: Type.Payload = .{ .tag = .@"enum" },
10
11analysis: union(enum) {
12 queued: Zir,
13 in_progress,
14 resolved: Size,
15 failed,
16},
17scope: Scope.Container,
18
19pub const Field = struct {
20 value: Value,
21};
22
23pub const Zir = struct {
24 body: zir.Module.Body,
25 inst: *zir.Inst,
26};
27
28pub const Size = struct {
29 tag_type: Type,
30 fields: std.StringArrayHashMapUnmanaged(Field),
31};
32
33pub fn resolve(self: *Enum, mod: *Module, scope: *Scope) !void {
34 const zir = switch (self.analysis) {
35 .failed => return error.AnalysisFail,
36 .resolved => return,
37 .in_progress => {
38 return mod.fail(scope, src, "enum '{}' depends on itself", .{enum_name});
39 },
40 .queued => |zir| zir,
41 };
42 self.analysis = .in_progress;
43
44 // TODO
45}
46
47// TODO should this resolve the type or assert that it has already been resolved?
48pub fn abiAlignment(self: *Enum, target: std.Target) u32 {
49 switch (self.analysis) {
50 .queued => unreachable, // alignment has not been resolved
51 .in_progress => unreachable, // alignment has not been resolved
52 .failed => unreachable, // type resolution failed
53 .resolved => |r| return r.tag_type.abiAlignment(target),
54 }
55}
src/type/Struct.zig created+56
...@@ -0,0 +1,56 @@
1const std = @import("std");
2const zir = @import("../zir.zig");
3const Value = @import("../value.zig").Value;
4const Type = @import("../type.zig").Type;
5const Module = @import("../Module.zig");
6const Scope = Module.Scope;
7const Struct = @This();
8
9base: Type.Payload = .{ .tag = .@"struct" },
10
11analysis: union(enum) {
12 queued: Zir,
13 zero_bits_in_progress,
14 zero_bits: Zero,
15 in_progress,
16 // alignment: Align,
17 resolved: Size,
18 failed,
19},
20scope: Scope.Container,
21
22pub const Field = struct {
23 value: Value,
24};
25
26pub const Zir = struct {
27 body: zir.Module.Body,
28 inst: *zir.Inst,
29};
30
31pub const Zero = struct {
32 is_zero_bits: bool,
33 fields: std.StringArrayHashMapUnmanaged(Field),
34};
35
36pub const Size = struct {
37 is_zero_bits: bool,
38 alignment: u32,
39 size: u32,
40 fields: std.StringArrayHashMapUnmanaged(Field),
41};
42
43pub fn resolveZeroBits(self: *Struct, mod: *Module, scope: *Scope) !void {
44 const zir = switch (self.analysis) {
45 .failed => return error.AnalysisFail,
46 .zero_bits_in_progress => {
47 return mod.fail(scope, src, "struct '{}' depends on itself", .{});
48 },
49 .queued => |zir| zir,
50 else => return,
51 };
52
53 self.analysis = .zero_bits_in_progress;
54
55 // TODO
56}
src/type/Union.zig created+56
...@@ -0,0 +1,56 @@
1const std = @import("std");
2const zir = @import("../zir.zig");
3const Value = @import("../value.zig").Value;
4const Type = @import("../type.zig").Type;
5const Module = @import("../Module.zig");
6const Scope = Module.Scope;
7const Union = @This();
8
9base: Type.Payload = .{ .tag = .@"struct" },
10
11analysis: union(enum) {
12 queued: Zir,
13 zero_bits_in_progress,
14 zero_bits: Zero,
15 in_progress,
16 // alignment: Align,
17 resolved: Size,
18 failed,
19},
20scope: Scope.Container,
21
22pub const Field = struct {
23 value: Value,
24};
25
26pub const Zir = struct {
27 body: zir.Module.Body,
28 inst: *zir.Inst,
29};
30
31pub const Zero = struct {
32 is_zero_bits: bool,
33 fields: std.StringArrayHashMapUnmanaged(Field),
34};
35
36pub const Size = struct {
37 is_zero_bits: bool,
38 alignment: u32,
39 size: u32,
40 fields: std.StringArrayHashMapUnmanaged(Field),
41};
42
43pub fn resolveZeroBits(self: *Union, mod: *Module, scope: *Scope) !void {
44 const zir = switch (self.analysis) {
45 .failed => return error.AnalysisFail,
46 .zero_bits_in_progress => {
47 return mod.fail(scope, src, "union '{}' depends on itself", .{});
48 },
49 .queued => |zir| zir,
50 else => return,
51 };
52
53 self.analysis = .zero_bits_in_progress;
54
55 // TODO
56}
src/value.zig+1-1
...@@ -389,7 +389,6 @@ pub const Value = extern union {...@@ -389,7 +389,6 @@ pub const Value = extern union {
389 },389 },
390 .@"error" => return self.copyPayloadShallow(allocator, Payload.Error),390 .@"error" => return self.copyPayloadShallow(allocator, Payload.Error),
391391
392 // memory is managed by the declaration
393 .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),392 .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),
394393
395 .inferred_alloc => unreachable,394 .inferred_alloc => unreachable,
...@@ -2025,6 +2024,7 @@ pub const Value = extern union {...@@ -2025,6 +2024,7 @@ pub const Value = extern union {
2025 data: f128,2024 data: f128,
2026 };2025 };
20272026
2027 // TODO move to type.zig
2028 pub const ErrorSet = struct {2028 pub const ErrorSet = struct {
2029 pub const base_tag = Tag.error_set;2029 pub const base_tag = Tag.error_set;
20302030
src/zir.zig+107-1
...@@ -133,6 +133,12 @@ pub const Inst = struct {...@@ -133,6 +133,12 @@ pub const Inst = struct {
133 condbr,133 condbr,
134 /// Special case, has no textual representation.134 /// Special case, has no textual representation.
135 @"const",135 @"const",
136 /// Container field with just the name.
137 container_field_named,
138 /// Container field with a type and a name,
139 container_field_typed,
140 /// Container field with all the bells and whistles.
141 container_field,
136 /// Declares the beginning of a statement. Used for debug info.142 /// Declares the beginning of a statement. Used for debug info.
137 dbg_stmt,143 dbg_stmt,
138 /// Represents a pointer to a global decl by name.144 /// Represents a pointer to a global decl by name.
...@@ -263,6 +269,8 @@ pub const Inst = struct {...@@ -263,6 +269,8 @@ pub const Inst = struct {
263 store_to_inferred_ptr,269 store_to_inferred_ptr,
264 /// String Literal. Makes an anonymous Decl and then takes a pointer to it.270 /// String Literal. Makes an anonymous Decl and then takes a pointer to it.
265 str,271 str,
272 /// Create a struct type.
273 struct_type,
266 /// Arithmetic subtraction. Asserts no integer overflow.274 /// Arithmetic subtraction. Asserts no integer overflow.
267 sub,275 sub,
268 /// Twos complement wrapping integer subtraction.276 /// Twos complement wrapping integer subtraction.
...@@ -282,6 +290,8 @@ pub const Inst = struct {...@@ -282,6 +290,8 @@ pub const Inst = struct {
282 xor,290 xor,
283 /// Create an optional type '?T'291 /// Create an optional type '?T'
284 optional_type,292 optional_type,
293 /// Create a union type.
294 union_type,
285 /// Unwraps an optional value 'lhs.?'295 /// Unwraps an optional value 'lhs.?'
286 unwrap_optional_safe,296 unwrap_optional_safe,
287 /// Same as previous, but without safety checks. Used for orelse, if and while297 /// Same as previous, but without safety checks. Used for orelse, if and while
...@@ -294,8 +304,10 @@ pub const Inst = struct {...@@ -294,8 +304,10 @@ pub const Inst = struct {
294 unwrap_err_code,304 unwrap_err_code,
295 /// Takes a *E!T and raises a compiler error if T != void305 /// Takes a *E!T and raises a compiler error if T != void
296 ensure_err_payload_void,306 ensure_err_payload_void,
297 /// Enum literal307 /// Create a enum literal,
298 enum_literal,308 enum_literal,
309 /// Create an enum type.
310 enum_type,
299 /// A switch expression.311 /// A switch expression.
300 switchbr,312 switchbr,
301 /// A range in a switch case, `lhs...rhs`.313 /// A range in a switch case, `lhs...rhs`.
...@@ -430,6 +442,12 @@ pub const Inst = struct {...@@ -430,6 +442,12 @@ pub const Inst = struct {
430 .slice => Slice,442 .slice => Slice,
431 .switchbr => SwitchBr,443 .switchbr => SwitchBr,
432 .typeof_peer => TypeOfPeer,444 .typeof_peer => TypeOfPeer,
445 .container_field_named => ContainerFieldNamed,
446 .container_field_typed => ContainerFieldTyped,
447 .container_field => ContainerField,
448 .enum_type => EnumType,
449 .union_type => UnionType,
450 .struct_type => StructType,
433 };451 };
434 }452 }
435453
...@@ -544,6 +562,9 @@ pub const Inst = struct {...@@ -544,6 +562,9 @@ pub const Inst = struct {
544 .resolve_inferred_alloc,562 .resolve_inferred_alloc,
545 .set_eval_branch_quota,563 .set_eval_branch_quota,
546 .compilelog,564 .compilelog,
565 .enum_type,
566 .union_type,
567 .struct_type,
547 => false,568 => false,
548569
549 .@"break",570 .@"break",
...@@ -556,6 +577,9 @@ pub const Inst = struct {...@@ -556,6 +577,9 @@ pub const Inst = struct {
556 .@"unreachable",577 .@"unreachable",
557 .loop,578 .loop,
558 .switchbr,579 .switchbr,
580 .container_field_named,
581 .container_field_typed,
582 .container_field,
559 => true,583 => true,
560 };584 };
561 }585 }
...@@ -1079,6 +1103,88 @@ pub const Inst = struct {...@@ -1079,6 +1103,88 @@ pub const Inst = struct {
1079 },1103 },
1080 kw_args: struct {},1104 kw_args: struct {},
1081 };1105 };
1106
1107 pub const ContainerFieldNamed = struct {
1108 pub const base_tag = Tag.container_field_named;
1109 base: Inst,
1110
1111 positionals: struct {
1112 bytes: []const u8,
1113 },
1114 kw_args: struct {},
1115 };
1116
1117 pub const ContainerFieldTyped = struct {
1118 pub const base_tag = Tag.container_field_typed;
1119 base: Inst,
1120
1121 positionals: struct {
1122 bytes: []const u8,
1123 ty: *Inst,
1124 },
1125 kw_args: struct {},
1126 };
1127
1128 pub const ContainerField = struct {
1129 pub const base_tag = Tag.container_field;
1130 base: Inst,
1131
1132 positionals: struct {
1133 bytes: []const u8,
1134 },
1135 kw_args: struct {
1136 ty: ?*Inst = null,
1137 init: ?*Inst = null,
1138 alignment: ?*Inst = null,
1139 is_comptime: bool = false,
1140 },
1141 };
1142
1143 pub const EnumType = struct {
1144 pub const base_tag = Tag.enum_type;
1145 base: Inst,
1146
1147 positionals: struct {
1148 fields: []*Inst,
1149 },
1150 kw_args: struct {
1151 tag_type: ?*Inst = null,
1152 layout: std.builtin.TypeInfo.ContainerLayout = .Auto,
1153 },
1154 };
1155
1156 pub const StructType = struct {
1157 pub const base_tag = Tag.struct_type;
1158 base: Inst,
1159
1160 positionals: struct {
1161 fields: []*Inst,
1162 },
1163 kw_args: struct {
1164 layout: std.builtin.TypeInfo.ContainerLayout = .Auto,
1165 },
1166 };
1167
1168 pub const UnionType = struct {
1169 pub const base_tag = Tag.union_type;
1170 base: Inst,
1171
1172 positionals: struct {
1173 fields: []*Inst,
1174 },
1175 kw_args: struct {
1176 init_inst: ?*Inst = null,
1177 init_kind: InitKind = .none,
1178 layout: std.builtin.TypeInfo.ContainerLayout = .Auto,
1179 },
1180
1181 // TODO error: values of type '(enum literal)' must be comptime known
1182 pub const InitKind = enum {
1183 enum_type,
1184 tag_type,
1185 none,
1186 };
1187 };
1082};1188};
10831189
1084pub const ErrorMsg = struct {1190pub const ErrorMsg = struct {
src/zir_sema.zig+8
...@@ -155,6 +155,14 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!...@@ -155,6 +155,14 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!
155 .switch_range => return analyzeInstSwitchRange(mod, scope, old_inst.castTag(.switch_range).?),155 .switch_range => return analyzeInstSwitchRange(mod, scope, old_inst.castTag(.switch_range).?),
156 .booland => return analyzeInstBoolOp(mod, scope, old_inst.castTag(.booland).?),156 .booland => return analyzeInstBoolOp(mod, scope, old_inst.castTag(.booland).?),
157 .boolor => return analyzeInstBoolOp(mod, scope, old_inst.castTag(.boolor).?),157 .boolor => return analyzeInstBoolOp(mod, scope, old_inst.castTag(.boolor).?),
158
159 .container_field_named,
160 .container_field_typed,
161 .container_field,
162 .enum_type,
163 .union_type,
164 .struct_type,
165 => return mod.fail(scope, old_inst.src, "TODO analyze container instructions", .{}),
158 }166 }
159}167}
160168