authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-24 16:24:23+03:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-24 15:36:42-07:00
log5de9aac7491958806164f46c356fce983b1c8624
tree41c4a9ef18996e39a2b24c2c765b2b4c452fffe5
parentbc1d55a1d19e1b4ad3826d58127396f27e96242c

stage2: error set types


4 files changed, 118 insertions(+), 17 deletions(-)

src-self-hosted/type.zig+79-3
......@@ -3,6 +3,7 @@ const Value = @import("value.zig").Value;
33const assert = std.debug.assert;
44const Allocator = std.mem.Allocator;
55const Target = std.Target;
6const Module = @import("Module.zig");
67
78/// This is the raw data, with no bookkeeping, no memory awareness, no de-duplication.
89/// It's important for this type to be small.
......@@ -52,7 +53,7 @@ pub const Type = extern union {
5253 .bool => return .Bool,
5354 .void => return .Void,
5455 .type => return .Type,
55 .anyerror => return .ErrorSet,
56 .error_set, .error_set_single, .anyerror => return .ErrorSet,
5657 .comptime_int => return .ComptimeInt,
5758 .comptime_float => return .ComptimeFloat,
5859 .noreturn => return .NoReturn,
......@@ -436,6 +437,8 @@ pub const Type = extern union {
436437 };
437438 return Type{ .ptr_otherwise = &new_payload.base };
438439 },
440 .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),
441 .error_set_single => return self.copyPayloadShallow(allocator, Payload.ErrorSetSingle),
439442 }
440443 }
441444
......@@ -657,6 +660,14 @@ pub const Type = extern union {
657660 ty = payload.payload;
658661 continue;
659662 },
663 .error_set => {
664 const payload = @fieldParentPtr(Payload.ErrorSet, "base", ty.ptr_otherwise);
665 return out_stream.writeAll(std.mem.spanZ(payload.decl.name));
666 },
667 .error_set_single => {
668 const payload = @fieldParentPtr(Payload.ErrorSetSingle, "base", ty.ptr_otherwise);
669 return out_stream.print("error{{{}}}", .{payload.name});
670 },
660671 }
661672 unreachable;
662673 }
......@@ -753,6 +764,8 @@ pub const Type = extern union {
753764 .@"anyframe",
754765 .anyframe_T,
755766 .anyerror_void_error_union,
767 .error_set,
768 .error_set_single,
756769 => true,
757770 // TODO lazy types
758771 .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,
......@@ -848,7 +861,11 @@ pub const Type = extern union {
848861 .f128 => return 16,
849862 .c_longdouble => return 16,
850863
851 .anyerror_void_error_union, .anyerror => return 2, // TODO revisit this when we have the concept of the error tag type
864 .error_set,
865 .error_set_single,
866 .anyerror_void_error_union,
867 .anyerror,
868 => return 2, // TODO revisit this when we have the concept of the error tag type
852869
853870 .array, .array_sentinel => return self.elemType().abiAlignment(target),
854871
......@@ -981,7 +998,11 @@ pub const Type = extern union {
981998 .f128 => return 16,
982999 .c_longdouble => return 16,
9831000
984 .anyerror_void_error_union, .anyerror => return 2, // TODO revisit this when we have the concept of the error tag type
1001 .error_set,
1002 .error_set_single,
1003 .anyerror_void_error_union,
1004 .anyerror,
1005 => return 2, // TODO revisit this when we have the concept of the error tag type
9851006
9861007 .int_signed, .int_unsigned => {
9871008 const bits: u16 = if (self.cast(Payload.IntSigned)) |pl|
......@@ -1084,6 +1105,8 @@ pub const Type = extern union {
10841105 .@"anyframe",
10851106 .anyframe_T,
10861107 .anyerror_void_error_union,
1108 .error_set,
1109 .error_set_single,
10871110 => false,
10881111
10891112 .single_const_pointer,
......@@ -1156,6 +1179,8 @@ pub const Type = extern union {
11561179 .@"anyframe",
11571180 .anyframe_T,
11581181 .anyerror_void_error_union,
1182 .error_set,
1183 .error_set_single,
11591184 => false,
11601185
11611186 .const_slice,
......@@ -1225,6 +1250,8 @@ pub const Type = extern union {
12251250 .@"anyframe",
12261251 .anyframe_T,
12271252 .anyerror_void_error_union,
1253 .error_set,
1254 .error_set_single,
12281255 => false,
12291256
12301257 .single_const_pointer,
......@@ -1303,6 +1330,8 @@ pub const Type = extern union {
13031330 .@"anyframe",
13041331 .anyframe_T,
13051332 .anyerror_void_error_union,
1333 .error_set,
1334 .error_set_single,
13061335 => false,
13071336
13081337 .pointer => {
......@@ -1418,6 +1447,8 @@ pub const Type = extern union {
14181447 .@"anyframe",
14191448 .anyframe_T,
14201449 .anyerror_void_error_union,
1450 .error_set,
1451 .error_set_single,
14211452 => unreachable,
14221453
14231454 .array => self.cast(Payload.Array).?.elem_type,
......@@ -1543,6 +1574,8 @@ pub const Type = extern union {
15431574 .@"anyframe",
15441575 .anyframe_T,
15451576 .anyerror_void_error_union,
1577 .error_set,
1578 .error_set_single,
15461579 => unreachable,
15471580
15481581 .array => self.cast(Payload.Array).?.len,
......@@ -1614,6 +1647,8 @@ pub const Type = extern union {
16141647 .@"anyframe",
16151648 .anyframe_T,
16161649 .anyerror_void_error_union,
1650 .error_set,
1651 .error_set_single,
16171652 => unreachable,
16181653
16191654 .array, .array_u8 => return null,
......@@ -1683,6 +1718,8 @@ pub const Type = extern union {
16831718 .@"anyframe",
16841719 .anyframe_T,
16851720 .anyerror_void_error_union,
1721 .error_set,
1722 .error_set_single,
16861723 => false,
16871724
16881725 .int_signed,
......@@ -1755,6 +1792,8 @@ pub const Type = extern union {
17551792 .@"anyframe",
17561793 .anyframe_T,
17571794 .anyerror_void_error_union,
1795 .error_set,
1796 .error_set_single,
17581797 => false,
17591798
17601799 .int_unsigned,
......@@ -1817,6 +1856,8 @@ pub const Type = extern union {
18171856 .@"anyframe",
18181857 .anyframe_T,
18191858 .anyerror_void_error_union,
1859 .error_set,
1860 .error_set_single,
18201861 => unreachable,
18211862
18221863 .int_unsigned => .{ .signed = false, .bits = self.cast(Payload.IntUnsigned).?.bits },
......@@ -1897,6 +1938,8 @@ pub const Type = extern union {
18971938 .@"anyframe",
18981939 .anyframe_T,
18991940 .anyerror_void_error_union,
1941 .error_set,
1942 .error_set_single,
19001943 => false,
19011944
19021945 .usize,
......@@ -2006,6 +2049,8 @@ pub const Type = extern union {
20062049 .@"anyframe",
20072050 .anyframe_T,
20082051 .anyerror_void_error_union,
2052 .error_set,
2053 .error_set_single,
20092054 => unreachable,
20102055 };
20112056 }
......@@ -2081,6 +2126,8 @@ pub const Type = extern union {
20812126 .@"anyframe",
20822127 .anyframe_T,
20832128 .anyerror_void_error_union,
2129 .error_set,
2130 .error_set_single,
20842131 => unreachable,
20852132 }
20862133 }
......@@ -2155,6 +2202,8 @@ pub const Type = extern union {
21552202 .@"anyframe",
21562203 .anyframe_T,
21572204 .anyerror_void_error_union,
2205 .error_set,
2206 .error_set_single,
21582207 => unreachable,
21592208 }
21602209 }
......@@ -2229,6 +2278,8 @@ pub const Type = extern union {
22292278 .@"anyframe",
22302279 .anyframe_T,
22312280 .anyerror_void_error_union,
2281 .error_set,
2282 .error_set_single,
22322283 => unreachable,
22332284 };
22342285 }
......@@ -2300,6 +2351,8 @@ pub const Type = extern union {
23002351 .@"anyframe",
23012352 .anyframe_T,
23022353 .anyerror_void_error_union,
2354 .error_set,
2355 .error_set_single,
23032356 => unreachable,
23042357 };
23052358 }
......@@ -2371,6 +2424,8 @@ pub const Type = extern union {
23712424 .@"anyframe",
23722425 .anyframe_T,
23732426 .anyerror_void_error_union,
2427 .error_set,
2428 .error_set_single,
23742429 => unreachable,
23752430 };
23762431 }
......@@ -2442,6 +2497,8 @@ pub const Type = extern union {
24422497 .@"anyframe",
24432498 .anyframe_T,
24442499 .anyerror_void_error_union,
2500 .error_set,
2501 .error_set_single,
24452502 => false,
24462503 };
24472504 }
......@@ -2497,6 +2554,8 @@ pub const Type = extern union {
24972554 .anyframe_T,
24982555 .@"anyframe",
24992556 .error_union,
2557 .error_set,
2558 .error_set_single,
25002559 => return null,
25012560
25022561 .void => return Value.initTag(.void_value),
......@@ -2604,6 +2663,8 @@ pub const Type = extern union {
26042663 .@"anyframe",
26052664 .anyframe_T,
26062665 .anyerror_void_error_union,
2666 .error_set,
2667 .error_set_single,
26072668 => return false,
26082669
26092670 .c_const_pointer,
......@@ -2687,6 +2748,8 @@ pub const Type = extern union {
26872748 optional_single_const_pointer,
26882749 error_union,
26892750 anyframe_T,
2751 error_set,
2752 error_set_single,
26902753
26912754 pub const last_no_payload_tag = Tag.const_slice_u8;
26922755 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
......@@ -2781,6 +2844,19 @@ pub const Type = extern union {
27812844
27822845 return_type: Type,
27832846 };
2847
2848 pub const ErrorSet = struct {
2849 base: Payload = .{ .tag = .error_set },
2850
2851 decl: *Module.Decl,
2852 };
2853
2854 pub const ErrorSetSingle = struct {
2855 base: Payload = .{ .tag = .error_set_single },
2856
2857 /// memory is owned by `Module`
2858 name: []const u8,
2859 };
27842860 };
27852861};
27862862
src-self-hosted/value.zig+21-4
......@@ -381,11 +381,9 @@ pub const Value = extern union {
381381 }
382382
383383 /// Asserts that the value is representable as a type.
384 pub fn toType(self: Value) Type {
384 pub fn toType(self: Value, allocator: *Allocator) !Type {
385385 return switch (self.tag()) {
386386 .ty => self.cast(Payload.Ty).?.ty,
387 .int_type => @panic("TODO int type to type"),
388
389387 .u8_type => Type.initTag(.u8),
390388 .i8_type => Type.initTag(.i8),
391389 .u16_type => Type.initTag(.u16),
......@@ -427,7 +425,25 @@ pub const Value = extern union {
427425 .const_slice_u8_type => Type.initTag(.const_slice_u8),
428426 .enum_literal_type => Type.initTag(.enum_literal),
429427 .anyframe_type => Type.initTag(.@"anyframe"),
430 .error_set => @panic("TODO error set to type"),
428
429 .int_type => {
430 const payload = self.cast(Payload.IntType).?;
431 if (payload.signed) {
432 const new = try allocator.create(Type.Payload.IntSigned);
433 new.* = .{ .bits = payload.bits };
434 return Type.initPayload(&new.base);
435 } else {
436 const new = try allocator.create(Type.Payload.IntUnsigned);
437 new.* = .{ .bits = payload.bits };
438 return Type.initPayload(&new.base);
439 }
440 },
441 .error_set => {
442 const payload = self.cast(Payload.ErrorSet).?;
443 const new = try allocator.create(Type.Payload.ErrorSet);
444 new.* = .{ .decl = payload.decl };
445 return Type.initPayload(&new.base);
446 },
431447
432448 .undef,
433449 .zero,
......@@ -1579,6 +1595,7 @@ pub const Value = extern union {
15791595
15801596 // TODO revisit this when we have the concept of the error tag type
15811597 fields: std.StringHashMapUnmanaged(u16),
1598 decl: *Module.Decl,
15821599 };
15831600
15841601 pub const Error = struct {
src-self-hosted/zir.zig+1-1
......@@ -2016,7 +2016,7 @@ const EmitZIR = struct {
20162016 return self.emitUnnamedDecl(&as_inst.base);
20172017 },
20182018 .Type => {
2019 const ty = typed_value.val.toType();
2019 const ty = try typed_value.val.toType(&self.arena.allocator);
20202020 return self.emitType(src, ty);
20212021 },
20222022 .Fn => {
src-self-hosted/zir_sema.zig+17-9
......@@ -150,7 +150,7 @@ pub fn analyzeBodyValueAsType(mod: *Module, block_scope: *Scope.Block, body: zir
150150 for (block_scope.instructions.items) |inst| {
151151 if (inst.castTag(.ret)) |ret| {
152152 const val = try mod.resolveConstValue(&block_scope.base, ret.operand);
153 return val.toType();
153 return val.toType(block_scope.base.arena());
154154 } else {
155155 return mod.fail(&block_scope.base, inst.src, "unable to resolve comptime value", .{});
156156 }
......@@ -275,7 +275,7 @@ fn resolveType(mod: *Module, scope: *Scope, old_inst: *zir.Inst) !Type {
275275 const wanted_type = Type.initTag(.@"type");
276276 const coerced_inst = try mod.coerce(scope, wanted_type, new_inst);
277277 const val = try mod.resolveConstValue(scope, coerced_inst);
278 return val.toType();
278 return val.toType(scope.arena());
279279}
280280
281281fn resolveInt(mod: *Module, scope: *Scope, old_inst: *zir.Inst, dest_type: Type) !u64 {
......@@ -745,7 +745,10 @@ fn analyzeInstErrorSet(mod: *Module, scope: *Scope, inst: *zir.Inst.ErrorSet) In
745745 errdefer new_decl_arena.deinit();
746746
747747 const payload = try scope.arena().create(Value.Payload.ErrorSet);
748 payload.* = .{ .fields = .{} };
748 payload.* = .{
749 .fields = .{},
750 .decl = undefined, // populated below
751 };
749752 try payload.fields.ensureCapacity(&new_decl_arena.allocator, inst.positionals.fields.len);
750753
751754 for (inst.positionals.fields) |field_name| {
......@@ -759,6 +762,7 @@ fn analyzeInstErrorSet(mod: *Module, scope: *Scope, inst: *zir.Inst.ErrorSet) In
759762 .ty = Type.initTag(.type),
760763 .val = Value.initPayload(&payload.base),
761764 });
765 payload.decl = new_decl;
762766 return mod.analyzeDeclRef(scope, inst.base.src, new_decl);
763767}
764768
......@@ -939,18 +943,17 @@ fn analyzeInstFieldPtr(mod: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPtr
939943 _ = try mod.resolveConstValue(scope, object_ptr);
940944 const result = try mod.analyzeDeref(scope, fieldptr.base.src, object_ptr, object_ptr.src);
941945 const val = result.value().?;
942 const child_type = val.toType();
946 const child_type = try val.toType(scope.arena());
943947 switch (child_type.zigTypeTag()) {
944948 .ErrorSet => {
945949 // TODO resolve inferred error sets
946950 const entry = if (val.cast(Value.Payload.ErrorSet)) |payload|
947951 (payload.fields.getEntry(field_name) orelse
948952 return mod.fail(scope, fieldptr.base.src, "no error named '{}' in '{}'", .{ field_name, child_type })).*
949 else
950 try mod.getErrorValue(field_name);
953 else try mod.getErrorValue(field_name);
951954
952955 const error_payload = try scope.arena().create(Value.Payload.Error);
953 error_payload.* = .{
956 error_payload.* = .{
954957 .name = entry.key,
955958 .value = entry.value,
956959 };
......@@ -958,9 +961,14 @@ fn analyzeInstFieldPtr(mod: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPtr
958961 const ref_payload = try scope.arena().create(Value.Payload.RefVal);
959962 ref_payload.* = .{ .val = Value.initPayload(&error_payload.base) };
960963
961 // TODO if this is accessing the global error set create a `error{field_name}` type
964 const result_type = if (child_type.tag() == .anyerror) blk: {
965 const result_payload = try scope.arena().create(Type.Payload.ErrorSetSingle);
966 result_payload.* = .{ .name = entry.key };
967 break :blk Type.initPayload(&result_payload.base);
968 } else child_type;
969
962970 return mod.constInst(scope, fieldptr.base.src, .{
963 .ty = try mod.simplePtrType(scope, fieldptr.base.src, child_type, false, .One),
971 .ty = try mod.simplePtrType(scope, fieldptr.base.src, result_type, false, .One),
964972 .val = Value.initPayload(&ref_payload.base),
965973 });
966974 },