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;...@@ -3,6 +3,7 @@ const Value = @import("value.zig").Value;
3const assert = std.debug.assert;3const assert = std.debug.assert;
4const Allocator = std.mem.Allocator;4const Allocator = std.mem.Allocator;
5const Target = std.Target;5const Target = std.Target;
6const Module = @import("Module.zig");
67
7/// This is the raw data, with no bookkeeping, no memory awareness, no de-duplication.8/// This is the raw data, with no bookkeeping, no memory awareness, no de-duplication.
8/// It's important for this type to be small.9/// It's important for this type to be small.
...@@ -52,7 +53,7 @@ pub const Type = extern union {...@@ -52,7 +53,7 @@ pub const Type = extern union {
52 .bool => return .Bool,53 .bool => return .Bool,
53 .void => return .Void,54 .void => return .Void,
54 .type => return .Type,55 .type => return .Type,
55 .anyerror => return .ErrorSet,56 .error_set, .error_set_single, .anyerror => return .ErrorSet,
56 .comptime_int => return .ComptimeInt,57 .comptime_int => return .ComptimeInt,
57 .comptime_float => return .ComptimeFloat,58 .comptime_float => return .ComptimeFloat,
58 .noreturn => return .NoReturn,59 .noreturn => return .NoReturn,
...@@ -436,6 +437,8 @@ pub const Type = extern union {...@@ -436,6 +437,8 @@ pub const Type = extern union {
436 };437 };
437 return Type{ .ptr_otherwise = &new_payload.base };438 return Type{ .ptr_otherwise = &new_payload.base };
438 },439 },
440 .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),
441 .error_set_single => return self.copyPayloadShallow(allocator, Payload.ErrorSetSingle),
439 }442 }
440 }443 }
441444
...@@ -657,6 +660,14 @@ pub const Type = extern union {...@@ -657,6 +660,14 @@ pub const Type = extern union {
657 ty = payload.payload;660 ty = payload.payload;
658 continue;661 continue;
659 },662 },
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 },
660 }671 }
661 unreachable;672 unreachable;
662 }673 }
...@@ -753,6 +764,8 @@ pub const Type = extern union {...@@ -753,6 +764,8 @@ pub const Type = extern union {
753 .@"anyframe",764 .@"anyframe",
754 .anyframe_T,765 .anyframe_T,
755 .anyerror_void_error_union,766 .anyerror_void_error_union,
767 .error_set,
768 .error_set_single,
756 => true,769 => true,
757 // TODO lazy types770 // TODO lazy types
758 .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,771 .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,
...@@ -848,7 +861,11 @@ pub const Type = extern union {...@@ -848,7 +861,11 @@ pub const Type = extern union {
848 .f128 => return 16,861 .f128 => return 16,
849 .c_longdouble => return 16,862 .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 type864 .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
853 .array, .array_sentinel => return self.elemType().abiAlignment(target),870 .array, .array_sentinel => return self.elemType().abiAlignment(target),
854871
...@@ -981,7 +998,11 @@ pub const Type = extern union {...@@ -981,7 +998,11 @@ pub const Type = extern union {
981 .f128 => return 16,998 .f128 => return 16,
982 .c_longdouble => return 16,999 .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 type1001 .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
986 .int_signed, .int_unsigned => {1007 .int_signed, .int_unsigned => {
987 const bits: u16 = if (self.cast(Payload.IntSigned)) |pl|1008 const bits: u16 = if (self.cast(Payload.IntSigned)) |pl|
...@@ -1084,6 +1105,8 @@ pub const Type = extern union {...@@ -1084,6 +1105,8 @@ pub const Type = extern union {
1084 .@"anyframe",1105 .@"anyframe",
1085 .anyframe_T,1106 .anyframe_T,
1086 .anyerror_void_error_union,1107 .anyerror_void_error_union,
1108 .error_set,
1109 .error_set_single,
1087 => false,1110 => false,
10881111
1089 .single_const_pointer,1112 .single_const_pointer,
...@@ -1156,6 +1179,8 @@ pub const Type = extern union {...@@ -1156,6 +1179,8 @@ pub const Type = extern union {
1156 .@"anyframe",1179 .@"anyframe",
1157 .anyframe_T,1180 .anyframe_T,
1158 .anyerror_void_error_union,1181 .anyerror_void_error_union,
1182 .error_set,
1183 .error_set_single,
1159 => false,1184 => false,
11601185
1161 .const_slice,1186 .const_slice,
...@@ -1225,6 +1250,8 @@ pub const Type = extern union {...@@ -1225,6 +1250,8 @@ pub const Type = extern union {
1225 .@"anyframe",1250 .@"anyframe",
1226 .anyframe_T,1251 .anyframe_T,
1227 .anyerror_void_error_union,1252 .anyerror_void_error_union,
1253 .error_set,
1254 .error_set_single,
1228 => false,1255 => false,
12291256
1230 .single_const_pointer,1257 .single_const_pointer,
...@@ -1303,6 +1330,8 @@ pub const Type = extern union {...@@ -1303,6 +1330,8 @@ pub const Type = extern union {
1303 .@"anyframe",1330 .@"anyframe",
1304 .anyframe_T,1331 .anyframe_T,
1305 .anyerror_void_error_union,1332 .anyerror_void_error_union,
1333 .error_set,
1334 .error_set_single,
1306 => false,1335 => false,
13071336
1308 .pointer => {1337 .pointer => {
...@@ -1418,6 +1447,8 @@ pub const Type = extern union {...@@ -1418,6 +1447,8 @@ pub const Type = extern union {
1418 .@"anyframe",1447 .@"anyframe",
1419 .anyframe_T,1448 .anyframe_T,
1420 .anyerror_void_error_union,1449 .anyerror_void_error_union,
1450 .error_set,
1451 .error_set_single,
1421 => unreachable,1452 => unreachable,
14221453
1423 .array => self.cast(Payload.Array).?.elem_type,1454 .array => self.cast(Payload.Array).?.elem_type,
...@@ -1543,6 +1574,8 @@ pub const Type = extern union {...@@ -1543,6 +1574,8 @@ pub const Type = extern union {
1543 .@"anyframe",1574 .@"anyframe",
1544 .anyframe_T,1575 .anyframe_T,
1545 .anyerror_void_error_union,1576 .anyerror_void_error_union,
1577 .error_set,
1578 .error_set_single,
1546 => unreachable,1579 => unreachable,
15471580
1548 .array => self.cast(Payload.Array).?.len,1581 .array => self.cast(Payload.Array).?.len,
...@@ -1614,6 +1647,8 @@ pub const Type = extern union {...@@ -1614,6 +1647,8 @@ pub const Type = extern union {
1614 .@"anyframe",1647 .@"anyframe",
1615 .anyframe_T,1648 .anyframe_T,
1616 .anyerror_void_error_union,1649 .anyerror_void_error_union,
1650 .error_set,
1651 .error_set_single,
1617 => unreachable,1652 => unreachable,
16181653
1619 .array, .array_u8 => return null,1654 .array, .array_u8 => return null,
...@@ -1683,6 +1718,8 @@ pub const Type = extern union {...@@ -1683,6 +1718,8 @@ pub const Type = extern union {
1683 .@"anyframe",1718 .@"anyframe",
1684 .anyframe_T,1719 .anyframe_T,
1685 .anyerror_void_error_union,1720 .anyerror_void_error_union,
1721 .error_set,
1722 .error_set_single,
1686 => false,1723 => false,
16871724
1688 .int_signed,1725 .int_signed,
...@@ -1755,6 +1792,8 @@ pub const Type = extern union {...@@ -1755,6 +1792,8 @@ pub const Type = extern union {
1755 .@"anyframe",1792 .@"anyframe",
1756 .anyframe_T,1793 .anyframe_T,
1757 .anyerror_void_error_union,1794 .anyerror_void_error_union,
1795 .error_set,
1796 .error_set_single,
1758 => false,1797 => false,
17591798
1760 .int_unsigned,1799 .int_unsigned,
...@@ -1817,6 +1856,8 @@ pub const Type = extern union {...@@ -1817,6 +1856,8 @@ pub const Type = extern union {
1817 .@"anyframe",1856 .@"anyframe",
1818 .anyframe_T,1857 .anyframe_T,
1819 .anyerror_void_error_union,1858 .anyerror_void_error_union,
1859 .error_set,
1860 .error_set_single,
1820 => unreachable,1861 => unreachable,
18211862
1822 .int_unsigned => .{ .signed = false, .bits = self.cast(Payload.IntUnsigned).?.bits },1863 .int_unsigned => .{ .signed = false, .bits = self.cast(Payload.IntUnsigned).?.bits },
...@@ -1897,6 +1938,8 @@ pub const Type = extern union {...@@ -1897,6 +1938,8 @@ pub const Type = extern union {
1897 .@"anyframe",1938 .@"anyframe",
1898 .anyframe_T,1939 .anyframe_T,
1899 .anyerror_void_error_union,1940 .anyerror_void_error_union,
1941 .error_set,
1942 .error_set_single,
1900 => false,1943 => false,
19011944
1902 .usize,1945 .usize,
...@@ -2006,6 +2049,8 @@ pub const Type = extern union {...@@ -2006,6 +2049,8 @@ pub const Type = extern union {
2006 .@"anyframe",2049 .@"anyframe",
2007 .anyframe_T,2050 .anyframe_T,
2008 .anyerror_void_error_union,2051 .anyerror_void_error_union,
2052 .error_set,
2053 .error_set_single,
2009 => unreachable,2054 => unreachable,
2010 };2055 };
2011 }2056 }
...@@ -2081,6 +2126,8 @@ pub const Type = extern union {...@@ -2081,6 +2126,8 @@ pub const Type = extern union {
2081 .@"anyframe",2126 .@"anyframe",
2082 .anyframe_T,2127 .anyframe_T,
2083 .anyerror_void_error_union,2128 .anyerror_void_error_union,
2129 .error_set,
2130 .error_set_single,
2084 => unreachable,2131 => unreachable,
2085 }2132 }
2086 }2133 }
...@@ -2155,6 +2202,8 @@ pub const Type = extern union {...@@ -2155,6 +2202,8 @@ pub const Type = extern union {
2155 .@"anyframe",2202 .@"anyframe",
2156 .anyframe_T,2203 .anyframe_T,
2157 .anyerror_void_error_union,2204 .anyerror_void_error_union,
2205 .error_set,
2206 .error_set_single,
2158 => unreachable,2207 => unreachable,
2159 }2208 }
2160 }2209 }
...@@ -2229,6 +2278,8 @@ pub const Type = extern union {...@@ -2229,6 +2278,8 @@ pub const Type = extern union {
2229 .@"anyframe",2278 .@"anyframe",
2230 .anyframe_T,2279 .anyframe_T,
2231 .anyerror_void_error_union,2280 .anyerror_void_error_union,
2281 .error_set,
2282 .error_set_single,
2232 => unreachable,2283 => unreachable,
2233 };2284 };
2234 }2285 }
...@@ -2300,6 +2351,8 @@ pub const Type = extern union {...@@ -2300,6 +2351,8 @@ pub const Type = extern union {
2300 .@"anyframe",2351 .@"anyframe",
2301 .anyframe_T,2352 .anyframe_T,
2302 .anyerror_void_error_union,2353 .anyerror_void_error_union,
2354 .error_set,
2355 .error_set_single,
2303 => unreachable,2356 => unreachable,
2304 };2357 };
2305 }2358 }
...@@ -2371,6 +2424,8 @@ pub const Type = extern union {...@@ -2371,6 +2424,8 @@ pub const Type = extern union {
2371 .@"anyframe",2424 .@"anyframe",
2372 .anyframe_T,2425 .anyframe_T,
2373 .anyerror_void_error_union,2426 .anyerror_void_error_union,
2427 .error_set,
2428 .error_set_single,
2374 => unreachable,2429 => unreachable,
2375 };2430 };
2376 }2431 }
...@@ -2442,6 +2497,8 @@ pub const Type = extern union {...@@ -2442,6 +2497,8 @@ pub const Type = extern union {
2442 .@"anyframe",2497 .@"anyframe",
2443 .anyframe_T,2498 .anyframe_T,
2444 .anyerror_void_error_union,2499 .anyerror_void_error_union,
2500 .error_set,
2501 .error_set_single,
2445 => false,2502 => false,
2446 };2503 };
2447 }2504 }
...@@ -2497,6 +2554,8 @@ pub const Type = extern union {...@@ -2497,6 +2554,8 @@ pub const Type = extern union {
2497 .anyframe_T,2554 .anyframe_T,
2498 .@"anyframe",2555 .@"anyframe",
2499 .error_union,2556 .error_union,
2557 .error_set,
2558 .error_set_single,
2500 => return null,2559 => return null,
25012560
2502 .void => return Value.initTag(.void_value),2561 .void => return Value.initTag(.void_value),
...@@ -2604,6 +2663,8 @@ pub const Type = extern union {...@@ -2604,6 +2663,8 @@ pub const Type = extern union {
2604 .@"anyframe",2663 .@"anyframe",
2605 .anyframe_T,2664 .anyframe_T,
2606 .anyerror_void_error_union,2665 .anyerror_void_error_union,
2666 .error_set,
2667 .error_set_single,
2607 => return false,2668 => return false,
26082669
2609 .c_const_pointer,2670 .c_const_pointer,
...@@ -2687,6 +2748,8 @@ pub const Type = extern union {...@@ -2687,6 +2748,8 @@ pub const Type = extern union {
2687 optional_single_const_pointer,2748 optional_single_const_pointer,
2688 error_union,2749 error_union,
2689 anyframe_T,2750 anyframe_T,
2751 error_set,
2752 error_set_single,
26902753
2691 pub const last_no_payload_tag = Tag.const_slice_u8;2754 pub const last_no_payload_tag = Tag.const_slice_u8;
2692 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;2755 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
...@@ -2781,6 +2844,19 @@ pub const Type = extern union {...@@ -2781,6 +2844,19 @@ pub const Type = extern union {
27812844
2782 return_type: Type,2845 return_type: Type,
2783 };2846 };
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 };
2784 };2860 };
2785};2861};
27862862
src-self-hosted/value.zig+21-4
...@@ -381,11 +381,9 @@ pub const Value = extern union {...@@ -381,11 +381,9 @@ pub const Value = extern union {
381 }381 }
382382
383 /// Asserts that the value is representable as a type.383 /// 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 {
385 return switch (self.tag()) {385 return switch (self.tag()) {
386 .ty => self.cast(Payload.Ty).?.ty,386 .ty => self.cast(Payload.Ty).?.ty,
387 .int_type => @panic("TODO int type to type"),
388
389 .u8_type => Type.initTag(.u8),387 .u8_type => Type.initTag(.u8),
390 .i8_type => Type.initTag(.i8),388 .i8_type => Type.initTag(.i8),
391 .u16_type => Type.initTag(.u16),389 .u16_type => Type.initTag(.u16),
...@@ -427,7 +425,25 @@ pub const Value = extern union {...@@ -427,7 +425,25 @@ pub const Value = extern union {
427 .const_slice_u8_type => Type.initTag(.const_slice_u8),425 .const_slice_u8_type => Type.initTag(.const_slice_u8),
428 .enum_literal_type => Type.initTag(.enum_literal),426 .enum_literal_type => Type.initTag(.enum_literal),
429 .anyframe_type => Type.initTag(.@"anyframe"),427 .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
432 .undef,448 .undef,
433 .zero,449 .zero,
...@@ -1579,6 +1595,7 @@ pub const Value = extern union {...@@ -1579,6 +1595,7 @@ pub const Value = extern union {
15791595
1580 // TODO revisit this when we have the concept of the error tag type1596 // TODO revisit this when we have the concept of the error tag type
1581 fields: std.StringHashMapUnmanaged(u16),1597 fields: std.StringHashMapUnmanaged(u16),
1598 decl: *Module.Decl,
1582 };1599 };
15831600
1584 pub const Error = struct {1601 pub const Error = struct {
src-self-hosted/zir.zig+1-1
...@@ -2016,7 +2016,7 @@ const EmitZIR = struct {...@@ -2016,7 +2016,7 @@ const EmitZIR = struct {
2016 return self.emitUnnamedDecl(&as_inst.base);2016 return self.emitUnnamedDecl(&as_inst.base);
2017 },2017 },
2018 .Type => {2018 .Type => {
2019 const ty = typed_value.val.toType();2019 const ty = try typed_value.val.toType(&self.arena.allocator);
2020 return self.emitType(src, ty);2020 return self.emitType(src, ty);
2021 },2021 },
2022 .Fn => {2022 .Fn => {
src-self-hosted/zir_sema.zig+17-9
...@@ -150,7 +150,7 @@ pub fn analyzeBodyValueAsType(mod: *Module, block_scope: *Scope.Block, body: zir...@@ -150,7 +150,7 @@ pub fn analyzeBodyValueAsType(mod: *Module, block_scope: *Scope.Block, body: zir
150 for (block_scope.instructions.items) |inst| {150 for (block_scope.instructions.items) |inst| {
151 if (inst.castTag(.ret)) |ret| {151 if (inst.castTag(.ret)) |ret| {
152 const val = try mod.resolveConstValue(&block_scope.base, ret.operand);152 const val = try mod.resolveConstValue(&block_scope.base, ret.operand);
153 return val.toType();153 return val.toType(block_scope.base.arena());
154 } else {154 } else {
155 return mod.fail(&block_scope.base, inst.src, "unable to resolve comptime value", .{});155 return mod.fail(&block_scope.base, inst.src, "unable to resolve comptime value", .{});
156 }156 }
...@@ -275,7 +275,7 @@ fn resolveType(mod: *Module, scope: *Scope, old_inst: *zir.Inst) !Type {...@@ -275,7 +275,7 @@ fn resolveType(mod: *Module, scope: *Scope, old_inst: *zir.Inst) !Type {
275 const wanted_type = Type.initTag(.@"type");275 const wanted_type = Type.initTag(.@"type");
276 const coerced_inst = try mod.coerce(scope, wanted_type, new_inst);276 const coerced_inst = try mod.coerce(scope, wanted_type, new_inst);
277 const val = try mod.resolveConstValue(scope, coerced_inst);277 const val = try mod.resolveConstValue(scope, coerced_inst);
278 return val.toType();278 return val.toType(scope.arena());
279}279}
280280
281fn resolveInt(mod: *Module, scope: *Scope, old_inst: *zir.Inst, dest_type: Type) !u64 {281fn 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...@@ -745,7 +745,10 @@ fn analyzeInstErrorSet(mod: *Module, scope: *Scope, inst: *zir.Inst.ErrorSet) In
745 errdefer new_decl_arena.deinit();745 errdefer new_decl_arena.deinit();
746746
747 const payload = try scope.arena().create(Value.Payload.ErrorSet);747 const payload = try scope.arena().create(Value.Payload.ErrorSet);
748 payload.* = .{ .fields = .{} };748 payload.* = .{
749 .fields = .{},
750 .decl = undefined, // populated below
751 };
749 try payload.fields.ensureCapacity(&new_decl_arena.allocator, inst.positionals.fields.len);752 try payload.fields.ensureCapacity(&new_decl_arena.allocator, inst.positionals.fields.len);
750753
751 for (inst.positionals.fields) |field_name| {754 for (inst.positionals.fields) |field_name| {
...@@ -759,6 +762,7 @@ fn analyzeInstErrorSet(mod: *Module, scope: *Scope, inst: *zir.Inst.ErrorSet) In...@@ -759,6 +762,7 @@ fn analyzeInstErrorSet(mod: *Module, scope: *Scope, inst: *zir.Inst.ErrorSet) In
759 .ty = Type.initTag(.type),762 .ty = Type.initTag(.type),
760 .val = Value.initPayload(&payload.base),763 .val = Value.initPayload(&payload.base),
761 });764 });
765 payload.decl = new_decl;
762 return mod.analyzeDeclRef(scope, inst.base.src, new_decl);766 return mod.analyzeDeclRef(scope, inst.base.src, new_decl);
763}767}
764768
...@@ -939,18 +943,17 @@ fn analyzeInstFieldPtr(mod: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPtr...@@ -939,18 +943,17 @@ fn analyzeInstFieldPtr(mod: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPtr
939 _ = try mod.resolveConstValue(scope, object_ptr);943 _ = try mod.resolveConstValue(scope, object_ptr);
940 const result = try mod.analyzeDeref(scope, fieldptr.base.src, object_ptr, object_ptr.src);944 const result = try mod.analyzeDeref(scope, fieldptr.base.src, object_ptr, object_ptr.src);
941 const val = result.value().?;945 const val = result.value().?;
942 const child_type = val.toType();946 const child_type = try val.toType(scope.arena());
943 switch (child_type.zigTypeTag()) {947 switch (child_type.zigTypeTag()) {
944 .ErrorSet => {948 .ErrorSet => {
945 // TODO resolve inferred error sets949 // TODO resolve inferred error sets
946 const entry = if (val.cast(Value.Payload.ErrorSet)) |payload|950 const entry = if (val.cast(Value.Payload.ErrorSet)) |payload|
947 (payload.fields.getEntry(field_name) orelse951 (payload.fields.getEntry(field_name) orelse
948 return mod.fail(scope, fieldptr.base.src, "no error named '{}' in '{}'", .{ field_name, child_type })).*952 return mod.fail(scope, fieldptr.base.src, "no error named '{}' in '{}'", .{ field_name, child_type })).*
949 else953 else try mod.getErrorValue(field_name);
950 try mod.getErrorValue(field_name);
951954
952 const error_payload = try scope.arena().create(Value.Payload.Error);955 const error_payload = try scope.arena().create(Value.Payload.Error);
953 error_payload.* = .{ 956 error_payload.* = .{
954 .name = entry.key,957 .name = entry.key,
955 .value = entry.value,958 .value = entry.value,
956 };959 };
...@@ -958,9 +961,14 @@ fn analyzeInstFieldPtr(mod: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPtr...@@ -958,9 +961,14 @@ fn analyzeInstFieldPtr(mod: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPtr
958 const ref_payload = try scope.arena().create(Value.Payload.RefVal);961 const ref_payload = try scope.arena().create(Value.Payload.RefVal);
959 ref_payload.* = .{ .val = Value.initPayload(&error_payload.base) };962 ref_payload.* = .{ .val = Value.initPayload(&error_payload.base) };
960963
961 // TODO if this is accessing the global error set create a `error{field_name}` type964 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
962 return mod.constInst(scope, fieldptr.base.src, .{970 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),
964 .val = Value.initPayload(&ref_payload.base),972 .val = Value.initPayload(&ref_payload.base),
965 });973 });
966 },974 },