authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-20 12:09:07-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:53-07:00
log9ff514b6a35b7201f45f8bff31c61b4f8cfa7a7a
treedda74acc00690d1b3d31fd6e43d7ec0aa4acc882
parent7bf91fc79ac9e4eae575baf3a2ca9549bc3bf6c2

compiler: move error union types and error set types to InternPool

One change worth noting in this commit is that `module.global_error_set` is no longer kept strictly up-to-date. The previous code reserved integer error values when dealing with error set types, but this is no longer needed because the integer values are not needed for semantic analysis unless `@errorToInt` or `@intToError` are used and therefore may be assigned lazily.

21 files changed, 1195 insertions(+), 1582 deletions(-)

src/Air.zig+1-1
......@@ -1411,7 +1411,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: InternPool) Type {
14111411
14121412 .@"try" => {
14131413 const err_union_ty = air.typeOf(datas[inst].pl_op.operand, ip);
1414 return err_union_ty.errorUnionPayload();
1414 return ip.indexToKey(err_union_ty.ip_index).error_union_type.payload_type.toType();
14151415 },
14161416
14171417 .work_item_id,
src/InternPool.zig+160-16
......@@ -34,6 +34,14 @@ allocated_unions: std.SegmentedList(Module.Union, 0) = .{},
3434/// When a Union object is freed from `allocated_unions`, it is pushed into this stack.
3535unions_free_list: std.ArrayListUnmanaged(Module.Union.Index) = .{},
3636
37/// InferredErrorSet objects are stored in this data structure because:
38/// * They contain pointers such as the errors map and the set of other inferred error sets.
39/// * They need to be mutated after creation.
40allocated_inferred_error_sets: std.SegmentedList(Module.Fn.InferredErrorSet, 0) = .{},
41/// When a Struct object is freed from `allocated_inferred_error_sets`, it is
42/// pushed into this stack.
43inferred_error_sets_free_list: std.ArrayListUnmanaged(Module.Fn.InferredErrorSet.Index) = .{},
44
3745/// Some types such as enums, structs, and unions need to store mappings from field names
3846/// to field index, or value to field index. In such cases, they will store the underlying
3947/// field names and values directly, relying on one of these maps, stored separately,
......@@ -113,6 +121,12 @@ pub const NullTerminatedString = enum(u32) {
113121 return std.hash.uint32(@enumToInt(a));
114122 }
115123 };
124
125 /// Compare based on integer value alone, ignoring the string contents.
126 pub fn indexLessThan(ctx: void, a: NullTerminatedString, b: NullTerminatedString) bool {
127 _ = ctx;
128 return @enumToInt(a) < @enumToInt(b);
129 }
116130};
117131
118132/// An index into `string_bytes` which might be `none`.
......@@ -135,10 +149,7 @@ pub const Key = union(enum) {
135149 /// `anyframe->T`. The payload is the child type, which may be `none` to indicate
136150 /// `anyframe`.
137151 anyframe_type: Index,
138 error_union_type: struct {
139 error_set_type: Index,
140 payload_type: Index,
141 },
152 error_union_type: ErrorUnionType,
142153 simple_type: SimpleType,
143154 /// This represents a struct that has been explicitly declared in source code,
144155 /// or was created with `@Type`. It is unique and based on a declaration.
......@@ -152,6 +163,8 @@ pub const Key = union(enum) {
152163 opaque_type: OpaqueType,
153164 enum_type: EnumType,
154165 func_type: FuncType,
166 error_set_type: ErrorSetType,
167 inferred_error_set_type: Module.Fn.InferredErrorSet.Index,
155168
156169 /// Typed `undefined`. This will never be `none`; untyped `undefined` is represented
157170 /// via `simple_value` and has a named `Index` tag for it.
......@@ -183,6 +196,26 @@ pub const Key = union(enum) {
183196
184197 pub const IntType = std.builtin.Type.Int;
185198
199 pub const ErrorUnionType = struct {
200 error_set_type: Index,
201 payload_type: Index,
202 };
203
204 pub const ErrorSetType = struct {
205 /// Set of error names, sorted by null terminated string index.
206 names: []const NullTerminatedString,
207 /// This is ignored by `get` but will always be provided by `indexToKey`.
208 names_map: OptionalMapIndex = .none,
209
210 /// Look up field index based on field name.
211 pub fn nameIndex(self: ErrorSetType, ip: *const InternPool, name: NullTerminatedString) ?u32 {
212 const map = &ip.maps.items[@enumToInt(self.names_map.unwrap().?)];
213 const adapter: NullTerminatedString.Adapter = .{ .strings = self.names };
214 const field_index = map.getIndexAdapted(name, adapter) orelse return null;
215 return @intCast(u32, field_index);
216 }
217 };
218
186219 pub const PtrType = struct {
187220 elem_type: Index,
188221 sentinel: Index = .none,
......@@ -507,6 +540,7 @@ pub const Key = union(enum) {
507540 .un,
508541 .undef,
509542 .enum_tag,
543 .inferred_error_set_type,
510544 => |info| std.hash.autoHash(hasher, info),
511545
512546 .opaque_type => |opaque_type| std.hash.autoHash(hasher, opaque_type.decl),
......@@ -535,7 +569,7 @@ pub const Key = union(enum) {
535569 .ptr => |ptr| {
536570 std.hash.autoHash(hasher, ptr.ty);
537571 // Int-to-ptr pointers are hashed separately than decl-referencing pointers.
538 // This is sound due to pointer province rules.
572 // This is sound due to pointer provenance rules.
539573 switch (ptr.addr) {
540574 .int => |int| std.hash.autoHash(hasher, int),
541575 .decl => @panic("TODO"),
......@@ -547,6 +581,10 @@ pub const Key = union(enum) {
547581 for (aggregate.fields) |field| std.hash.autoHash(hasher, field);
548582 },
549583
584 .error_set_type => |error_set_type| {
585 for (error_set_type.names) |elem| std.hash.autoHash(hasher, elem);
586 },
587
550588 .anon_struct_type => |anon_struct_type| {
551589 for (anon_struct_type.types) |elem| std.hash.autoHash(hasher, elem);
552590 for (anon_struct_type.values) |elem| std.hash.autoHash(hasher, elem);
......@@ -726,6 +764,14 @@ pub const Key = union(enum) {
726764 std.mem.eql(Index, a_info.values, b_info.values) and
727765 std.mem.eql(NullTerminatedString, a_info.names, b_info.names);
728766 },
767 .error_set_type => |a_info| {
768 const b_info = b.error_set_type;
769 return std.mem.eql(NullTerminatedString, a_info.names, b_info.names);
770 },
771 .inferred_error_set_type => |a_info| {
772 const b_info = b.inferred_error_set_type;
773 return a_info == b_info;
774 },
729775
730776 .func_type => |a_info| {
731777 const b_info = b.func_type;
......@@ -752,6 +798,8 @@ pub const Key = union(enum) {
752798 .opt_type,
753799 .anyframe_type,
754800 .error_union_type,
801 .error_set_type,
802 .inferred_error_set_type,
755803 .simple_type,
756804 .struct_type,
757805 .union_type,
......@@ -1207,8 +1255,14 @@ pub const Tag = enum(u8) {
12071255 /// If the child type is `none`, the type is `anyframe`.
12081256 type_anyframe,
12091257 /// An error union type.
1210 /// data is payload to ErrorUnion.
1258 /// data is payload to `Key.ErrorUnionType`.
12111259 type_error_union,
1260 /// An error set type.
1261 /// data is payload to `ErrorSet`.
1262 type_error_set,
1263 /// The inferred error set type of a function.
1264 /// data is `Module.Fn.InferredErrorSet.Index`.
1265 type_inferred_error_set,
12121266 /// An enum type with auto-numbered tag values.
12131267 /// The enum is exhaustive.
12141268 /// data is payload index to `EnumAuto`.
......@@ -1355,6 +1409,12 @@ pub const Tag = enum(u8) {
13551409 aggregate,
13561410};
13571411
1412/// Trailing:
1413/// 0. name: NullTerminatedString for each names_len
1414pub const ErrorSet = struct {
1415 names_len: u32,
1416};
1417
13581418/// Trailing:
13591419/// 0. param_type: Index for each params_len
13601420pub const TypeFunction = struct {
......@@ -1539,11 +1599,6 @@ pub const Array = struct {
15391599 }
15401600};
15411601
1542pub const ErrorUnion = struct {
1543 error_set_type: Index,
1544 payload_type: Index,
1545};
1546
15471602/// Trailing:
15481603/// 0. field name: NullTerminatedString for each fields_len; declaration order
15491604/// 1. tag value: Index for each fields_len; declaration order
......@@ -1719,6 +1774,9 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
17191774 ip.unions_free_list.deinit(gpa);
17201775 ip.allocated_unions.deinit(gpa);
17211776
1777 ip.inferred_error_sets_free_list.deinit(gpa);
1778 ip.allocated_inferred_error_sets.deinit(gpa);
1779
17221780 for (ip.maps.items) |*map| map.deinit(gpa);
17231781 ip.maps.deinit(gpa);
17241782
......@@ -1798,7 +1856,18 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
17981856 .type_optional => .{ .opt_type = @intToEnum(Index, data) },
17991857 .type_anyframe => .{ .anyframe_type = @intToEnum(Index, data) },
18001858
1801 .type_error_union => @panic("TODO"),
1859 .type_error_union => .{ .error_union_type = ip.extraData(Key.ErrorUnionType, data) },
1860 .type_error_set => {
1861 const error_set = ip.extraDataTrail(ErrorSet, data);
1862 const names_len = error_set.data.names_len;
1863 const names = ip.extra.items[error_set.end..][0..names_len];
1864 return .{ .error_set_type = .{
1865 .names = @ptrCast([]const NullTerminatedString, names),
1866 } };
1867 },
1868 .type_inferred_error_set => .{
1869 .inferred_error_set_type = @intToEnum(Module.Fn.InferredErrorSet.Index, data),
1870 },
18021871
18031872 .type_opaque => .{ .opaque_type = ip.extraData(Key.OpaqueType, data) },
18041873 .type_struct => {
......@@ -2179,11 +2248,29 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
21792248 .error_union_type => |error_union_type| {
21802249 ip.items.appendAssumeCapacity(.{
21812250 .tag = .type_error_union,
2182 .data = try ip.addExtra(gpa, ErrorUnion{
2183 .error_set_type = error_union_type.error_set_type,
2184 .payload_type = error_union_type.payload_type,
2251 .data = try ip.addExtra(gpa, error_union_type),
2252 });
2253 },
2254 .error_set_type => |error_set_type| {
2255 assert(error_set_type.names_map == .none);
2256 assert(std.sort.isSorted(NullTerminatedString, error_set_type.names, {}, NullTerminatedString.indexLessThan));
2257 const names_map = try ip.addMap(gpa);
2258 try addStringsToMap(ip, gpa, names_map, error_set_type.names);
2259 const names_len = @intCast(u32, error_set_type.names.len);
2260 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(ErrorSet).Struct.fields.len + names_len);
2261 ip.items.appendAssumeCapacity(.{
2262 .tag = .type_error_set,
2263 .data = ip.addExtraAssumeCapacity(ErrorSet{
2264 .names_len = names_len,
21852265 }),
21862266 });
2267 ip.extra.appendSliceAssumeCapacity(@ptrCast([]const u32, error_set_type.names));
2268 },
2269 .inferred_error_set_type => |ies_index| {
2270 ip.items.appendAssumeCapacity(.{
2271 .tag = .type_inferred_error_set,
2272 .data = @enumToInt(ies_index),
2273 });
21872274 },
21882275 .simple_type => |simple_type| {
21892276 ip.items.appendAssumeCapacity(.{
......@@ -3192,12 +3279,26 @@ pub fn indexToFuncType(ip: InternPool, val: Index) ?Key.FuncType {
31923279 }
31933280}
31943281
3282pub fn indexToInferredErrorSetType(ip: InternPool, val: Index) Module.Fn.InferredErrorSet.OptionalIndex {
3283 assert(val != .none);
3284 const tags = ip.items.items(.tag);
3285 if (tags[@enumToInt(val)] != .type_inferred_error_set) return .none;
3286 const datas = ip.items.items(.data);
3287 return @intToEnum(Module.Fn.InferredErrorSet.Index, datas[@enumToInt(val)]).toOptional();
3288}
3289
31953290pub fn isOptionalType(ip: InternPool, ty: Index) bool {
31963291 const tags = ip.items.items(.tag);
31973292 if (ty == .none) return false;
31983293 return tags[@enumToInt(ty)] == .type_optional;
31993294}
32003295
3296pub fn isInferredErrorSetType(ip: InternPool, ty: Index) bool {
3297 const tags = ip.items.items(.tag);
3298 assert(ty != .none);
3299 return tags[@enumToInt(ty)] == .type_inferred_error_set;
3300}
3301
32013302pub fn dump(ip: InternPool) void {
32023303 dumpFallible(ip, std.heap.page_allocator) catch return;
32033304}
......@@ -3258,7 +3359,12 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void {
32583359 .type_slice => 0,
32593360 .type_optional => 0,
32603361 .type_anyframe => 0,
3261 .type_error_union => @sizeOf(ErrorUnion),
3362 .type_error_union => @sizeOf(Key.ErrorUnionType),
3363 .type_error_set => b: {
3364 const info = ip.extraData(ErrorSet, data);
3365 break :b @sizeOf(ErrorSet) + (@sizeOf(u32) * info.names_len);
3366 },
3367 .type_inferred_error_set => @sizeOf(Module.Fn.InferredErrorSet),
32623368 .type_enum_explicit, .type_enum_nonexhaustive => @sizeOf(EnumExplicit),
32633369 .type_enum_auto => @sizeOf(EnumAuto),
32643370 .type_opaque => @sizeOf(Key.OpaqueType),
......@@ -3359,6 +3465,14 @@ pub fn unionPtr(ip: *InternPool, index: Module.Union.Index) *Module.Union {
33593465 return ip.allocated_unions.at(@enumToInt(index));
33603466}
33613467
3468pub fn inferredErrorSetPtr(ip: *InternPool, index: Module.Fn.InferredErrorSet.Index) *Module.Fn.InferredErrorSet {
3469 return ip.allocated_inferred_error_sets.at(@enumToInt(index));
3470}
3471
3472pub fn inferredErrorSetPtrConst(ip: InternPool, index: Module.Fn.InferredErrorSet.Index) *const Module.Fn.InferredErrorSet {
3473 return ip.allocated_inferred_error_sets.at(@enumToInt(index));
3474}
3475
33623476pub fn createStruct(
33633477 ip: *InternPool,
33643478 gpa: Allocator,
......@@ -3397,6 +3511,25 @@ pub fn destroyUnion(ip: *InternPool, gpa: Allocator, index: Module.Union.Index)
33973511 };
33983512}
33993513
3514pub fn createInferredErrorSet(
3515 ip: *InternPool,
3516 gpa: Allocator,
3517 initialization: Module.Fn.InferredErrorSet,
3518) Allocator.Error!Module.Fn.InferredErrorSet.Index {
3519 if (ip.inferred_error_sets_free_list.popOrNull()) |index| return index;
3520 const ptr = try ip.allocated_inferred_error_sets.addOne(gpa);
3521 ptr.* = initialization;
3522 return @intToEnum(Module.Fn.InferredErrorSet.Index, ip.allocated_inferred_error_sets.len - 1);
3523}
3524
3525pub fn destroyInferredErrorSet(ip: *InternPool, gpa: Allocator, index: Module.Fn.InferredErrorSet.Index) void {
3526 ip.inferredErrorSetPtr(index).* = undefined;
3527 ip.inferred_error_sets_free_list.append(gpa, index) catch {
3528 // In order to keep `destroyInferredErrorSet` a non-fallible function, we ignore memory
3529 // allocation failures here, instead leaking the InferredErrorSet until garbage collection.
3530 };
3531}
3532
34003533pub fn getOrPutString(
34013534 ip: *InternPool,
34023535 gpa: Allocator,
......@@ -3459,3 +3592,14 @@ pub fn aggregateTypeLen(ip: InternPool, ty: Index) u64 {
34593592 else => unreachable,
34603593 };
34613594}
3595
3596pub fn isNoReturn(ip: InternPool, ty: InternPool.Index) bool {
3597 return switch (ty) {
3598 .noreturn_type => true,
3599 else => switch (ip.indexToKey(ty)) {
3600 .error_set_type => |error_set_type| error_set_type.names.len == 0,
3601 .enum_type => |enum_type| enum_type.names.len == 0,
3602 else => false,
3603 },
3604 };
3605}
src/Liveness.zig+1-1
......@@ -1416,7 +1416,7 @@ fn analyzeInstBlock(
14161416
14171417 // If the block is noreturn, block deaths not only aren't useful, they're impossible to
14181418 // find: there could be more stuff alive after the block than before it!
1419 if (!a.air.getRefType(ty_pl.ty).isNoReturn()) {
1419 if (!a.intern_pool.isNoReturn(a.air.getRefType(ty_pl.ty).ip_index)) {
14201420 // The block kills the difference in the live sets
14211421 const block_scope = data.block_scopes.get(inst).?;
14221422 const num_deaths = data.live_set.count() - block_scope.live_set.count();
src/Liveness/Verify.zig+1-1
......@@ -453,7 +453,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
453453
454454 for (block_liveness.deaths) |death| try self.verifyDeath(inst, death);
455455
456 if (block_ty.isNoReturn()) {
456 if (ip.isNoReturn(block_ty.toIntern())) {
457457 assert(!self.blocks.contains(inst));
458458 } else {
459459 var live = self.blocks.fetchRemove(inst).?.value;
src/Module.zig+94-75
......@@ -960,38 +960,6 @@ pub const EmitH = struct {
960960 fwd_decl: ArrayListUnmanaged(u8) = .{},
961961};
962962
963/// Represents the data that an explicit error set syntax provides.
964pub const ErrorSet = struct {
965 /// The Decl that corresponds to the error set itself.
966 owner_decl: Decl.Index,
967 /// The string bytes are stored in the owner Decl arena.
968 /// These must be in sorted order. See sortNames.
969 names: NameMap,
970
971 pub const NameMap = std.StringArrayHashMapUnmanaged(void);
972
973 pub fn srcLoc(self: ErrorSet, mod: *Module) SrcLoc {
974 const owner_decl = mod.declPtr(self.owner_decl);
975 return .{
976 .file_scope = owner_decl.getFileScope(mod),
977 .parent_decl_node = owner_decl.src_node,
978 .lazy = LazySrcLoc.nodeOffset(0),
979 };
980 }
981
982 /// sort the NameMap. This should be called whenever the map is modified.
983 /// alloc should be the allocator used for the NameMap data.
984 pub fn sortNames(names: *NameMap) void {
985 const Context = struct {
986 keys: [][]const u8,
987 pub fn lessThan(ctx: @This(), a_index: usize, b_index: usize) bool {
988 return std.mem.lessThan(u8, ctx.keys[a_index], ctx.keys[b_index]);
989 }
990 };
991 names.sort(Context{ .keys = names.keys() });
992 }
993};
994
995963pub const PropertyBoolean = enum { no, yes, unknown, wip };
996964
997965/// Represents the data that a struct declaration provides.
......@@ -1530,13 +1498,6 @@ pub const Fn = struct {
15301498 is_noinline: bool,
15311499 calls_or_awaits_errorable_fn: bool = false,
15321500
1533 /// Any inferred error sets that this function owns, both its own inferred error set and
1534 /// inferred error sets of any inline/comptime functions called. Not to be confused
1535 /// with inferred error sets of generic instantiations of this function, which are
1536 /// *not* tracked here - they are tracked in the new `Fn` object created for the
1537 /// instantiations.
1538 inferred_error_sets: InferredErrorSetList = .{},
1539
15401501 pub const Analysis = enum {
15411502 /// This function has not yet undergone analysis, because we have not
15421503 /// seen a potential runtime call. It may be analyzed in future.
......@@ -1568,10 +1529,10 @@ pub const Fn = struct {
15681529 /// direct additions via `return error.Foo;`, and possibly also errors that
15691530 /// are returned from any dependent functions. When the inferred error set is
15701531 /// fully resolved, this map contains all the errors that the function might return.
1571 errors: ErrorSet.NameMap = .{},
1532 errors: NameMap = .{},
15721533
15731534 /// Other inferred error sets which this inferred error set should include.
1574 inferred_error_sets: std.AutoArrayHashMapUnmanaged(*InferredErrorSet, void) = .{},
1535 inferred_error_sets: std.AutoArrayHashMapUnmanaged(InferredErrorSet.Index, void) = .{},
15751536
15761537 /// Whether the function returned anyerror. This is true if either of
15771538 /// the dependent functions returns anyerror.
......@@ -1581,51 +1542,59 @@ pub const Fn = struct {
15811542 /// can skip resolving any dependents of this inferred error set.
15821543 is_resolved: bool = false,
15831544
1584 pub fn addErrorSet(self: *InferredErrorSet, gpa: Allocator, err_set_ty: Type) !void {
1545 pub const NameMap = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void);
1546
1547 pub const Index = enum(u32) {
1548 _,
1549
1550 pub fn toOptional(i: Index) OptionalIndex {
1551 return @intToEnum(OptionalIndex, @enumToInt(i));
1552 }
1553 };
1554
1555 pub const OptionalIndex = enum(u32) {
1556 none = std.math.maxInt(u32),
1557 _,
1558
1559 pub fn init(oi: ?Index) OptionalIndex {
1560 return @intToEnum(OptionalIndex, @enumToInt(oi orelse return .none));
1561 }
1562
1563 pub fn unwrap(oi: OptionalIndex) ?Index {
1564 if (oi == .none) return null;
1565 return @intToEnum(Index, @enumToInt(oi));
1566 }
1567 };
1568
1569 pub fn addErrorSet(
1570 self: *InferredErrorSet,
1571 err_set_ty: Type,
1572 ip: *InternPool,
1573 gpa: Allocator,
1574 ) !void {
15851575 switch (err_set_ty.ip_index) {
15861576 .anyerror_type => {
15871577 self.is_anyerror = true;
15881578 },
1589 .none => switch (err_set_ty.tag()) {
1590 .error_set => {
1591 const names = err_set_ty.castTag(.error_set).?.data.names.keys();
1592 for (names) |name| {
1579 else => switch (ip.indexToKey(err_set_ty.ip_index)) {
1580 .error_set_type => |error_set_type| {
1581 for (error_set_type.names) |name| {
15931582 try self.errors.put(gpa, name, {});
15941583 }
15951584 },
1596 .error_set_single => {
1597 const name = err_set_ty.castTag(.error_set_single).?.data;
1598 try self.errors.put(gpa, name, {});
1599 },
1600 .error_set_inferred => {
1601 const ies = err_set_ty.castTag(.error_set_inferred).?.data;
1602 try self.inferred_error_sets.put(gpa, ies, {});
1603 },
1604 .error_set_merged => {
1605 const names = err_set_ty.castTag(.error_set_merged).?.data.keys();
1606 for (names) |name| {
1607 try self.errors.put(gpa, name, {});
1608 }
1585 .inferred_error_set_type => |ies_index| {
1586 try self.inferred_error_sets.put(gpa, ies_index, {});
16091587 },
16101588 else => unreachable,
16111589 },
1612 else => @panic("TODO"),
16131590 }
16141591 }
16151592 };
16161593
1617 pub const InferredErrorSetList = std.SinglyLinkedList(InferredErrorSet);
1618 pub const InferredErrorSetListNode = InferredErrorSetList.Node;
1619
1594 /// TODO: remove this function
16201595 pub fn deinit(func: *Fn, gpa: Allocator) void {
1621 var it = func.inferred_error_sets.first;
1622 while (it) |node| {
1623 const next = node.next;
1624 node.data.errors.deinit(gpa);
1625 node.data.inferred_error_sets.deinit(gpa);
1626 gpa.destroy(node);
1627 it = next;
1628 }
1596 _ = func;
1597 _ = gpa;
16291598 }
16301599
16311600 pub fn isAnytypeParam(func: Fn, mod: *Module, index: u32) bool {
......@@ -3508,6 +3477,10 @@ pub fn structPtr(mod: *Module, index: Struct.Index) *Struct {
35083477 return mod.intern_pool.structPtr(index);
35093478}
35103479
3480pub fn inferredErrorSetPtr(mod: *Module, index: Fn.InferredErrorSet.Index) *Fn.InferredErrorSet {
3481 return mod.intern_pool.inferredErrorSetPtr(index);
3482}
3483
35113484/// This one accepts an index from the InternPool and asserts that it is not
35123485/// the anonymous empty struct type.
35133486pub fn structPtrUnwrap(mod: *Module, index: Struct.OptionalIndex) ?*Struct {
......@@ -4722,7 +4695,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
47224695 decl_tv.ty.fmt(mod),
47234696 });
47244697 }
4725 const ty = try decl_tv.val.toType().copy(decl_arena_allocator);
4698 const ty = decl_tv.val.toType();
47264699 if (ty.getNamespace(mod) == null) {
47274700 return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(mod)});
47284701 }
......@@ -4756,7 +4729,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
47564729 }
47574730 decl.clearValues(mod);
47584731
4759 decl.ty = try decl_tv.ty.copy(decl_arena_allocator);
4732 decl.ty = decl_tv.ty;
47604733 decl.val = try decl_tv.val.copy(decl_arena_allocator);
47614734 // linksection, align, and addrspace were already set by Sema
47624735 decl.has_tv = true;
......@@ -4823,7 +4796,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
48234796 },
48244797 }
48254798
4826 decl.ty = try decl_tv.ty.copy(decl_arena_allocator);
4799 decl.ty = decl_tv.ty;
48274800 decl.val = try decl_tv.val.copy(decl_arena_allocator);
48284801 decl.@"align" = blk: {
48294802 const align_ref = decl.zirAlignRef(mod);
......@@ -6599,7 +6572,7 @@ pub fn populateTestFunctions(
65996572 // This copy accesses the old Decl Type/Value so it must be done before `clearValues`.
66006573 const new_ty = try Type.ptr(arena, mod, .{
66016574 .size = .Slice,
6602 .pointee_type = try tmp_test_fn_ty.copy(arena),
6575 .pointee_type = tmp_test_fn_ty,
66036576 .mutable = false,
66046577 .@"addrspace" = .generic,
66056578 });
......@@ -6877,6 +6850,42 @@ pub fn anyframeType(mod: *Module, payload_ty: Type) Allocator.Error!Type {
68776850 return (try intern(mod, .{ .anyframe_type = payload_ty.toIntern() })).toType();
68786851}
68796852
6853pub fn errorUnionType(mod: *Module, error_set_ty: Type, payload_ty: Type) Allocator.Error!Type {
6854 return (try intern(mod, .{ .error_union_type = .{
6855 .error_set_type = error_set_ty.toIntern(),
6856 .payload_type = payload_ty.toIntern(),
6857 } })).toType();
6858}
6859
6860pub fn singleErrorSetType(mod: *Module, name: []const u8) Allocator.Error!Type {
6861 const gpa = mod.gpa;
6862 const ip = &mod.intern_pool;
6863 return singleErrorSetTypeNts(mod, try ip.getOrPutString(gpa, name));
6864}
6865
6866pub fn singleErrorSetTypeNts(mod: *Module, name: InternPool.NullTerminatedString) Allocator.Error!Type {
6867 const gpa = mod.gpa;
6868 const ip = &mod.intern_pool;
6869 const names = [1]InternPool.NullTerminatedString{name};
6870 const i = try ip.get(gpa, .{ .error_set_type = .{ .names = &names } });
6871 return i.toType();
6872}
6873
6874/// Sorts `names` in place.
6875pub fn errorSetFromUnsortedNames(
6876 mod: *Module,
6877 names: []InternPool.NullTerminatedString,
6878) Allocator.Error!Type {
6879 std.mem.sort(
6880 InternPool.NullTerminatedString,
6881 names,
6882 {},
6883 InternPool.NullTerminatedString.indexLessThan,
6884 );
6885 const new_ty = try mod.intern(.{ .error_set_type = .{ .names = names } });
6886 return new_ty.toType();
6887}
6888
68806889/// Supports optionals in addition to pointers.
68816890pub fn ptrIntValue(mod: *Module, ty: Type, x: u64) Allocator.Error!Value {
68826891 if (ty.isPtrLikeOptional(mod)) {
......@@ -7240,6 +7249,16 @@ pub fn typeToFunc(mod: *Module, ty: Type) ?InternPool.Key.FuncType {
72407249 return mod.intern_pool.indexToFuncType(ty.ip_index);
72417250}
72427251
7252pub fn typeToInferredErrorSet(mod: *Module, ty: Type) ?*Fn.InferredErrorSet {
7253 const index = typeToInferredErrorSetIndex(mod, ty).unwrap() orelse return null;
7254 return mod.inferredErrorSetPtr(index);
7255}
7256
7257pub fn typeToInferredErrorSetIndex(mod: *Module, ty: Type) Fn.InferredErrorSet.OptionalIndex {
7258 if (ty.ip_index == .none) return .none;
7259 return mod.intern_pool.indexToInferredErrorSetType(ty.ip_index);
7260}
7261
72437262pub fn fieldSrcLoc(mod: *Module, owner_decl_index: Decl.Index, query: FieldSrcQuery) SrcLoc {
72447263 @setCold(true);
72457264 const owner_decl = mod.declPtr(owner_decl_index);
src/Sema.zig+377-444
......@@ -825,12 +825,13 @@ pub fn analyzeBodyBreak(
825825 block: *Block,
826826 body: []const Zir.Inst.Index,
827827) CompileError!?BreakData {
828 const mod = sema.mod;
828829 const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
829830 error.ComptimeBreak => sema.comptime_break_inst,
830831 else => |e| return e,
831832 };
832833 if (block.instructions.items.len != 0 and
833 sema.typeOf(Air.indexToRef(block.instructions.items[block.instructions.items.len - 1])).isNoReturn())
834 sema.typeOf(Air.indexToRef(block.instructions.items[block.instructions.items.len - 1])).isNoReturn(mod))
834835 return null;
835836 const break_data = sema.code.instructions.items(.data)[break_inst].@"break";
836837 const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;
......@@ -1701,7 +1702,7 @@ fn analyzeBodyInner(
17011702 break :blk Air.Inst.Ref.void_value;
17021703 },
17031704 };
1704 if (sema.typeOf(air_inst).isNoReturn())
1705 if (sema.typeOf(air_inst).isNoReturn(mod))
17051706 break always_noreturn;
17061707 map.putAssumeCapacity(inst, air_inst);
17071708 i += 1;
......@@ -1796,8 +1797,7 @@ fn analyzeAsType(
17961797 const wanted_type = Type.type;
17971798 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
17981799 const val = try sema.resolveConstValue(block, src, coerced_inst, "types must be comptime-known");
1799 const ty = val.toType();
1800 return ty.copy(sema.arena);
1800 return val.toType();
18011801}
18021802
18031803pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void {
......@@ -2004,7 +2004,7 @@ fn resolveMaybeUndefValAllowVariablesMaybeRuntime(
20042004 if (val.isPtrToThreadLocal(sema.mod)) make_runtime.* = true;
20052005 return val;
20062006 },
2007 .const_ty => return try air_datas[i].ty.toValue(sema.arena),
2007 .const_ty => return air_datas[i].ty.toValue(),
20082008 .interned => return air_datas[i].interned.toValue(),
20092009 else => return null,
20102010 }
......@@ -2131,7 +2131,7 @@ fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, objec
21312131 };
21322132 return sema.failWithOwnedErrorMsg(msg);
21332133 } else if (inner_ty.zigTypeTag(mod) == .ErrorUnion) err: {
2134 const child_ty = inner_ty.errorUnionPayload();
2134 const child_ty = inner_ty.errorUnionPayload(mod);
21352135 if (!typeSupportsFieldAccess(mod, child_ty, field_name)) break :err;
21362136 const msg = msg: {
21372137 const msg = try sema.errMsg(block, src, "error union type '{}' does not support field access", .{object_ty.fmt(sema.mod)});
......@@ -2473,7 +2473,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
24732473 var anon_decl = try block.startAnonDecl();
24742474 defer anon_decl.deinit();
24752475 iac.data.decl_index = try anon_decl.finish(
2476 try pointee_ty.copy(anon_decl.arena()),
2476 pointee_ty,
24772477 Value.undef,
24782478 iac.data.alignment,
24792479 );
......@@ -3250,47 +3250,35 @@ fn zirErrorSetDecl(
32503250 const tracy = trace(@src());
32513251 defer tracy.end();
32523252
3253 const mod = sema.mod;
32533254 const gpa = sema.gpa;
32543255 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
32553256 const src = inst_data.src();
32563257 const extra = sema.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index);
32573258
3258 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
3259 errdefer new_decl_arena.deinit();
3260 const new_decl_arena_allocator = new_decl_arena.allocator();
3261
3262 const error_set = try new_decl_arena_allocator.create(Module.ErrorSet);
3263 const error_set_ty = try Type.Tag.error_set.create(new_decl_arena_allocator, error_set);
3264 const error_set_val = try Value.Tag.ty.create(new_decl_arena_allocator, error_set_ty);
3265 const mod = sema.mod;
3266 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
3267 .ty = Type.type,
3268 .val = error_set_val,
3269 }, name_strategy, "error", inst);
3270 const new_decl = mod.declPtr(new_decl_index);
3271 new_decl.owns_tv = true;
3272 errdefer mod.abortAnonDecl(new_decl_index);
3273
3274 var names = Module.ErrorSet.NameMap{};
3275 try names.ensureUnusedCapacity(new_decl_arena_allocator, extra.data.fields_len);
3259 var names: Module.Fn.InferredErrorSet.NameMap = .{};
3260 try names.ensureUnusedCapacity(sema.arena, extra.data.fields_len);
32763261
32773262 var extra_index = @intCast(u32, extra.end);
32783263 const extra_index_end = extra_index + (extra.data.fields_len * 2);
32793264 while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string
32803265 const str_index = sema.code.extra[extra_index];
3281 const kv = try mod.getErrorValue(sema.code.nullTerminatedString(str_index));
3282 const result = names.getOrPutAssumeCapacity(kv.key);
3266 const name = sema.code.nullTerminatedString(str_index);
3267 const name_ip = try mod.intern_pool.getOrPutString(gpa, name);
3268 const result = names.getOrPutAssumeCapacity(name_ip);
32833269 assert(!result.found_existing); // verified in AstGen
32843270 }
32853271
3286 // names must be sorted.
3287 Module.ErrorSet.sortNames(&names);
3272 const error_set_ty = try mod.errorSetFromUnsortedNames(names.keys());
3273
3274 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
3275 .ty = Type.type,
3276 .val = error_set_ty.toValue(),
3277 }, name_strategy, "error", inst);
3278 const new_decl = mod.declPtr(new_decl_index);
3279 new_decl.owns_tv = true;
3280 errdefer mod.abortAnonDecl(new_decl_index);
32883281
3289 error_set.* = .{
3290 .owner_decl = new_decl_index,
3291 .names = names,
3292 };
3293 try new_decl.finalizeNewArena(&new_decl_arena);
32943282 return sema.analyzeDeclVal(block, src, new_decl_index);
32953283}
32963284
......@@ -3407,7 +3395,7 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index
34073395 else
34083396 operand_ty;
34093397 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) return;
3410 const payload_ty = err_union_ty.errorUnionPayload().zigTypeTag(mod);
3398 const payload_ty = err_union_ty.errorUnionPayload(mod).zigTypeTag(mod);
34113399 if (payload_ty != .Void and payload_ty != .NoReturn) {
34123400 const msg = msg: {
34133401 const msg = try sema.errMsg(block, src, "error union payload is ignored", .{});
......@@ -3590,7 +3578,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
35903578 var anon_decl = try block.startAnonDecl();
35913579 defer anon_decl.deinit();
35923580 return sema.analyzeDeclRef(try anon_decl.finish(
3593 try elem_ty.copy(anon_decl.arena()),
3581 elem_ty,
35943582 try store_val.copy(anon_decl.arena()),
35953583 ptr_info.@"align",
35963584 ));
......@@ -3722,7 +3710,6 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
37223710 const var_is_mut = switch (sema.typeOf(ptr).tag()) {
37233711 .inferred_alloc_const => false,
37243712 .inferred_alloc_mut => true,
3725 else => unreachable,
37263713 };
37273714 const target = sema.mod.getTarget();
37283715
......@@ -3733,7 +3720,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
37333720 try sema.mod.declareDeclDependency(sema.owner_decl_index, decl_index);
37343721
37353722 const decl = sema.mod.declPtr(decl_index);
3736 const final_elem_ty = try decl.ty.copy(sema.arena);
3723 const final_elem_ty = decl.ty;
37373724 const final_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
37383725 .pointee_type = final_elem_ty,
37393726 .mutable = true,
......@@ -3833,7 +3820,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
38333820 var anon_decl = try block.startAnonDecl();
38343821 defer anon_decl.deinit();
38353822 const new_decl_index = try anon_decl.finish(
3836 try final_elem_ty.copy(anon_decl.arena()),
3823 final_elem_ty,
38373824 try store_val.copy(anon_decl.arena()),
38383825 inferred_alloc.data.alignment,
38393826 );
......@@ -5042,7 +5029,7 @@ fn storeToInferredAllocComptime(
50425029 var anon_decl = try block.startAnonDecl();
50435030 defer anon_decl.deinit();
50445031 iac.data.decl_index = try anon_decl.finish(
5045 try operand_ty.copy(anon_decl.arena()),
5032 operand_ty,
50465033 try operand_val.copy(anon_decl.arena()),
50475034 iac.data.alignment,
50485035 );
......@@ -5286,6 +5273,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
52865273 const tracy = trace(@src());
52875274 defer tracy.end();
52885275
5276 const mod = sema.mod;
52895277 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
52905278 const src = inst_data.src();
52915279 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
......@@ -5335,7 +5323,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
53355323 try sema.analyzeBody(&loop_block, body);
53365324
53375325 const loop_block_len = loop_block.instructions.items.len;
5338 if (loop_block_len > 0 and sema.typeOf(Air.indexToRef(loop_block.instructions.items[loop_block_len - 1])).isNoReturn()) {
5326 if (loop_block_len > 0 and sema.typeOf(Air.indexToRef(loop_block.instructions.items[loop_block_len - 1])).isNoReturn(mod)) {
53395327 // If the loop ended with a noreturn terminator, then there is no way for it to loop,
53405328 // so we can just use the block instead.
53415329 try child_block.instructions.appendSlice(gpa, loop_block.instructions.items);
......@@ -5588,7 +5576,7 @@ fn analyzeBlockBody(
55885576
55895577 // Blocks must terminate with noreturn instruction.
55905578 assert(child_block.instructions.items.len != 0);
5591 assert(sema.typeOf(Air.indexToRef(child_block.instructions.items[child_block.instructions.items.len - 1])).isNoReturn());
5579 assert(sema.typeOf(Air.indexToRef(child_block.instructions.items[child_block.instructions.items.len - 1])).isNoReturn(mod));
55925580
55935581 if (merges.results.items.len == 0) {
55945582 // No need for a block instruction. We can put the new instructions
......@@ -5755,7 +5743,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
57555743 var anon_decl = try block.startAnonDecl();
57565744 defer anon_decl.deinit();
57575745 break :blk try anon_decl.finish(
5758 try operand.ty.copy(anon_decl.arena()),
5746 operand.ty,
57595747 try operand.val.copy(anon_decl.arena()),
57605748 0,
57615749 );
......@@ -6434,7 +6422,7 @@ fn zirCall(
64346422 };
64356423
64366424 const return_ty = sema.typeOf(call_inst);
6437 if (modifier != .always_tail and return_ty.isNoReturn())
6425 if (modifier != .always_tail and return_ty.isNoReturn(mod))
64386426 return call_inst; // call to "fn(...) noreturn", don't pop
64396427
64406428 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only
......@@ -6957,17 +6945,11 @@ fn analyzeCall(
69576945 // Create a fresh inferred error set type for inline/comptime calls.
69586946 const fn_ret_ty = blk: {
69596947 if (module_fn.hasInferredErrorSet(mod)) {
6960 const node = try sema.gpa.create(Module.Fn.InferredErrorSetListNode);
6961 node.data = .{ .func = module_fn };
6962 if (parent_func) |some| {
6963 some.inferred_error_sets.prepend(node);
6964 }
6965
6966 const error_set_ty = try Type.Tag.error_set_inferred.create(sema.arena, &node.data);
6967 break :blk try Type.Tag.error_union.create(sema.arena, .{
6968 .error_set = error_set_ty,
6969 .payload = bare_return_type,
6948 const ies_index = try mod.intern_pool.createInferredErrorSet(gpa, .{
6949 .func = module_fn,
69706950 });
6951 const error_set_ty = try mod.intern(.{ .inferred_error_set_type = ies_index });
6952 break :blk try mod.errorUnionType(error_set_ty.toType(), bare_return_type);
69716953 }
69726954 break :blk bare_return_type;
69736955 };
......@@ -7843,21 +7825,21 @@ fn resolveGenericInstantiationType(
78437825 // `GenericCallAdapter.eql` as well as function body analysis.
78447826 // Whether it is anytype is communicated by `isAnytypeParam`.
78457827 const arg = child_sema.inst_map.get(inst).?;
7846 const copied_arg_ty = try child_sema.typeOf(arg).copy(new_decl_arena_allocator);
7828 const arg_ty = child_sema.typeOf(arg);
78477829
7848 if (try sema.typeRequiresComptime(copied_arg_ty)) {
7830 if (try sema.typeRequiresComptime(arg_ty)) {
78497831 is_comptime = true;
78507832 }
78517833
78527834 if (is_comptime) {
78537835 const arg_val = (child_sema.resolveMaybeUndefValAllowVariables(arg) catch unreachable).?;
78547836 child_sema.comptime_args[arg_i] = .{
7855 .ty = copied_arg_ty,
7837 .ty = arg_ty,
78567838 .val = try arg_val.copy(new_decl_arena_allocator),
78577839 };
78587840 } else {
78597841 child_sema.comptime_args[arg_i] = .{
7860 .ty = copied_arg_ty,
7842 .ty = arg_ty,
78617843 .val = Value.generic_poison,
78627844 };
78637845 }
......@@ -7868,7 +7850,7 @@ fn resolveGenericInstantiationType(
78687850 try wip_captures.finalize();
78697851
78707852 // Populate the Decl ty/val with the function and its type.
7871 new_decl.ty = try child_sema.typeOf(new_func_inst).copy(new_decl_arena_allocator);
7853 new_decl.ty = child_sema.typeOf(new_func_inst);
78727854 // If the call evaluated to a return type that requires comptime, never mind
78737855 // our generic instantiation. Instead we need to perform a comptime call.
78747856 const new_fn_info = mod.typeToFunc(new_decl.ty).?;
......@@ -8068,7 +8050,7 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
80688050 });
80698051 }
80708052 try sema.validateErrorUnionPayloadType(block, payload, rhs_src);
8071 const err_union_ty = try Type.errorUnion(sema.arena, error_set, payload, sema.mod);
8053 const err_union_ty = try mod.errorUnionType(error_set, payload);
80728054 return sema.addType(err_union_ty);
80738055}
80748056
......@@ -8087,16 +8069,13 @@ fn validateErrorUnionPayloadType(sema: *Sema, block: *Block, payload_ty: Type, p
80878069
80888070fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
80898071 _ = block;
8090 const tracy = trace(@src());
8091 defer tracy.end();
8092
8072 const mod = sema.mod;
80938073 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
8094
8095 // Create an anonymous error set type with only this error value, and return the value.
8096 const kv = try sema.mod.getErrorValue(inst_data.get(sema.code));
8097 const result_type = try Type.Tag.error_set_single.create(sema.arena, kv.key);
8074 const name = inst_data.get(sema.code);
8075 // Create an error set type with only this error value, and return the value.
8076 const kv = try sema.mod.getErrorValue(name);
80988077 return sema.addConstant(
8099 result_type,
8078 try mod.singleErrorSetType(kv.key),
81008079 try Value.Tag.@"error".create(sema.arena, .{
81018080 .name = kv.key,
81028081 }),
......@@ -8139,11 +8118,14 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
81398118
81408119 const op_ty = sema.typeOf(uncasted_operand);
81418120 try sema.resolveInferredErrorSetTy(block, src, op_ty);
8142 if (!op_ty.isAnyError()) {
8143 const names = op_ty.errorSetNames();
8121 if (!op_ty.isAnyError(mod)) {
8122 const names = op_ty.errorSetNames(mod);
81448123 switch (names.len) {
81458124 0 => return sema.addConstant(Type.err_int, try mod.intValue(Type.err_int, 0)),
8146 1 => return sema.addIntUnsigned(Type.err_int, sema.mod.global_error_set.get(names[0]).?),
8125 1 => {
8126 const name = mod.intern_pool.stringToSlice(names[0]);
8127 return sema.addIntUnsigned(Type.err_int, mod.global_error_set.get(name).?);
8128 },
81478129 else => {},
81488130 }
81498131 }
......@@ -8224,22 +8206,22 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
82248206 return Air.Inst.Ref.anyerror_type;
82258207 }
82268208
8227 if (lhs_ty.castTag(.error_set_inferred)) |payload| {
8228 try sema.resolveInferredErrorSet(block, src, payload.data);
8209 if (mod.typeToInferredErrorSetIndex(lhs_ty).unwrap()) |ies_index| {
8210 try sema.resolveInferredErrorSet(block, src, ies_index);
82298211 // isAnyError might have changed from a false negative to a true positive after resolution.
8230 if (lhs_ty.isAnyError()) {
8212 if (lhs_ty.isAnyError(mod)) {
82318213 return Air.Inst.Ref.anyerror_type;
82328214 }
82338215 }
8234 if (rhs_ty.castTag(.error_set_inferred)) |payload| {
8235 try sema.resolveInferredErrorSet(block, src, payload.data);
8216 if (mod.typeToInferredErrorSetIndex(rhs_ty).unwrap()) |ies_index| {
8217 try sema.resolveInferredErrorSet(block, src, ies_index);
82368218 // isAnyError might have changed from a false negative to a true positive after resolution.
8237 if (rhs_ty.isAnyError()) {
8219 if (rhs_ty.isAnyError(mod)) {
82388220 return Air.Inst.Ref.anyerror_type;
82398221 }
82408222 }
82418223
8242 const err_set_ty = try lhs_ty.errorSetMerge(sema.arena, rhs_ty);
8224 const err_set_ty = try sema.errorSetMerge(lhs_ty, rhs_ty);
82438225 return sema.addType(err_set_ty);
82448226}
82458227
......@@ -8484,7 +8466,7 @@ fn zirOptionalPayload(
84848466 if (true) break :t operand_ty;
84858467 const ptr_info = operand_ty.ptrInfo(mod);
84868468 break :t try Type.ptr(sema.arena, sema.mod, .{
8487 .pointee_type = try ptr_info.pointee_type.copy(sema.arena),
8469 .pointee_type = ptr_info.pointee_type,
84888470 .@"align" = ptr_info.@"align",
84898471 .@"addrspace" = ptr_info.@"addrspace",
84908472 .mutable = ptr_info.mutable,
......@@ -8547,7 +8529,7 @@ fn analyzeErrUnionPayload(
85478529 safety_check: bool,
85488530) CompileError!Air.Inst.Ref {
85498531 const mod = sema.mod;
8550 const payload_ty = err_union_ty.errorUnionPayload();
8532 const payload_ty = err_union_ty.errorUnionPayload(mod);
85518533 if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {
85528534 if (val.getError()) |name| {
85538535 return sema.fail(block, src, "caught unexpected error '{s}'", .{name});
......@@ -8560,7 +8542,7 @@ fn analyzeErrUnionPayload(
85608542
85618543 // If the error set has no fields then no safety check is needed.
85628544 if (safety_check and block.wantSafety() and
8563 !err_union_ty.errorUnionSet().errorSetIsEmpty(mod))
8545 !err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod))
85648546 {
85658547 try sema.panicUnwrapError(block, operand, .unwrap_errunion_err, .is_non_err);
85668548 }
......@@ -8603,7 +8585,7 @@ fn analyzeErrUnionPayloadPtr(
86038585 }
86048586
86058587 const err_union_ty = operand_ty.childType(mod);
8606 const payload_ty = err_union_ty.errorUnionPayload();
8588 const payload_ty = err_union_ty.errorUnionPayload(mod);
86078589 const operand_pointer_ty = try Type.ptr(sema.arena, sema.mod, .{
86088590 .pointee_type = payload_ty,
86098591 .mutable = !operand_ty.isConstPtr(mod),
......@@ -8646,7 +8628,7 @@ fn analyzeErrUnionPayloadPtr(
86468628
86478629 // If the error set has no fields then no safety check is needed.
86488630 if (safety_check and block.wantSafety() and
8649 !err_union_ty.errorUnionSet().errorSetIsEmpty(mod))
8631 !err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod))
86508632 {
86518633 try sema.panicUnwrapError(block, operand, .unwrap_errunion_err_ptr, .is_non_err_ptr);
86528634 }
......@@ -8678,7 +8660,7 @@ fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air
86788660 });
86798661 }
86808662
8681 const result_ty = operand_ty.errorUnionSet();
8663 const result_ty = operand_ty.errorUnionSet(mod);
86828664
86838665 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
86848666 assert(val.getError() != null);
......@@ -8707,7 +8689,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
87078689 });
87088690 }
87098691
8710 const result_ty = operand_ty.childType(mod).errorUnionSet();
8692 const result_ty = operand_ty.childType(mod).errorUnionSet(mod);
87118693
87128694 if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| {
87138695 if (try sema.pointerDeref(block, src, pointer_val, operand_ty)) |val| {
......@@ -8755,7 +8737,7 @@ fn zirFunc(
87558737 extra_index += ret_ty_body.len;
87568738
87578739 const ret_ty_val = try sema.resolveGenericBody(block, ret_ty_src, ret_ty_body, inst, Type.type, "return type must be comptime-known");
8758 break :blk try ret_ty_val.toType().copy(sema.arena);
8740 break :blk ret_ty_val.toType();
87598741 },
87608742 };
87618743
......@@ -8927,6 +8909,7 @@ fn funcCommon(
89278909 is_noinline: bool,
89288910) CompileError!Air.Inst.Ref {
89298911 const mod = sema.mod;
8912 const gpa = sema.gpa;
89308913 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset };
89318914 const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = src_node_offset };
89328915 const func_src = LazySrcLoc.nodeOffset(src_node_offset);
......@@ -8955,16 +8938,12 @@ fn funcCommon(
89558938 break :new_func new_func;
89568939 }
89578940 destroy_fn_on_error = true;
8958 const new_func = try sema.gpa.create(Module.Fn);
8941 const new_func = try gpa.create(Module.Fn);
89598942 // Set this here so that the inferred return type can be printed correctly if it appears in an error.
89608943 new_func.owner_decl = sema.owner_decl_index;
89618944 break :new_func new_func;
89628945 };
8963 errdefer if (destroy_fn_on_error) sema.gpa.destroy(new_func);
8964
8965 var maybe_inferred_error_set_node: ?*Module.Fn.InferredErrorSetListNode = null;
8966 errdefer if (maybe_inferred_error_set_node) |node| sema.gpa.destroy(node);
8967 // Note: no need to errdefer since this will still be in its default state at the end of the function.
8946 errdefer if (destroy_fn_on_error) gpa.destroy(new_func);
89688947
89698948 const target = sema.mod.getTarget();
89708949 const fn_ty: Type = fn_ty: {
......@@ -9027,15 +9006,11 @@ fn funcCommon(
90279006 bare_return_type
90289007 else blk: {
90299008 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);
9030 const node = try sema.gpa.create(Module.Fn.InferredErrorSetListNode);
9031 node.data = .{ .func = new_func };
9032 maybe_inferred_error_set_node = node;
9033
9034 const error_set_ty = try Type.Tag.error_set_inferred.create(sema.arena, &node.data);
9035 break :blk try Type.Tag.error_union.create(sema.arena, .{
9036 .error_set = error_set_ty,
9037 .payload = bare_return_type,
9009 const ies_index = try mod.intern_pool.createInferredErrorSet(gpa, .{
9010 .func = new_func,
90389011 });
9012 const error_set_ty = try mod.intern(.{ .inferred_error_set_type = ies_index });
9013 break :blk try mod.errorUnionType(error_set_ty.toType(), bare_return_type);
90399014 };
90409015
90419016 if (!return_type.isValidReturnType(mod)) {
......@@ -9044,7 +9019,7 @@ fn funcCommon(
90449019 const msg = try sema.errMsg(block, ret_ty_src, "{s}return type '{}' not allowed", .{
90459020 opaque_str, return_type.fmt(sema.mod),
90469021 });
9047 errdefer msg.destroy(sema.gpa);
9022 errdefer msg.destroy(gpa);
90489023
90499024 try sema.addDeclaredHereNote(msg, return_type);
90509025 break :msg msg;
......@@ -9058,7 +9033,7 @@ fn funcCommon(
90589033 const msg = try sema.errMsg(block, ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{
90599034 return_type.fmt(sema.mod), @tagName(cc_resolved),
90609035 });
9061 errdefer msg.destroy(sema.gpa);
9036 errdefer msg.destroy(gpa);
90629037
90639038 const src_decl = sema.mod.declPtr(block.src_decl);
90649039 try sema.explainWhyTypeIsNotExtern(msg, ret_ty_src.toSrcLoc(src_decl, mod), return_type, .ret_ty);
......@@ -9182,8 +9157,8 @@ fn funcCommon(
91829157 sema.owner_decl.@"addrspace" = address_space orelse .generic;
91839158
91849159 if (is_extern) {
9185 const new_extern_fn = try sema.gpa.create(Module.ExternFn);
9186 errdefer sema.gpa.destroy(new_extern_fn);
9160 const new_extern_fn = try gpa.create(Module.ExternFn);
9161 errdefer gpa.destroy(new_extern_fn);
91879162
91889163 new_extern_fn.* = Module.ExternFn{
91899164 .owner_decl = sema.owner_decl_index,
......@@ -9232,10 +9207,6 @@ fn funcCommon(
92329207 .branch_quota = default_branch_quota,
92339208 .is_noinline = is_noinline,
92349209 };
9235 if (maybe_inferred_error_set_node) |node| {
9236 new_func.inferred_error_sets.prepend(node);
9237 }
9238 maybe_inferred_error_set_node = null;
92399210 fn_payload.* = .{
92409211 .base = .{ .tag = .function },
92419212 .data = new_func,
......@@ -10139,6 +10110,7 @@ fn zirSwitchCapture(
1013910110 defer tracy.end();
1014010111
1014110112 const mod = sema.mod;
10113 const gpa = sema.gpa;
1014210114 const zir_datas = sema.code.instructions.items(.data);
1014310115 const capture_info = zir_datas[inst].switch_capture;
1014410116 const switch_info = zir_datas[capture_info.switch_inst].pl_node;
......@@ -10248,7 +10220,7 @@ fn zirSwitchCapture(
1024810220 const capture_src = raw_capture_src.resolve(mod, sema.mod.declPtr(block.src_decl), switch_info.src_node, .first);
1024910221
1025010222 const msg = try sema.errMsg(block, capture_src, "capture group with incompatible types", .{});
10251 errdefer msg.destroy(sema.gpa);
10223 errdefer msg.destroy(gpa);
1025210224
1025310225 const raw_first_item_src = Module.SwitchProngSrc{ .multi = .{ .prong = capture_info.prong_index, .item = 0 } };
1025410226 const first_item_src = raw_first_item_src.resolve(mod, sema.mod.declPtr(block.src_decl), switch_info.src_node, .first);
......@@ -10294,20 +10266,16 @@ fn zirSwitchCapture(
1029410266 },
1029510267 .ErrorSet => {
1029610268 if (is_multi) {
10297 var names: Module.ErrorSet.NameMap = .{};
10269 var names: Module.Fn.InferredErrorSet.NameMap = .{};
1029810270 try names.ensureUnusedCapacity(sema.arena, items.len);
1029910271 for (items) |item| {
1030010272 const item_ref = try sema.resolveInst(item);
1030110273 // Previous switch validation ensured this will succeed
1030210274 const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable;
10303 names.putAssumeCapacityNoClobber(
10304 item_val.getError().?,
10305 {},
10306 );
10275 const name_ip = try mod.intern_pool.getOrPutString(gpa, item_val.getError().?);
10276 names.putAssumeCapacityNoClobber(name_ip, {});
1030710277 }
10308 // names must be sorted
10309 Module.ErrorSet.sortNames(&names);
10310 const else_error_ty = try Type.Tag.error_set_merged.create(sema.arena, names);
10278 const else_error_ty = try mod.errorSetFromUnsortedNames(names.keys());
1031110279
1031210280 return sema.bitCast(block, else_error_ty, operand, operand_src, null);
1031310281 } else {
......@@ -10315,7 +10283,7 @@ fn zirSwitchCapture(
1031510283 // Previous switch validation ensured this will succeed
1031610284 const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable;
1031710285
10318 const item_ty = try Type.Tag.error_set_single.create(sema.arena, item_val.getError().?);
10286 const item_ty = try mod.singleErrorSetType(item_val.getError().?);
1031910287 return sema.bitCast(block, item_ty, operand, operand_src, null);
1032010288 }
1032110289 },
......@@ -10678,7 +10646,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1067810646
1067910647 try sema.resolveInferredErrorSetTy(block, src, operand_ty);
1068010648
10681 if (operand_ty.isAnyError()) {
10649 if (operand_ty.isAnyError(mod)) {
1068210650 if (special_prong != .@"else") {
1068310651 return sema.fail(
1068410652 block,
......@@ -10692,7 +10660,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1069210660 var maybe_msg: ?*Module.ErrorMsg = null;
1069310661 errdefer if (maybe_msg) |msg| msg.destroy(sema.gpa);
1069410662
10695 for (operand_ty.errorSetNames()) |error_name| {
10663 for (operand_ty.errorSetNames(mod)) |error_name_ip| {
10664 const error_name = mod.intern_pool.stringToSlice(error_name_ip);
1069610665 if (!seen_errors.contains(error_name) and special_prong != .@"else") {
1069710666 const msg = maybe_msg orelse blk: {
1069810667 maybe_msg = try sema.errMsg(
......@@ -10720,7 +10689,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1072010689 return sema.failWithOwnedErrorMsg(msg);
1072110690 }
1072210691
10723 if (special_prong == .@"else" and seen_errors.count() == operand_ty.errorSetNames().len) {
10692 if (special_prong == .@"else" and seen_errors.count() == operand_ty.errorSetNames(mod).len) {
1072410693 // In order to enable common patterns for generic code allow simple else bodies
1072510694 // else => unreachable,
1072610695 // else => return,
......@@ -10757,18 +10726,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1075710726 );
1075810727 }
1075910728
10760 const error_names = operand_ty.errorSetNames();
10761 var names: Module.ErrorSet.NameMap = .{};
10729 const error_names = operand_ty.errorSetNames(mod);
10730 var names: Module.Fn.InferredErrorSet.NameMap = .{};
1076210731 try names.ensureUnusedCapacity(sema.arena, error_names.len);
10763 for (error_names) |error_name| {
10732 for (error_names) |error_name_ip| {
10733 const error_name = mod.intern_pool.stringToSlice(error_name_ip);
1076410734 if (seen_errors.contains(error_name)) continue;
1076510735
10766 names.putAssumeCapacityNoClobber(error_name, {});
10736 names.putAssumeCapacityNoClobber(error_name_ip, {});
1076710737 }
10768
10769 // names must be sorted
10770 Module.ErrorSet.sortNames(&names);
10771 else_error_ty = try Type.Tag.error_set_merged.create(sema.arena, names);
10738 // No need to keep the hash map metadata correct; here we
10739 // extract the (sorted) keys only.
10740 else_error_ty = try mod.errorSetFromUnsortedNames(names.keys());
1077210741 }
1077310742 },
1077410743 .Int, .ComptimeInt => {
......@@ -11513,12 +11482,13 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1151311482 }
1151411483 },
1151511484 .ErrorSet => {
11516 if (operand_ty.isAnyError()) {
11485 if (operand_ty.isAnyError(mod)) {
1151711486 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{
1151811487 operand_ty.fmt(mod),
1151911488 });
1152011489 }
11521 for (operand_ty.errorSetNames()) |error_name| {
11490 for (operand_ty.errorSetNames(mod)) |error_name_ip| {
11491 const error_name = mod.intern_pool.stringToSlice(error_name_ip);
1152211492 if (seen_errors.contains(error_name)) continue;
1152311493 cases_len += 1;
1152411494
......@@ -11931,7 +11901,8 @@ fn validateSwitchNoRange(
1193111901}
1193211902
1193311903fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, operand: Air.Inst.Ref) !bool {
11934 if (!sema.mod.backendSupportsFeature(.panic_unwrap_error)) return false;
11904 const mod = sema.mod;
11905 if (!mod.backendSupportsFeature(.panic_unwrap_error)) return false;
1193511906
1193611907 const tags = sema.code.instructions.items(.tag);
1193711908 for (body) |inst| {
......@@ -11967,7 +11938,7 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op
1196711938 .as_node => try sema.zirAsNode(block, inst),
1196811939 .field_val => try sema.zirFieldVal(block, inst),
1196911940 .@"unreachable" => {
11970 if (!sema.mod.comp.formatted_panics) {
11941 if (!mod.comp.formatted_panics) {
1197111942 try sema.safetyPanic(block, .unwrap_error);
1197211943 return true;
1197311944 }
......@@ -11990,7 +11961,7 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op
1199011961 },
1199111962 else => unreachable,
1199211963 };
11993 if (sema.typeOf(air_inst).isNoReturn())
11964 if (sema.typeOf(air_inst).isNoReturn(mod))
1199411965 return true;
1199511966 sema.inst_map.putAssumeCapacity(inst, air_inst);
1199611967 }
......@@ -12194,13 +12165,14 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1219412165}
1219512166
1219612167fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
12168 const mod = sema.mod;
1219712169 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
1219812170 const err_name = inst_data.get(sema.code);
1219912171
1220012172 // Return the error code from the function.
12201 const kv = try sema.mod.getErrorValue(err_name);
12173 const kv = try mod.getErrorValue(err_name);
1220212174 const result_inst = try sema.addConstant(
12203 try Type.Tag.error_set_single.create(sema.arena, kv.key),
12175 try mod.singleErrorSetType(kv.key),
1220412176 try Value.Tag.@"error".create(sema.arena, .{ .name = kv.key }),
1220512177 );
1220612178 return result_inst;
......@@ -15737,7 +15709,7 @@ fn zirClosureCapture(
1573715709 Value.@"unreachable";
1573815710
1573915711 try block.wip_capture_scope.captures.putNoClobber(sema.gpa, inst, .{
15740 .ty = try sema.typeOf(operand).copy(sema.perm_arena),
15712 .ty = sema.typeOf(operand),
1574115713 .val = try val.copy(sema.perm_arena),
1574215714 });
1574315715}
......@@ -16223,10 +16195,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1622316195 try mod.declareDeclDependency(sema.owner_decl_index, set_field_ty_decl_index);
1622416196 try sema.ensureDeclAnalyzed(set_field_ty_decl_index);
1622516197 const set_field_ty_decl = mod.declPtr(set_field_ty_decl_index);
16226 break :t try set_field_ty_decl.val.toType().copy(fields_anon_decl.arena());
16198 break :t set_field_ty_decl.val.toType();
1622716199 };
1622816200
16229 try sema.queueFullTypeResolution(try error_field_ty.copy(sema.arena));
16201 try sema.queueFullTypeResolution(error_field_ty);
1623016202
1623116203 // If the error set is inferred it must be resolved at this point
1623216204 try sema.resolveInferredErrorSetTy(block, src, ty);
......@@ -16234,11 +16206,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1623416206 // Build our list of Error values
1623516207 // Optional value is only null if anyerror
1623616208 // Value can be zero-length slice otherwise
16237 const error_field_vals: ?[]Value = if (ty.isAnyError()) null else blk: {
16238 const names = ty.errorSetNames();
16209 const error_field_vals: ?[]Value = if (ty.isAnyError(mod)) null else blk: {
16210 const names = ty.errorSetNames(mod);
1623916211 const vals = try fields_anon_decl.arena().alloc(Value, names.len);
16240 for (vals, 0..) |*field_val, i| {
16241 const name = names[i];
16212 for (vals, names) |*field_val, name_ip| {
16213 const name = mod.intern_pool.stringToSlice(name_ip);
1624216214 const name_val = v: {
1624316215 var anon_decl = try block.startAnonDecl();
1624416216 defer anon_decl.deinit();
......@@ -16301,9 +16273,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1630116273 .ErrorUnion => {
1630216274 const field_values = try sema.arena.alloc(Value, 2);
1630316275 // error_set: type,
16304 field_values[0] = try Value.Tag.ty.create(sema.arena, ty.errorUnionSet());
16276 field_values[0] = try Value.Tag.ty.create(sema.arena, ty.errorUnionSet(mod));
1630516277 // payload: type,
16306 field_values[1] = try Value.Tag.ty.create(sema.arena, ty.errorUnionPayload());
16278 field_values[1] = try Value.Tag.ty.create(sema.arena, ty.errorUnionPayload(mod));
1630716279
1630816280 return sema.addConstant(
1630916281 type_info_ty,
......@@ -16332,7 +16304,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1633216304 try mod.declareDeclDependency(sema.owner_decl_index, enum_field_ty_decl_index);
1633316305 try sema.ensureDeclAnalyzed(enum_field_ty_decl_index);
1633416306 const enum_field_ty_decl = mod.declPtr(enum_field_ty_decl_index);
16335 break :t try enum_field_ty_decl.val.toType().copy(fields_anon_decl.arena());
16307 break :t enum_field_ty_decl.val.toType();
1633616308 };
1633716309
1633816310 const enum_field_vals = try fields_anon_decl.arena().alloc(Value, enum_type.names.len);
......@@ -16416,7 +16388,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1641616388 try mod.declareDeclDependency(sema.owner_decl_index, union_field_ty_decl_index);
1641716389 try sema.ensureDeclAnalyzed(union_field_ty_decl_index);
1641816390 const union_field_ty_decl = mod.declPtr(union_field_ty_decl_index);
16419 break :t try union_field_ty_decl.val.toType().copy(fields_anon_decl.arena());
16391 break :t union_field_ty_decl.val.toType();
1642016392 };
1642116393
1642216394 const union_ty = try sema.resolveTypeFields(ty);
......@@ -16523,7 +16495,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1652316495 try mod.declareDeclDependency(sema.owner_decl_index, struct_field_ty_decl_index);
1652416496 try sema.ensureDeclAnalyzed(struct_field_ty_decl_index);
1652516497 const struct_field_ty_decl = mod.declPtr(struct_field_ty_decl_index);
16526 break :t try struct_field_ty_decl.val.toType().copy(fields_anon_decl.arena());
16498 break :t struct_field_ty_decl.val.toType();
1652716499 };
1652816500 const struct_ty = try sema.resolveTypeFields(ty);
1652916501 try sema.resolveTypeLayout(ty); // Getting alignment requires type layout
......@@ -16733,9 +16705,9 @@ fn typeInfoDecls(
1673316705 try mod.declareDeclDependency(sema.owner_decl_index, declaration_ty_decl_index);
1673416706 try sema.ensureDeclAnalyzed(declaration_ty_decl_index);
1673516707 const declaration_ty_decl = mod.declPtr(declaration_ty_decl_index);
16736 break :t try declaration_ty_decl.val.toType().copy(decls_anon_decl.arena());
16708 break :t declaration_ty_decl.val.toType();
1673716709 };
16738 try sema.queueFullTypeResolution(try declaration_ty.copy(sema.arena));
16710 try sema.queueFullTypeResolution(declaration_ty);
1673916711
1674016712 var decl_vals = std.ArrayList(Value).init(sema.gpa);
1674116713 defer decl_vals.deinit();
......@@ -17018,12 +16990,12 @@ fn zirBoolBr(
1701816990 _ = try lhs_block.addBr(block_inst, lhs_result);
1701916991
1702016992 const rhs_result = try sema.resolveBody(rhs_block, body, inst);
17021 if (!sema.typeOf(rhs_result).isNoReturn()) {
16993 if (!sema.typeOf(rhs_result).isNoReturn(mod)) {
1702216994 _ = try rhs_block.addBr(block_inst, rhs_result);
1702316995 }
1702416996
1702516997 const result = sema.finishCondBr(parent_block, &child_block, &then_block, &else_block, lhs, block_inst);
17026 if (!sema.typeOf(rhs_result).isNoReturn()) {
16998 if (!sema.typeOf(rhs_result).isNoReturn(mod)) {
1702716999 if (try sema.resolveDefinedValue(rhs_block, sema.src, rhs_result)) |rhs_val| {
1702817000 if (is_bool_or and rhs_val.toBool(mod)) {
1702917001 return Air.Inst.Ref.bool_true;
......@@ -17211,7 +17183,7 @@ fn zirCondbr(
1721117183 const err_operand = try sema.resolveInst(err_inst_data.operand);
1721217184 const operand_ty = sema.typeOf(err_operand);
1721317185 assert(operand_ty.zigTypeTag(mod) == .ErrorUnion);
17214 const result_ty = operand_ty.errorUnionSet();
17186 const result_ty = operand_ty.errorUnionSet(mod);
1721517187 break :blk try sub_block.addTyOp(.unwrap_errunion_err, result_ty, err_operand);
1721617188 };
1721717189
......@@ -17318,7 +17290,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
1731817290 const operand_ty = sema.typeOf(operand);
1731917291 const ptr_info = operand_ty.ptrInfo(mod);
1732017292 const res_ty = try Type.ptr(sema.arena, sema.mod, .{
17321 .pointee_type = err_union_ty.errorUnionPayload(),
17293 .pointee_type = err_union_ty.errorUnionPayload(mod),
1732217294 .@"addrspace" = ptr_info.@"addrspace",
1732317295 .mutable = ptr_info.mutable,
1732417296 .@"allowzero" = ptr_info.@"allowzero",
......@@ -17414,14 +17386,15 @@ fn zirRetErrValue(
1741417386 block: *Block,
1741517387 inst: Zir.Inst.Index,
1741617388) CompileError!Zir.Inst.Index {
17389 const mod = sema.mod;
1741717390 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
1741817391 const err_name = inst_data.get(sema.code);
1741917392 const src = inst_data.src();
1742017393
1742117394 // Return the error code from the function.
17422 const kv = try sema.mod.getErrorValue(err_name);
17395 const kv = try mod.getErrorValue(err_name);
1742317396 const result_inst = try sema.addConstant(
17424 try Type.Tag.error_set_single.create(sema.arena, kv.key),
17397 try mod.singleErrorSetType(err_name),
1742517398 try Value.Tag.@"error".create(sema.arena, .{ .name = kv.key }),
1742617399 );
1742717400 return sema.analyzeRet(block, result_inst, src);
......@@ -17632,17 +17605,15 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index)
1763217605
1763317606fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {
1763417607 const mod = sema.mod;
17608 const gpa = sema.gpa;
17609 const ip = &mod.intern_pool;
1763517610 assert(sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion);
1763617611
17637 if (sema.fn_ret_ty.errorUnionSet().castTag(.error_set_inferred)) |payload| {
17612 if (mod.typeToInferredErrorSet(sema.fn_ret_ty.errorUnionSet(mod))) |ies| {
1763817613 const op_ty = sema.typeOf(uncasted_operand);
1763917614 switch (op_ty.zigTypeTag(mod)) {
17640 .ErrorSet => {
17641 try payload.data.addErrorSet(sema.gpa, op_ty);
17642 },
17643 .ErrorUnion => {
17644 try payload.data.addErrorSet(sema.gpa, op_ty.errorUnionSet());
17645 },
17615 .ErrorSet => try ies.addErrorSet(op_ty, ip, gpa),
17616 .ErrorUnion => try ies.addErrorSet(op_ty.errorUnionSet(mod), ip, gpa),
1764617617 else => {},
1764717618 }
1764817619 }
......@@ -18521,7 +18492,7 @@ fn addConstantMaybeRef(
1852118492 var anon_decl = try block.startAnonDecl();
1852218493 defer anon_decl.deinit();
1852318494 const decl = try anon_decl.finish(
18524 try ty.copy(anon_decl.arena()),
18495 ty,
1852518496 try val.copy(anon_decl.arena()),
1852618497 0, // default alignment
1852718498 );
......@@ -18595,7 +18566,7 @@ fn fieldType(
1859518566 continue;
1859618567 },
1859718568 .ErrorUnion => {
18598 cur_ty = cur_ty.errorUnionPayload();
18569 cur_ty = cur_ty.errorUnionPayload(mod);
1859918570 continue;
1860018571 },
1860118572 else => {},
......@@ -18641,7 +18612,7 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1864118612 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1864218613 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1864318614 const ty = try sema.resolveType(block, operand_src, inst_data.operand);
18644 if (ty.isNoReturn()) {
18615 if (ty.isNoReturn(mod)) {
1864518616 return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(sema.mod)});
1864618617 }
1864718618 const val = try ty.lazyAbiAlignment(mod, sema.arena);
......@@ -18929,7 +18900,7 @@ fn zirReify(
1892918900 const sentinel_ptr_val = sentinel_val.castTag(.opt_payload).?.data;
1893018901 const ptr_ty = try Type.ptr(sema.arena, mod, .{
1893118902 .@"addrspace" = .generic,
18932 .pointee_type = try elem_ty.copy(sema.arena),
18903 .pointee_type = elem_ty,
1893318904 });
1893418905 const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
1893518906 break :s sent_val.toIntern();
......@@ -18993,7 +18964,7 @@ fn zirReify(
1899318964 const sentinel_val = struct_val[2];
1899418965
1899518966 const len = len_val.toUnsignedInt(mod);
18996 const child_ty = try child_val.toType().copy(sema.arena);
18967 const child_ty = child_val.toType();
1899718968 const sentinel = if (sentinel_val.castTag(.opt_payload)) |p| blk: {
1899818969 const ptr_ty = try Type.ptr(sema.arena, mod, .{
1899918970 .@"addrspace" = .generic,
......@@ -19011,7 +18982,7 @@ fn zirReify(
1901118982 // child: type,
1901218983 const child_val = struct_val[0];
1901318984
19014 const child_ty = try child_val.toType().copy(sema.arena);
18985 const child_ty = child_val.toType();
1901518986
1901618987 const ty = try Type.optional(sema.arena, child_ty, mod);
1901718988 return sema.addType(ty);
......@@ -19024,17 +18995,14 @@ fn zirReify(
1902418995 // payload: type,
1902518996 const payload_val = struct_val[1];
1902618997
19027 const error_set_ty = try error_set_val.toType().copy(sema.arena);
19028 const payload_ty = try payload_val.toType().copy(sema.arena);
18998 const error_set_ty = error_set_val.toType();
18999 const payload_ty = payload_val.toType();
1902919000
1903019001 if (error_set_ty.zigTypeTag(mod) != .ErrorSet) {
1903119002 return sema.fail(block, src, "Type.ErrorUnion.error_set must be an error set type", .{});
1903219003 }
1903319004
19034 const ty = try Type.Tag.error_union.create(sema.arena, .{
19035 .error_set = error_set_ty,
19036 .payload = payload_ty,
19037 });
19005 const ty = try mod.errorUnionType(error_set_ty, payload_ty);
1903819006 return sema.addType(ty);
1903919007 },
1904019008 .ErrorSet => {
......@@ -19043,27 +19011,23 @@ fn zirReify(
1904319011 const slice_val = payload_val.castTag(.slice).?.data;
1904419012
1904519013 const len = try sema.usizeCast(block, src, slice_val.len.toUnsignedInt(mod));
19046 var names: Module.ErrorSet.NameMap = .{};
19014 var names: Module.Fn.InferredErrorSet.NameMap = .{};
1904719015 try names.ensureUnusedCapacity(sema.arena, len);
19048 var i: usize = 0;
19049 while (i < len) : (i += 1) {
19016 for (0..len) |i| {
1905019017 const elem_val = try slice_val.ptr.elemValue(mod, i);
1905119018 const struct_val = elem_val.castTag(.aggregate).?.data;
1905219019 // TODO use reflection instead of magic numbers here
1905319020 // error_set: type,
1905419021 const name_val = struct_val[0];
1905519022 const name_str = try name_val.toAllocatedBytes(Type.const_slice_u8, sema.arena, mod);
19056
19057 const kv = try mod.getErrorValue(name_str);
19058 const gop = names.getOrPutAssumeCapacity(kv.key);
19023 const name_ip = try mod.intern_pool.getOrPutString(gpa, name_str);
19024 const gop = names.getOrPutAssumeCapacity(name_ip);
1905919025 if (gop.found_existing) {
1906019026 return sema.fail(block, src, "duplicate error '{s}'", .{name_str});
1906119027 }
1906219028 }
1906319029
19064 // names must be sorted
19065 Module.ErrorSet.sortNames(&names);
19066 const ty = try Type.Tag.error_set_merged.create(sema.arena, names);
19030 const ty = try mod.errorSetFromUnsortedNames(names.keys());
1906719031 return sema.addType(ty);
1906819032 },
1906919033 .Struct => {
......@@ -19378,7 +19342,7 @@ fn zirReify(
1937819342 return sema.fail(block, src, "duplicate union field {s}", .{field_name});
1937919343 }
1938019344
19381 const field_ty = try type_val.toType().copy(new_decl_arena_allocator);
19345 const field_ty = type_val.toType();
1938219346 gop.value_ptr.* = .{
1938319347 .ty = field_ty,
1938419348 .abi_align = @intCast(u32, (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?),
......@@ -19673,7 +19637,7 @@ fn reifyStruct(
1967319637 return sema.fail(block, src, "comptime field without default initialization value", .{});
1967419638 }
1967519639
19676 const field_ty = try type_val.toType().copy(new_decl_arena_allocator);
19640 const field_ty = type_val.toType();
1967719641 gop.value_ptr.* = .{
1967819642 .ty = field_ty,
1967919643 .abi_align = abi_align,
......@@ -19751,7 +19715,7 @@ fn reifyStruct(
1975119715 if (backing_int_val.optionalValue(mod)) |payload| {
1975219716 const backing_int_ty = payload.toType();
1975319717 try sema.checkBackingIntType(block, src, backing_int_ty, fields_bit_sum);
19754 struct_obj.backing_int_ty = try backing_int_ty.copy(new_decl_arena_allocator);
19718 struct_obj.backing_int_ty = backing_int_ty;
1975519719 } else {
1975619720 struct_obj.backing_int_ty = try mod.intType(.unsigned, @intCast(u16, fields_bit_sum));
1975719721 }
......@@ -20035,6 +19999,8 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2003519999}
2003620000
2003720001fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
20002 const mod = sema.mod;
20003 const ip = &mod.intern_pool;
2003820004 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
2003920005 const src = LazySrcLoc.nodeOffset(extra.node);
2004020006 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
......@@ -20050,22 +20016,27 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
2005020016
2005120017 if (disjoint: {
2005220018 // Try avoiding resolving inferred error sets if we can
20053 if (!dest_ty.isAnyError() and dest_ty.errorSetNames().len == 0) break :disjoint true;
20054 if (!operand_ty.isAnyError() and operand_ty.errorSetNames().len == 0) break :disjoint true;
20055 if (dest_ty.isAnyError()) break :disjoint false;
20056 if (operand_ty.isAnyError()) break :disjoint false;
20057 for (dest_ty.errorSetNames()) |dest_err_name|
20058 if (operand_ty.errorSetHasField(dest_err_name))
20019 if (!dest_ty.isAnyError(mod) and dest_ty.errorSetNames(mod).len == 0) break :disjoint true;
20020 if (!operand_ty.isAnyError(mod) and operand_ty.errorSetNames(mod).len == 0) break :disjoint true;
20021 if (dest_ty.isAnyError(mod)) break :disjoint false;
20022 if (operand_ty.isAnyError(mod)) break :disjoint false;
20023 for (dest_ty.errorSetNames(mod)) |dest_err_name| {
20024 if (Type.errorSetHasFieldIp(ip, operand_ty.toIntern(), dest_err_name))
2005920025 break :disjoint false;
20026 }
2006020027
20061 if (dest_ty.tag() != .error_set_inferred and operand_ty.tag() != .error_set_inferred)
20028 if (!ip.isInferredErrorSetType(dest_ty.ip_index) and
20029 !ip.isInferredErrorSetType(operand_ty.ip_index))
20030 {
2006220031 break :disjoint true;
20032 }
2006320033
2006420034 try sema.resolveInferredErrorSetTy(block, dest_ty_src, dest_ty);
2006520035 try sema.resolveInferredErrorSetTy(block, operand_src, operand_ty);
20066 for (dest_ty.errorSetNames()) |dest_err_name|
20067 if (operand_ty.errorSetHasField(dest_err_name))
20036 for (dest_ty.errorSetNames(mod)) |dest_err_name| {
20037 if (Type.errorSetHasFieldIp(ip, operand_ty.toIntern(), dest_err_name))
2006820038 break :disjoint false;
20039 }
2006920040
2007020041 break :disjoint true;
2007120042 }) {
......@@ -20085,9 +20056,9 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
2008520056 }
2008620057
2008720058 if (maybe_operand_val) |val| {
20088 if (!dest_ty.isAnyError()) {
20059 if (!dest_ty.isAnyError(mod)) {
2008920060 const error_name = val.castTag(.@"error").?.data.name;
20090 if (!dest_ty.errorSetHasField(error_name)) {
20061 if (!dest_ty.errorSetHasField(error_name, mod)) {
2009120062 const msg = msg: {
2009220063 const msg = try sema.errMsg(
2009320064 block,
......@@ -20107,7 +20078,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
2010720078 }
2010820079
2010920080 try sema.requireRuntimeBlock(block, src, operand_src);
20110 if (block.wantSafety() and !dest_ty.isAnyError() and sema.mod.backendSupportsFeature(.error_set_has_value)) {
20081 if (block.wantSafety() and !dest_ty.isAnyError(mod) and sema.mod.backendSupportsFeature(.error_set_has_value)) {
2011120082 const err_int_inst = try block.addBitCast(Type.err_int, operand);
2011220083 const ok = try block.addTyOp(.error_set_has_value, dest_ty, err_int_inst);
2011320084 try sema.addSafetyCheck(block, ok, .invalid_error_code);
......@@ -22862,7 +22833,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2286222833 extra_index += body.len;
2286322834
2286422835 const val = try sema.resolveGenericBody(block, ret_src, body, inst, Type.type, "return type must be comptime-known");
22865 const ty = try val.toType().copy(sema.arena);
22836 const ty = val.toType();
2286622837 break :blk ty;
2286722838 } else if (extra.data.bits.has_ret_ty_ref) blk: {
2286822839 const ret_ty_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
......@@ -22873,7 +22844,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2287322844 },
2287422845 else => |e| return e,
2287522846 };
22876 const ty = try ret_ty_tv.val.toType().copy(sema.arena);
22847 const ty = ret_ty_tv.val.toType();
2287722848 break :blk ty;
2287822849 } else Type.void;
2287922850
......@@ -23360,7 +23331,7 @@ fn validateRunTimeType(
2336023331 },
2336123332 .Array, .Vector => ty = ty.childType(mod),
2336223333
23363 .ErrorUnion => ty = ty.errorUnionPayload(),
23334 .ErrorUnion => ty = ty.errorUnionPayload(mod),
2336423335
2336523336 .Struct, .Union => {
2336623337 const resolved_ty = try sema.resolveTypeFields(ty);
......@@ -23452,7 +23423,7 @@ fn explainWhyTypeIsComptimeInner(
2345223423 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.optionalChild(mod), type_set);
2345323424 },
2345423425 .ErrorUnion => {
23455 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.errorUnionPayload(), type_set);
23426 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.errorUnionPayload(mod), type_set);
2345623427 },
2345723428
2345823429 .Struct => {
......@@ -24065,7 +24036,9 @@ fn fieldVal(
2406524036 // in `fieldPtr`. This function takes a value and returns a value.
2406624037
2406724038 const mod = sema.mod;
24039 const gpa = sema.gpa;
2406824040 const arena = sema.arena;
24041 const ip = &mod.intern_pool;
2406924042 const object_src = src; // TODO better source location
2407024043 const object_ty = sema.typeOf(object);
2407124044
......@@ -24147,27 +24120,33 @@ fn fieldVal(
2414724120
2414824121 switch (try child_type.zigTypeTagOrPoison(mod)) {
2414924122 .ErrorSet => {
24150 const name: []const u8 = if (child_type.castTag(.error_set)) |payload| blk: {
24151 if (payload.data.names.getEntry(field_name)) |entry| {
24152 break :blk entry.key_ptr.*;
24153 }
24154 const msg = msg: {
24155 const msg = try sema.errMsg(block, src, "no error named '{s}' in '{}'", .{
24156 field_name, child_type.fmt(mod),
24157 });
24158 errdefer msg.destroy(sema.gpa);
24159 try sema.addDeclaredHereNote(msg, child_type);
24160 break :msg msg;
24161 };
24162 return sema.failWithOwnedErrorMsg(msg);
24163 } else (try mod.getErrorValue(field_name)).key;
24123 const name = try ip.getOrPutString(gpa, field_name);
24124 switch (ip.indexToKey(child_type.ip_index)) {
24125 .error_set_type => |error_set_type| blk: {
24126 if (error_set_type.nameIndex(ip, name) != null) break :blk;
24127 const msg = msg: {
24128 const msg = try sema.errMsg(block, src, "no error named '{s}' in '{}'", .{
24129 field_name, child_type.fmt(mod),
24130 });
24131 errdefer msg.destroy(sema.gpa);
24132 try sema.addDeclaredHereNote(msg, child_type);
24133 break :msg msg;
24134 };
24135 return sema.failWithOwnedErrorMsg(msg);
24136 },
24137 .inferred_error_set_type => {
24138 return sema.fail(block, src, "TODO handle inferred error sets here", .{});
24139 },
24140 .simple_type => |t| assert(t == .anyerror),
24141 else => unreachable,
24142 }
2416424143
2416524144 return sema.addConstant(
24166 if (!child_type.isAnyError())
24167 try child_type.copy(arena)
24145 if (!child_type.isAnyError(mod))
24146 child_type
2416824147 else
24169 try Type.Tag.error_set_single.create(arena, name),
24170 try Value.Tag.@"error".create(arena, .{ .name = name }),
24148 try mod.singleErrorSetTypeNts(name),
24149 try Value.Tag.@"error".create(arena, .{ .name = ip.stringToSlice(name) }),
2417124150 );
2417224151 },
2417324152 .Union => {
......@@ -24252,6 +24231,8 @@ fn fieldPtr(
2425224231 // in `fieldVal`. This function takes a pointer and returns a pointer.
2425324232
2425424233 const mod = sema.mod;
24234 const gpa = sema.gpa;
24235 const ip = &mod.intern_pool;
2425524236 const object_ptr_src = src; // TODO better source location
2425624237 const object_ptr_ty = sema.typeOf(object_ptr);
2425724238 const object_ty = switch (object_ptr_ty.zigTypeTag(mod)) {
......@@ -24362,24 +24343,33 @@ fn fieldPtr(
2436224343
2436324344 switch (child_type.zigTypeTag(mod)) {
2436424345 .ErrorSet => {
24365 // TODO resolve inferred error sets
24366 const name: []const u8 = if (child_type.castTag(.error_set)) |payload| blk: {
24367 if (payload.data.names.getEntry(field_name)) |entry| {
24368 break :blk entry.key_ptr.*;
24369 }
24370 return sema.fail(block, src, "no error named '{s}' in '{}'", .{
24371 field_name, child_type.fmt(mod),
24372 });
24373 } else (try mod.getErrorValue(field_name)).key;
24346 const name = try ip.getOrPutString(gpa, field_name);
24347 switch (ip.indexToKey(child_type.ip_index)) {
24348 .error_set_type => |error_set_type| blk: {
24349 if (error_set_type.nameIndex(ip, name) != null) {
24350 break :blk;
24351 }
24352 return sema.fail(block, src, "no error named '{s}' in '{}'", .{
24353 field_name, child_type.fmt(mod),
24354 });
24355 },
24356 .inferred_error_set_type => {
24357 return sema.fail(block, src, "TODO handle inferred error sets here", .{});
24358 },
24359 .simple_type => |t| assert(t == .anyerror),
24360 else => unreachable,
24361 }
2437424362
2437524363 var anon_decl = try block.startAnonDecl();
2437624364 defer anon_decl.deinit();
2437724365 return sema.analyzeDeclRef(try anon_decl.finish(
24378 if (!child_type.isAnyError())
24379 try child_type.copy(anon_decl.arena())
24366 if (!child_type.isAnyError(mod))
24367 child_type
2438024368 else
24381 try Type.Tag.error_set_single.create(anon_decl.arena(), name),
24382 try Value.Tag.@"error".create(anon_decl.arena(), .{ .name = name }),
24369 try mod.singleErrorSetTypeNts(name),
24370 try Value.Tag.@"error".create(anon_decl.arena(), .{
24371 .name = ip.stringToSlice(name),
24372 }),
2438324373 0, // default alignment
2438424374 ));
2438524375 },
......@@ -24589,7 +24579,7 @@ fn fieldCallBind(
2458924579 } };
2459024580 }
2459124581 } else if (first_param_type.zigTypeTag(mod) == .ErrorUnion and
24592 first_param_type.errorUnionPayload().eql(concrete_ty, mod))
24582 first_param_type.errorUnionPayload(mod).eql(concrete_ty, mod))
2459324583 {
2459424584 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
2459524585 return .{ .method = .{
......@@ -24832,7 +24822,7 @@ fn structFieldPtrByIndex(
2483224822
2483324823 if (field.is_comptime) {
2483424824 const val = try Value.Tag.comptime_field_ptr.create(sema.arena, .{
24835 .field_ty = try field.ty.copy(sema.arena),
24825 .field_ty = field.ty,
2483624826 .field_val = try field.default_val.copy(sema.arena),
2483724827 });
2483824828 return sema.addConstant(ptr_field_ty, val);
......@@ -26227,7 +26217,7 @@ fn coerceExtra(
2622726217 .none => switch (inst_val.tag()) {
2622826218 .eu_payload => {
2622926219 const payload = try sema.addConstant(
26230 inst_ty.errorUnionPayload(),
26220 inst_ty.errorUnionPayload(mod),
2623126221 inst_val.castTag(.eu_payload).?.data,
2623226222 );
2623326223 return sema.wrapErrorUnionPayload(block, dest_ty, payload, inst_src) catch |err| switch (err) {
......@@ -26240,7 +26230,7 @@ fn coerceExtra(
2624026230 else => {},
2624126231 }
2624226232 const error_set = try sema.addConstant(
26243 inst_ty.errorUnionSet(),
26233 inst_ty.errorUnionSet(mod),
2624426234 inst_val,
2624526235 );
2624626236 return sema.wrapErrorUnionSet(block, dest_ty, error_set, inst_src);
......@@ -26342,7 +26332,7 @@ fn coerceExtra(
2634226332
2634326333 // E!T to T
2634426334 if (inst_ty.zigTypeTag(mod) == .ErrorUnion and
26345 (try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(), dest_ty, false, target, dest_ty_src, inst_src)) == .ok)
26335 (try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(mod), dest_ty, false, target, dest_ty_src, inst_src)) == .ok)
2634626336 {
2634726337 try sema.errNote(block, inst_src, msg, "cannot convert error union to payload type", .{});
2634826338 try sema.errNote(block, inst_src, msg, "consider using 'try', 'catch', or 'if'", .{});
......@@ -26393,7 +26383,7 @@ const InMemoryCoercionResult = union(enum) {
2639326383 optional_shape: Pair,
2639426384 optional_child: PairAndChild,
2639526385 from_anyerror,
26396 missing_error: []const []const u8,
26386 missing_error: []const InternPool.NullTerminatedString,
2639726387 /// true if wanted is var args
2639826388 fn_var_args: bool,
2639926389 /// true if wanted is generic
......@@ -26567,7 +26557,8 @@ const InMemoryCoercionResult = union(enum) {
2656726557 break;
2656826558 },
2656926559 .missing_error => |missing_errors| {
26570 for (missing_errors) |err| {
26560 for (missing_errors) |err_index| {
26561 const err = mod.intern_pool.stringToSlice(err_index);
2657126562 try sema.errNote(block, src, msg, "'error.{s}' not a member of destination error set", .{err});
2657226563 }
2657326564 break;
......@@ -26813,8 +26804,8 @@ fn coerceInMemoryAllowed(
2681326804
2681426805 // Error Unions
2681526806 if (dest_tag == .ErrorUnion and src_tag == .ErrorUnion) {
26816 const dest_payload = dest_ty.errorUnionPayload();
26817 const src_payload = src_ty.errorUnionPayload();
26807 const dest_payload = dest_ty.errorUnionPayload(mod);
26808 const src_payload = src_ty.errorUnionPayload(mod);
2681826809 const child = try sema.coerceInMemoryAllowed(block, dest_payload, src_payload, dest_is_mut, target, dest_src, src_src);
2681926810 if (child != .ok) {
2682026811 return InMemoryCoercionResult{ .error_union_payload = .{
......@@ -26823,7 +26814,7 @@ fn coerceInMemoryAllowed(
2682326814 .wanted = dest_payload,
2682426815 } };
2682526816 }
26826 return try sema.coerceInMemoryAllowed(block, dest_ty.errorUnionSet(), src_ty.errorUnionSet(), dest_is_mut, target, dest_src, src_src);
26817 return try sema.coerceInMemoryAllowed(block, dest_ty.errorUnionSet(mod), src_ty.errorUnionSet(mod), dest_is_mut, target, dest_src, src_src);
2682726818 }
2682826819
2682926820 // Error Sets
......@@ -26903,8 +26894,8 @@ fn coerceInMemoryAllowed(
2690326894 if (child != .ok) {
2690426895 return InMemoryCoercionResult{ .optional_child = .{
2690526896 .child = try child.dupe(sema.arena),
26906 .actual = try src_child_type.copy(sema.arena),
26907 .wanted = try dest_child_type.copy(sema.arena),
26897 .actual = src_child_type,
26898 .wanted = dest_child_type,
2690826899 } };
2690926900 }
2691026901
......@@ -26926,133 +26917,100 @@ fn coerceInMemoryAllowedErrorSets(
2692626917 src_src: LazySrcLoc,
2692726918) !InMemoryCoercionResult {
2692826919 const mod = sema.mod;
26920 const gpa = sema.gpa;
26921 const ip = &mod.intern_pool;
2692926922
2693026923 // Coercion to `anyerror`. Note that this check can return false negatives
2693126924 // in case the error sets did not get resolved.
26932 if (dest_ty.isAnyError()) {
26925 if (dest_ty.isAnyError(mod)) {
2693326926 return .ok;
2693426927 }
2693526928
26936 if (dest_ty.castTag(.error_set_inferred)) |dst_payload| {
26937 const dst_ies = dst_payload.data;
26929 if (mod.typeToInferredErrorSetIndex(dest_ty).unwrap()) |dst_ies_index| {
26930 const dst_ies = mod.inferredErrorSetPtr(dst_ies_index);
2693826931 // We will make an effort to return `ok` without resolving either error set, to
2693926932 // avoid unnecessary "unable to resolve error set" dependency loop errors.
2694026933 switch (src_ty.ip_index) {
26941 .none => switch (src_ty.tag()) {
26942 .error_set_inferred => {
26934 .anyerror_type => {},
26935 else => switch (ip.indexToKey(src_ty.ip_index)) {
26936 .inferred_error_set_type => |src_index| {
2694326937 // If both are inferred error sets of functions, and
2694426938 // the dest includes the source function, the coercion is OK.
2694526939 // This check is important because it works without forcing a full resolution
2694626940 // of inferred error sets.
26947 const src_ies = src_ty.castTag(.error_set_inferred).?.data;
26948
26949 if (dst_ies.inferred_error_sets.contains(src_ies)) {
26941 if (dst_ies.inferred_error_sets.contains(src_index)) {
2695026942 return .ok;
2695126943 }
2695226944 },
26953 .error_set_single => {
26954 const name = src_ty.castTag(.error_set_single).?.data;
26955 if (dst_ies.errors.contains(name)) return .ok;
26956 },
26957 .error_set_merged => {
26958 const names = src_ty.castTag(.error_set_merged).?.data.keys();
26959 for (names) |name| {
26960 if (!dst_ies.errors.contains(name)) break;
26961 } else return .ok;
26962 },
26963 .error_set => {
26964 const names = src_ty.castTag(.error_set).?.data.names.keys();
26965 for (names) |name| {
26945 .error_set_type => |error_set_type| {
26946 for (error_set_type.names) |name| {
2696626947 if (!dst_ies.errors.contains(name)) break;
2696726948 } else return .ok;
2696826949 },
2696926950 else => unreachable,
2697026951 },
26971 .anyerror_type => {},
26972 else => switch (mod.intern_pool.indexToKey(src_ty.ip_index)) {
26973 else => @panic("TODO"),
26974 },
2697526952 }
2697626953
2697726954 if (dst_ies.func == sema.owner_func) {
2697826955 // We are trying to coerce an error set to the current function's
2697926956 // inferred error set.
26980 try dst_ies.addErrorSet(sema.gpa, src_ty);
26957 try dst_ies.addErrorSet(src_ty, ip, gpa);
2698126958 return .ok;
2698226959 }
2698326960
26984 try sema.resolveInferredErrorSet(block, dest_src, dst_payload.data);
26961 try sema.resolveInferredErrorSet(block, dest_src, dst_ies_index);
2698526962 // isAnyError might have changed from a false negative to a true positive after resolution.
26986 if (dest_ty.isAnyError()) {
26963 if (dest_ty.isAnyError(mod)) {
2698726964 return .ok;
2698826965 }
2698926966 }
2699026967
26991 var missing_error_buf = std.ArrayList([]const u8).init(sema.gpa);
26968 var missing_error_buf = std.ArrayList(InternPool.NullTerminatedString).init(gpa);
2699226969 defer missing_error_buf.deinit();
2699326970
2699426971 switch (src_ty.ip_index) {
26995 .none => switch (src_ty.tag()) {
26996 .error_set_inferred => {
26997 const src_data = src_ty.castTag(.error_set_inferred).?.data;
26972 .anyerror_type => switch (ip.indexToKey(dest_ty.ip_index)) {
26973 .inferred_error_set_type => unreachable, // Caught by dest_ty.isAnyError(mod) above.
26974 .simple_type => unreachable, // filtered out above
26975 .error_set_type => return .from_anyerror,
26976 else => unreachable,
26977 },
26978
26979 else => switch (ip.indexToKey(src_ty.ip_index)) {
26980 .inferred_error_set_type => |src_index| {
26981 const src_data = mod.inferredErrorSetPtr(src_index);
2699826982
26999 try sema.resolveInferredErrorSet(block, src_src, src_data);
26983 try sema.resolveInferredErrorSet(block, src_src, src_index);
2700026984 // src anyerror status might have changed after the resolution.
27001 if (src_ty.isAnyError()) {
27002 // dest_ty.isAnyError() == true is already checked for at this point.
26985 if (src_ty.isAnyError(mod)) {
26986 // dest_ty.isAnyError(mod) == true is already checked for at this point.
2700326987 return .from_anyerror;
2700426988 }
2700526989
2700626990 for (src_data.errors.keys()) |key| {
27007 if (!dest_ty.errorSetHasField(key)) {
26991 if (!Type.errorSetHasFieldIp(ip, dest_ty.toIntern(), key)) {
2700826992 try missing_error_buf.append(key);
2700926993 }
2701026994 }
2701126995
2701226996 if (missing_error_buf.items.len != 0) {
2701326997 return InMemoryCoercionResult{
27014 .missing_error = try sema.arena.dupe([]const u8, missing_error_buf.items),
27015 };
27016 }
27017
27018 return .ok;
27019 },
27020 .error_set_single => {
27021 const name = src_ty.castTag(.error_set_single).?.data;
27022 if (dest_ty.errorSetHasField(name)) {
27023 return .ok;
27024 }
27025 const list = try sema.arena.alloc([]const u8, 1);
27026 list[0] = name;
27027 return InMemoryCoercionResult{ .missing_error = list };
27028 },
27029 .error_set_merged => {
27030 const names = src_ty.castTag(.error_set_merged).?.data.keys();
27031 for (names) |name| {
27032 if (!dest_ty.errorSetHasField(name)) {
27033 try missing_error_buf.append(name);
27034 }
27035 }
27036
27037 if (missing_error_buf.items.len != 0) {
27038 return InMemoryCoercionResult{
27039 .missing_error = try sema.arena.dupe([]const u8, missing_error_buf.items),
26998 .missing_error = try sema.arena.dupe(InternPool.NullTerminatedString, missing_error_buf.items),
2704026999 };
2704127000 }
2704227001
2704327002 return .ok;
2704427003 },
27045 .error_set => {
27046 const names = src_ty.castTag(.error_set).?.data.names.keys();
27047 for (names) |name| {
27048 if (!dest_ty.errorSetHasField(name)) {
27004 .error_set_type => |error_set_type| {
27005 for (error_set_type.names) |name| {
27006 if (!Type.errorSetHasFieldIp(ip, dest_ty.toIntern(), name)) {
2704927007 try missing_error_buf.append(name);
2705027008 }
2705127009 }
2705227010
2705327011 if (missing_error_buf.items.len != 0) {
2705427012 return InMemoryCoercionResult{
27055 .missing_error = try sema.arena.dupe([]const u8, missing_error_buf.items),
27013 .missing_error = try sema.arena.dupe(InternPool.NullTerminatedString, missing_error_buf.items),
2705627014 };
2705727015 }
2705827016
......@@ -27060,18 +27018,6 @@ fn coerceInMemoryAllowedErrorSets(
2706027018 },
2706127019 else => unreachable,
2706227020 },
27063
27064 .anyerror_type => switch (dest_ty.ip_index) {
27065 .none => switch (dest_ty.tag()) {
27066 .error_set_inferred => unreachable, // Caught by dest_ty.isAnyError() above.
27067 .error_set_single, .error_set_merged, .error_set => return .from_anyerror,
27068 else => unreachable,
27069 },
27070 .anyerror_type => unreachable, // Filtered out above.
27071 else => @panic("TODO"),
27072 },
27073
27074 else => @panic("TODO"),
2707527021 }
2707627022
2707727023 unreachable;
......@@ -28029,7 +27975,7 @@ fn beginComptimePtrMutation(
2802927975 var parent = try sema.beginComptimePtrMutation(block, src, eu_ptr.container_ptr, eu_ptr.container_ty);
2803027976 switch (parent.pointee) {
2803127977 .direct => |val_ptr| {
28032 const payload_ty = parent.ty.errorUnionPayload();
27978 const payload_ty = parent.ty.errorUnionPayload(mod);
2803327979 if (val_ptr.ip_index == .none and val_ptr.tag() == .eu_payload) {
2803427980 return ComptimePtrMutationKit{
2803527981 .decl_ref_mut = parent.decl_ref_mut,
......@@ -28402,7 +28348,7 @@ fn beginComptimePtrLoad(
2840228348 => blk: {
2840328349 const payload_ptr = ptr_val.cast(Value.Payload.PayloadPtr).?.data;
2840428350 const payload_ty = switch (ptr_val.tag()) {
28405 .eu_payload_ptr => payload_ptr.container_ty.errorUnionPayload(),
28351 .eu_payload_ptr => payload_ptr.container_ty.errorUnionPayload(mod),
2840628352 .opt_payload_ptr => payload_ptr.container_ty.optionalChild(mod),
2840728353 else => unreachable,
2840828354 };
......@@ -29301,7 +29247,7 @@ fn refValue(sema: *Sema, block: *Block, ty: Type, val: Value) !Value {
2930129247 var anon_decl = try block.startAnonDecl();
2930229248 defer anon_decl.deinit();
2930329249 const decl = try anon_decl.finish(
29304 try ty.copy(anon_decl.arena()),
29250 ty,
2930529251 try val.copy(anon_decl.arena()),
2930629252 0, // default alignment
2930729253 );
......@@ -29387,7 +29333,7 @@ fn analyzeRef(
2938729333 var anon_decl = try block.startAnonDecl();
2938829334 defer anon_decl.deinit();
2938929335 return sema.analyzeDeclRef(try anon_decl.finish(
29390 try operand_ty.copy(anon_decl.arena()),
29336 operand_ty,
2939129337 try val.copy(anon_decl.arena()),
2939229338 0, // default alignment
2939329339 ));
......@@ -29555,7 +29501,7 @@ fn analyzeIsNonErrComptimeOnly(
2955529501 if (ot == .ErrorSet) return Air.Inst.Ref.bool_false;
2955629502 assert(ot == .ErrorUnion);
2955729503
29558 const payload_ty = operand_ty.errorUnionPayload();
29504 const payload_ty = operand_ty.errorUnionPayload(mod);
2955929505 if (payload_ty.zigTypeTag(mod) == .NoReturn) {
2956029506 return Air.Inst.Ref.bool_false;
2956129507 }
......@@ -29577,23 +29523,28 @@ fn analyzeIsNonErrComptimeOnly(
2957729523
2957829524 // exception if the error union error set is known to be empty,
2957929525 // we allow the comparison but always make it comptime-known.
29580 const set_ty = operand_ty.errorUnionSet();
29526 const set_ty = operand_ty.errorUnionSet(mod);
2958129527 switch (set_ty.ip_index) {
29582 .none => switch (set_ty.tag()) {
29583 .error_set_inferred => blk: {
29528 .anyerror_type => {},
29529 else => switch (mod.intern_pool.indexToKey(set_ty.ip_index)) {
29530 .error_set_type => |error_set_type| {
29531 if (error_set_type.names.len == 0) return Air.Inst.Ref.bool_true;
29532 },
29533 .inferred_error_set_type => |ies_index| blk: {
2958429534 // If the error set is empty, we must return a comptime true or false.
2958529535 // However we want to avoid unnecessarily resolving an inferred error set
2958629536 // in case it is already non-empty.
29587 const ies = set_ty.castTag(.error_set_inferred).?.data;
29537 const ies = mod.inferredErrorSetPtr(ies_index);
2958829538 if (ies.is_anyerror) break :blk;
2958929539 if (ies.errors.count() != 0) break :blk;
2959029540 if (maybe_operand_val == null) {
2959129541 // Try to avoid resolving inferred error set if possible.
2959229542 if (ies.errors.count() != 0) break :blk;
2959329543 if (ies.is_anyerror) break :blk;
29594 for (ies.inferred_error_sets.keys()) |other_ies| {
29595 if (ies == other_ies) continue;
29596 try sema.resolveInferredErrorSet(block, src, other_ies);
29544 for (ies.inferred_error_sets.keys()) |other_ies_index| {
29545 if (ies_index == other_ies_index) continue;
29546 try sema.resolveInferredErrorSet(block, src, other_ies_index);
29547 const other_ies = mod.inferredErrorSetPtr(other_ies_index);
2959729548 if (other_ies.is_anyerror) {
2959829549 ies.is_anyerror = true;
2959929550 ies.is_resolved = true;
......@@ -29608,18 +29559,12 @@ fn analyzeIsNonErrComptimeOnly(
2960829559 // so far with this type can't contain errors either.
2960929560 return Air.Inst.Ref.bool_true;
2961029561 }
29611 try sema.resolveInferredErrorSet(block, src, ies);
29562 try sema.resolveInferredErrorSet(block, src, ies_index);
2961229563 if (ies.is_anyerror) break :blk;
2961329564 if (ies.errors.count() == 0) return Air.Inst.Ref.bool_true;
2961429565 }
2961529566 },
29616 else => if (set_ty.errorSetNames().len == 0) return Air.Inst.Ref.bool_true,
29617 },
29618
29619 .anyerror_type => {},
29620
29621 else => switch (mod.intern_pool.indexToKey(set_ty.ip_index)) {
29622 else => @panic("TODO"),
29567 else => unreachable,
2962329568 },
2962429569 }
2962529570
......@@ -30516,7 +30461,8 @@ fn wrapErrorUnionPayload(
3051630461 inst: Air.Inst.Ref,
3051730462 inst_src: LazySrcLoc,
3051830463) !Air.Inst.Ref {
30519 const dest_payload_ty = dest_ty.errorUnionPayload();
30464 const mod = sema.mod;
30465 const dest_payload_ty = dest_ty.errorUnionPayload(mod);
3052030466 const coerced = try sema.coerceExtra(block, dest_payload_ty, inst, inst_src, .{ .report_err = false });
3052130467 if (try sema.resolveMaybeUndefVal(coerced)) |val| {
3052230468 return sema.addConstant(dest_ty, try Value.Tag.eu_payload.create(sema.arena, val));
......@@ -30533,51 +30479,41 @@ fn wrapErrorUnionSet(
3053330479 inst: Air.Inst.Ref,
3053430480 inst_src: LazySrcLoc,
3053530481) !Air.Inst.Ref {
30482 const mod = sema.mod;
30483 const ip = &mod.intern_pool;
3053630484 const inst_ty = sema.typeOf(inst);
30537 const dest_err_set_ty = dest_ty.errorUnionSet();
30485 const dest_err_set_ty = dest_ty.errorUnionSet(mod);
3053830486 if (try sema.resolveMaybeUndefVal(inst)) |val| {
3053930487 switch (dest_err_set_ty.ip_index) {
3054030488 .anyerror_type => {},
30541
30542 .none => switch (dest_err_set_ty.tag()) {
30543 .error_set_single => ok: {
30544 const expected_name = val.castTag(.@"error").?.data.name;
30545 const n = dest_err_set_ty.castTag(.error_set_single).?.data;
30546 if (mem.eql(u8, expected_name, n)) break :ok;
30547 return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
30548 },
30549 .error_set => {
30489 else => switch (ip.indexToKey(dest_err_set_ty.ip_index)) {
30490 .error_set_type => |error_set_type| ok: {
3055030491 const expected_name = val.castTag(.@"error").?.data.name;
30551 const error_set = dest_err_set_ty.castTag(.error_set).?.data;
30552 if (!error_set.names.contains(expected_name)) {
30553 return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
30492 if (ip.getString(expected_name).unwrap()) |expected_name_interned| {
30493 if (error_set_type.nameIndex(ip, expected_name_interned) != null)
30494 break :ok;
3055430495 }
30496 return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
3055530497 },
30556 .error_set_inferred => ok: {
30498 .inferred_error_set_type => |ies_index| ok: {
30499 const ies = mod.inferredErrorSetPtr(ies_index);
3055730500 const expected_name = val.castTag(.@"error").?.data.name;
30558 const ies = dest_err_set_ty.castTag(.error_set_inferred).?.data;
3055930501
3056030502 // We carefully do this in an order that avoids unnecessarily
3056130503 // resolving the destination error set type.
3056230504 if (ies.is_anyerror) break :ok;
30563 if (ies.errors.contains(expected_name)) break :ok;
30505
30506 if (ip.getString(expected_name).unwrap()) |expected_name_interned| {
30507 if (ies.errors.contains(expected_name_interned)) break :ok;
30508 }
3056430509 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, dest_err_set_ty, inst_ty, inst_src, inst_src)) {
3056530510 break :ok;
3056630511 }
3056730512
3056830513 return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
3056930514 },
30570 .error_set_merged => {
30571 const expected_name = val.castTag(.@"error").?.data.name;
30572 const error_set = dest_err_set_ty.castTag(.error_set_merged).?.data;
30573 if (!error_set.contains(expected_name)) {
30574 return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
30575 }
30576 },
3057730515 else => unreachable,
3057830516 },
30579
30580 else => @panic("TODO"),
3058130517 }
3058230518 return sema.addConstant(dest_ty, val);
3058330519 }
......@@ -30743,11 +30679,11 @@ fn resolvePeerTypes(
3074330679 continue;
3074430680 }
3074530681
30746 err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_ty);
30682 err_set_ty = try sema.errorSetMerge(chosen_set_ty, candidate_ty);
3074730683 continue;
3074830684 },
3074930685 .ErrorUnion => {
30750 const chosen_set_ty = err_set_ty orelse chosen_ty.errorUnionSet();
30686 const chosen_set_ty = err_set_ty orelse chosen_ty.errorUnionSet(mod);
3075130687
3075230688 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_ty, src, src)) {
3075330689 continue;
......@@ -30757,7 +30693,7 @@ fn resolvePeerTypes(
3075730693 continue;
3075830694 }
3075930695
30760 err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_ty);
30696 err_set_ty = try sema.errorSetMerge(chosen_set_ty, candidate_ty);
3076130697 continue;
3076230698 },
3076330699 else => {
......@@ -30770,7 +30706,7 @@ fn resolvePeerTypes(
3077030706 continue;
3077130707 }
3077230708
30773 err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_ty);
30709 err_set_ty = try sema.errorSetMerge(chosen_set_ty, candidate_ty);
3077430710 continue;
3077530711 } else {
3077630712 err_set_ty = candidate_ty;
......@@ -30781,14 +30717,14 @@ fn resolvePeerTypes(
3078130717 .ErrorUnion => switch (chosen_ty_tag) {
3078230718 .ErrorSet => {
3078330719 const chosen_set_ty = err_set_ty orelse chosen_ty;
30784 const candidate_set_ty = candidate_ty.errorUnionSet();
30720 const candidate_set_ty = candidate_ty.errorUnionSet(mod);
3078530721
3078630722 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_set_ty, src, src)) {
3078730723 err_set_ty = chosen_set_ty;
3078830724 } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, candidate_set_ty, chosen_set_ty, src, src)) {
3078930725 err_set_ty = null;
3079030726 } else {
30791 err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty);
30727 err_set_ty = try sema.errorSetMerge(chosen_set_ty, candidate_set_ty);
3079230728 }
3079330729 chosen = candidate;
3079430730 chosen_i = candidate_i + 1;
......@@ -30796,8 +30732,8 @@ fn resolvePeerTypes(
3079630732 },
3079730733
3079830734 .ErrorUnion => {
30799 const chosen_payload_ty = chosen_ty.errorUnionPayload();
30800 const candidate_payload_ty = candidate_ty.errorUnionPayload();
30735 const chosen_payload_ty = chosen_ty.errorUnionPayload(mod);
30736 const candidate_payload_ty = candidate_ty.errorUnionPayload(mod);
3080130737
3080230738 const coerce_chosen = (try sema.coerceInMemoryAllowed(block, chosen_payload_ty, candidate_payload_ty, false, target, src, src)) == .ok;
3080330739 const coerce_candidate = (try sema.coerceInMemoryAllowed(block, candidate_payload_ty, chosen_payload_ty, false, target, src, src)) == .ok;
......@@ -30811,15 +30747,15 @@ fn resolvePeerTypes(
3081130747 chosen_i = candidate_i + 1;
3081230748 }
3081330749
30814 const chosen_set_ty = err_set_ty orelse chosen_ty.errorUnionSet();
30815 const candidate_set_ty = candidate_ty.errorUnionSet();
30750 const chosen_set_ty = err_set_ty orelse chosen_ty.errorUnionSet(mod);
30751 const candidate_set_ty = candidate_ty.errorUnionSet(mod);
3081630752
3081730753 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_set_ty, src, src)) {
3081830754 err_set_ty = chosen_set_ty;
3081930755 } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, candidate_set_ty, chosen_set_ty, src, src)) {
3082030756 err_set_ty = candidate_set_ty;
3082130757 } else {
30822 err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty);
30758 err_set_ty = try sema.errorSetMerge(chosen_set_ty, candidate_set_ty);
3082330759 }
3082430760 continue;
3082530761 }
......@@ -30827,13 +30763,13 @@ fn resolvePeerTypes(
3082730763
3082830764 else => {
3082930765 if (err_set_ty) |chosen_set_ty| {
30830 const candidate_set_ty = candidate_ty.errorUnionSet();
30766 const candidate_set_ty = candidate_ty.errorUnionSet(mod);
3083130767 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_set_ty, src, src)) {
3083230768 err_set_ty = chosen_set_ty;
3083330769 } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, candidate_set_ty, chosen_set_ty, src, src)) {
3083430770 err_set_ty = null;
3083530771 } else {
30836 err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty);
30772 err_set_ty = try sema.errorSetMerge(chosen_set_ty, candidate_set_ty);
3083730773 }
3083830774 }
3083930775 seen_const = seen_const or chosen_ty.isConstPtr(mod);
......@@ -30963,7 +30899,7 @@ fn resolvePeerTypes(
3096330899 }
3096430900 },
3096530901 .ErrorUnion => {
30966 const chosen_ptr_ty = chosen_ty.errorUnionPayload();
30902 const chosen_ptr_ty = chosen_ty.errorUnionPayload(mod);
3096730903 if (chosen_ptr_ty.zigTypeTag(mod) == .Pointer) {
3096830904 const chosen_info = chosen_ptr_ty.ptrInfo(mod);
3096930905
......@@ -31073,7 +31009,7 @@ fn resolvePeerTypes(
3107331009 }
3107431010 },
3107531011 .ErrorUnion => {
31076 const payload_ty = chosen_ty.errorUnionPayload();
31012 const payload_ty = chosen_ty.errorUnionPayload(mod);
3107731013 if ((try sema.coerceInMemoryAllowed(block, payload_ty, candidate_ty, false, target, src, src)) == .ok) {
3107831014 continue;
3107931015 }
......@@ -31090,7 +31026,7 @@ fn resolvePeerTypes(
3109031026 continue;
3109131027 }
3109231028
31093 err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, chosen_ty);
31029 err_set_ty = try sema.errorSetMerge(chosen_set_ty, chosen_ty);
3109431030 continue;
3109531031 } else {
3109631032 err_set_ty = chosen_ty;
......@@ -31148,14 +31084,14 @@ fn resolvePeerTypes(
3114831084 else
3114931085 new_ptr_ty;
3115031086 const set_ty = err_set_ty orelse return opt_ptr_ty;
31151 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, mod);
31087 return try mod.errorUnionType(set_ty, opt_ptr_ty);
3115231088 }
3115331089
3115431090 if (seen_const) {
3115531091 // turn []T => []const T
3115631092 switch (chosen_ty.zigTypeTag(mod)) {
3115731093 .ErrorUnion => {
31158 const ptr_ty = chosen_ty.errorUnionPayload();
31094 const ptr_ty = chosen_ty.errorUnionPayload(mod);
3115931095 var info = ptr_ty.ptrInfo(mod);
3116031096 info.mutable = false;
3116131097 const new_ptr_ty = try Type.ptr(sema.arena, mod, info);
......@@ -31163,8 +31099,8 @@ fn resolvePeerTypes(
3116331099 try Type.optional(sema.arena, new_ptr_ty, mod)
3116431100 else
3116531101 new_ptr_ty;
31166 const set_ty = err_set_ty orelse chosen_ty.errorUnionSet();
31167 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, mod);
31102 const set_ty = err_set_ty orelse chosen_ty.errorUnionSet(mod);
31103 return try mod.errorUnionType(set_ty, opt_ptr_ty);
3116831104 },
3116931105 .Pointer => {
3117031106 var info = chosen_ty.ptrInfo(mod);
......@@ -31175,7 +31111,7 @@ fn resolvePeerTypes(
3117531111 else
3117631112 new_ptr_ty;
3117731113 const set_ty = err_set_ty orelse return opt_ptr_ty;
31178 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, mod);
31114 return try mod.errorUnionType(set_ty, opt_ptr_ty);
3117931115 },
3118031116 else => return chosen_ty,
3118131117 }
......@@ -31187,16 +31123,16 @@ fn resolvePeerTypes(
3118731123 else => try Type.optional(sema.arena, chosen_ty, mod),
3118831124 };
3118931125 const set_ty = err_set_ty orelse return opt_ty;
31190 return try Type.errorUnion(sema.arena, set_ty, opt_ty, mod);
31126 return try mod.errorUnionType(set_ty, opt_ty);
3119131127 }
3119231128
3119331129 if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag(mod)) {
3119431130 .ErrorSet => return ty,
3119531131 .ErrorUnion => {
31196 const payload_ty = chosen_ty.errorUnionPayload();
31197 return try Type.errorUnion(sema.arena, ty, payload_ty, mod);
31132 const payload_ty = chosen_ty.errorUnionPayload(mod);
31133 return try mod.errorUnionType(ty, payload_ty);
3119831134 },
31199 else => return try Type.errorUnion(sema.arena, ty, chosen_ty, mod),
31135 else => return try mod.errorUnionType(ty, chosen_ty),
3120031136 };
3120131137
3120231138 return chosen_ty;
......@@ -31279,7 +31215,7 @@ pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void {
3127931215 return sema.resolveTypeLayout(payload_ty);
3128031216 },
3128131217 .ErrorUnion => {
31282 const payload_ty = ty.errorUnionPayload();
31218 const payload_ty = ty.errorUnionPayload(mod);
3128331219 return sema.resolveTypeLayout(payload_ty);
3128431220 },
3128531221 .Fn => {
......@@ -31465,7 +31401,7 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
3146531401 };
3146631402
3146731403 try sema.checkBackingIntType(&block, backing_int_src, backing_int_ty, fields_bit_sum);
31468 struct_obj.backing_int_ty = try backing_int_ty.copy(decl_arena_allocator);
31404 struct_obj.backing_int_ty = backing_int_ty;
3146931405 try wip_captures.finalize();
3147031406 } else {
3147131407 if (fields_bit_sum > std.math.maxInt(u16)) {
......@@ -31605,18 +31541,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3160531541
3160631542 return switch (ty.ip_index) {
3160731543 .empty_struct_type => false,
31608 .none => switch (ty.tag()) {
31609 .error_set,
31610 .error_set_single,
31611 .error_set_inferred,
31612 .error_set_merged,
31613 => false,
31614
31615 .inferred_alloc_mut => unreachable,
31616 .inferred_alloc_const => unreachable,
31617
31618 .error_union => return sema.resolveTypeRequiresComptime(ty.errorUnionPayload()),
31619 },
3162031544 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3162131545 .int_type => false,
3162231546 .ptr_type => |ptr_type| {
......@@ -31635,6 +31559,8 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3163531559 .vector_type => |vector_type| return sema.resolveTypeRequiresComptime(vector_type.child.toType()),
3163631560 .opt_type => |child| return sema.resolveTypeRequiresComptime(child.toType()),
3163731561 .error_union_type => |error_union_type| return sema.resolveTypeRequiresComptime(error_union_type.payload_type.toType()),
31562 .error_set_type, .inferred_error_set_type => false,
31563
3163831564 .func_type => true,
3163931565
3164031566 .simple_type => |t| switch (t) {
......@@ -31780,7 +31706,7 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {
3178031706 .Optional => {
3178131707 return sema.resolveTypeFully(ty.optionalChild(mod));
3178231708 },
31783 .ErrorUnion => return sema.resolveTypeFully(ty.errorUnionPayload()),
31709 .ErrorUnion => return sema.resolveTypeFully(ty.errorUnionPayload(mod)),
3178431710 .Fn => {
3178531711 const info = mod.typeToFunc(ty).?;
3178631712 if (info.is_generic) {
......@@ -32048,16 +31974,17 @@ fn resolveInferredErrorSet(
3204831974 sema: *Sema,
3204931975 block: *Block,
3205031976 src: LazySrcLoc,
32051 ies: *Module.Fn.InferredErrorSet,
31977 ies_index: Module.Fn.InferredErrorSet.Index,
3205231978) CompileError!void {
31979 const mod = sema.mod;
31980 const ies = mod.inferredErrorSetPtr(ies_index);
31981
3205331982 if (ies.is_resolved) return;
3205431983
3205531984 if (ies.func.state == .in_progress) {
3205631985 return sema.fail(block, src, "unable to resolve inferred error set", .{});
3205731986 }
3205831987
32059 const mod = sema.mod;
32060
3206131988 // In order to ensure that all dependencies are properly added to the set, we
3206231989 // need to ensure the function body is analyzed of the inferred error set.
3206331990 // However, in the case of comptime/inline function calls with inferred error sets,
......@@ -32072,7 +31999,7 @@ fn resolveInferredErrorSet(
3207231999 // so here we can simply skip this case.
3207332000 if (ies_func_info.return_type == .generic_poison_type) {
3207432001 assert(ies_func_info.cc == .Inline);
32075 } else if (ies_func_info.return_type.toType().errorUnionSet().castTag(.error_set_inferred).?.data == ies) {
32002 } else if (mod.typeToInferredErrorSet(ies_func_info.return_type.toType().errorUnionSet(mod)).? == ies) {
3207632003 if (ies_func_info.is_generic) {
3207732004 const msg = msg: {
3207832005 const msg = try sema.errMsg(block, src, "unable to resolve inferred error set of generic function", .{});
......@@ -32090,10 +32017,11 @@ fn resolveInferredErrorSet(
3209032017
3209132018 ies.is_resolved = true;
3209232019
32093 for (ies.inferred_error_sets.keys()) |other_ies| {
32094 if (ies == other_ies) continue;
32095 try sema.resolveInferredErrorSet(block, src, other_ies);
32020 for (ies.inferred_error_sets.keys()) |other_ies_index| {
32021 if (ies_index == other_ies_index) continue;
32022 try sema.resolveInferredErrorSet(block, src, other_ies_index);
3209632023
32024 const other_ies = mod.inferredErrorSetPtr(other_ies_index);
3209732025 for (other_ies.errors.keys()) |key| {
3209832026 try ies.errors.put(sema.gpa, key, {});
3209932027 }
......@@ -32108,8 +32036,9 @@ fn resolveInferredErrorSetTy(
3210832036 src: LazySrcLoc,
3210932037 ty: Type,
3211032038) CompileError!void {
32111 if (ty.castTag(.error_set_inferred)) |inferred| {
32112 try sema.resolveInferredErrorSet(block, src, inferred.data);
32039 const mod = sema.mod;
32040 if (mod.typeToInferredErrorSetIndex(ty).unwrap()) |ies_index| {
32041 try sema.resolveInferredErrorSet(block, src, ies_index);
3211332042 }
3211432043}
3211532044
......@@ -32333,7 +32262,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
3233332262 }
3233432263
3233532264 const field = &struct_obj.fields.values()[field_i];
32336 field.ty = try field_ty.copy(decl_arena_allocator);
32265 field.ty = field_ty;
3233732266
3233832267 if (field_ty.zigTypeTag(mod) == .Opaque) {
3233932268 const msg = msg: {
......@@ -32809,7 +32738,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3280932738 }
3281032739
3281132740 gop.value_ptr.* = .{
32812 .ty = try field_ty.copy(decl_arena_allocator),
32741 .ty = field_ty,
3281332742 .abi_align = 0,
3281432743 };
3281532744
......@@ -33038,13 +32967,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3303832967 .empty_struct_type => return Value.empty_struct,
3303932968
3304032969 .none => switch (ty.tag()) {
33041 .error_set_single,
33042 .error_set,
33043 .error_set_merged,
33044 .error_union,
33045 .error_set_inferred,
33046 => return null,
33047
3304832970 .inferred_alloc_const => unreachable,
3304932971 .inferred_alloc_mut => unreachable,
3305032972 },
......@@ -33062,6 +32984,8 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3306232984 .error_union_type,
3306332985 .func_type,
3306432986 .anyframe_type,
32987 .error_set_type,
32988 .inferred_error_set_type,
3306532989 => null,
3306632990
3306732991 .array_type => |array_type| {
......@@ -33389,7 +33313,7 @@ fn analyzeComptimeAlloc(
3338933313 defer anon_decl.deinit();
3339033314
3339133315 const decl_index = try anon_decl.finish(
33392 try var_type.copy(anon_decl.arena()),
33316 var_type,
3339333317 // There will be stores before the first load, but they may be to sub-elements or
3339433318 // sub-fields. So we need to initialize with undef to allow the mechanism to expand
3339533319 // into fields/elements and have those overridden with stored values.
......@@ -33600,8 +33524,6 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {
3360033524 switch (ty.tag()) {
3360133525 .inferred_alloc_const => unreachable,
3360233526 .inferred_alloc_mut => unreachable,
33603
33604 else => return null,
3360533527 }
3360633528}
3360733529
......@@ -33616,18 +33538,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3361633538 return switch (ty.ip_index) {
3361733539 .empty_struct_type => false,
3361833540
33619 .none => switch (ty.tag()) {
33620 .error_set,
33621 .error_set_single,
33622 .error_set_inferred,
33623 .error_set_merged,
33624 => false,
33625
33626 .inferred_alloc_mut => unreachable,
33627 .inferred_alloc_const => unreachable,
33628
33629 .error_union => return sema.typeRequiresComptime(ty.errorUnionPayload()),
33630 },
3363133541 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3363233542 .int_type => return false,
3363333543 .ptr_type => |ptr_type| {
......@@ -33649,6 +33559,9 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3364933559 .error_union_type => |error_union_type| {
3365033560 return sema.typeRequiresComptime(error_union_type.payload_type.toType());
3365133561 },
33562
33563 .error_set_type, .inferred_error_set_type => false,
33564
3365233565 .func_type => true,
3365333566
3365433567 .simple_type => |t| return switch (t) {
......@@ -34410,3 +34323,23 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
3441034323 .vector_index = vector_info.vector_index,
3441134324 });
3441234325}
34326
34327/// Merge lhs with rhs.
34328/// Asserts that lhs and rhs are both error sets and are resolved.
34329fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {
34330 const mod = sema.mod;
34331 const arena = sema.arena;
34332 const lhs_names = lhs.errorSetNames(mod);
34333 const rhs_names = rhs.errorSetNames(mod);
34334 var names: Module.Fn.InferredErrorSet.NameMap = .{};
34335 try names.ensureUnusedCapacity(arena, lhs_names.len);
34336
34337 for (lhs_names) |name| {
34338 names.putAssumeCapacityNoClobber(name, {});
34339 }
34340 for (rhs_names) |name| {
34341 try names.put(arena, name, {});
34342 }
34343
34344 return mod.errorSetFromUnsortedNames(names.keys());
34345}
src/TypedValue.zig+3-3
......@@ -27,13 +27,13 @@ pub const Managed = struct {
2727/// Assumes arena allocation. Does a recursive copy.
2828pub fn copy(self: TypedValue, arena: Allocator) error{OutOfMemory}!TypedValue {
2929 return TypedValue{
30 .ty = try self.ty.copy(arena),
30 .ty = self.ty,
3131 .val = try self.val.copy(arena),
3232 };
3333}
3434
3535pub fn eql(a: TypedValue, b: TypedValue, mod: *Module) bool {
36 if (!a.ty.eql(b.ty, mod)) return false;
36 if (a.ty.ip_index != b.ty.ip_index) return false;
3737 return a.val.eql(b.val, a.ty, mod);
3838}
3939
......@@ -286,7 +286,7 @@ pub fn print(
286286 .@"error" => return writer.print("error.{s}", .{val.castTag(.@"error").?.data.name}),
287287 .eu_payload => {
288288 val = val.castTag(.eu_payload).?.data;
289 ty = ty.errorUnionPayload();
289 ty = ty.errorUnionPayload(mod);
290290 },
291291 .opt_payload => {
292292 val = val.castTag(.opt_payload).?.data;
src/arch/aarch64/CodeGen.zig+9-9
......@@ -3065,8 +3065,8 @@ fn errUnionErr(
30653065 maybe_inst: ?Air.Inst.Index,
30663066) !MCValue {
30673067 const mod = self.bin_file.options.module.?;
3068 const err_ty = error_union_ty.errorUnionSet();
3069 const payload_ty = error_union_ty.errorUnionPayload();
3068 const err_ty = error_union_ty.errorUnionSet(mod);
3069 const payload_ty = error_union_ty.errorUnionPayload(mod);
30703070 if (err_ty.errorSetIsEmpty(mod)) {
30713071 return MCValue{ .immediate = 0 };
30723072 }
......@@ -3145,8 +3145,8 @@ fn errUnionPayload(
31453145 maybe_inst: ?Air.Inst.Index,
31463146) !MCValue {
31473147 const mod = self.bin_file.options.module.?;
3148 const err_ty = error_union_ty.errorUnionSet();
3149 const payload_ty = error_union_ty.errorUnionPayload();
3148 const err_ty = error_union_ty.errorUnionSet(mod);
3149 const payload_ty = error_union_ty.errorUnionPayload(mod);
31503150 if (err_ty.errorSetIsEmpty(mod)) {
31513151 return try error_union_bind.resolveToMcv(self);
31523152 }
......@@ -3305,8 +3305,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
33053305 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
33063306 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
33073307 const error_union_ty = self.air.getRefType(ty_op.ty);
3308 const error_ty = error_union_ty.errorUnionSet();
3309 const payload_ty = error_union_ty.errorUnionPayload();
3308 const error_ty = error_union_ty.errorUnionSet(mod);
3309 const payload_ty = error_union_ty.errorUnionPayload(mod);
33103310 const operand = try self.resolveInst(ty_op.operand);
33113311 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;
33123312
......@@ -3329,8 +3329,8 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
33293329 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
33303330 const mod = self.bin_file.options.module.?;
33313331 const error_union_ty = self.air.getRefType(ty_op.ty);
3332 const error_ty = error_union_ty.errorUnionSet();
3333 const payload_ty = error_union_ty.errorUnionPayload();
3332 const error_ty = error_union_ty.errorUnionSet(mod);
3333 const payload_ty = error_union_ty.errorUnionPayload(mod);
33343334 const operand = try self.resolveInst(ty_op.operand);
33353335 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;
33363336
......@@ -4893,7 +4893,7 @@ fn isErr(
48934893 error_union_ty: Type,
48944894) !MCValue {
48954895 const mod = self.bin_file.options.module.?;
4896 const error_type = error_union_ty.errorUnionSet();
4896 const error_type = error_union_ty.errorUnionSet(mod);
48974897
48984898 if (error_type.errorSetIsEmpty(mod)) {
48994899 return MCValue{ .immediate = 0 }; // always false
src/arch/arm/CodeGen.zig+9-9
......@@ -2042,8 +2042,8 @@ fn errUnionErr(
20422042 maybe_inst: ?Air.Inst.Index,
20432043) !MCValue {
20442044 const mod = self.bin_file.options.module.?;
2045 const err_ty = error_union_ty.errorUnionSet();
2046 const payload_ty = error_union_ty.errorUnionPayload();
2045 const err_ty = error_union_ty.errorUnionSet(mod);
2046 const payload_ty = error_union_ty.errorUnionPayload(mod);
20472047 if (err_ty.errorSetIsEmpty(mod)) {
20482048 return MCValue{ .immediate = 0 };
20492049 }
......@@ -2119,8 +2119,8 @@ fn errUnionPayload(
21192119 maybe_inst: ?Air.Inst.Index,
21202120) !MCValue {
21212121 const mod = self.bin_file.options.module.?;
2122 const err_ty = error_union_ty.errorUnionSet();
2123 const payload_ty = error_union_ty.errorUnionPayload();
2122 const err_ty = error_union_ty.errorUnionSet(mod);
2123 const payload_ty = error_union_ty.errorUnionPayload(mod);
21242124 if (err_ty.errorSetIsEmpty(mod)) {
21252125 return try error_union_bind.resolveToMcv(self);
21262126 }
......@@ -2232,8 +2232,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
22322232 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
22332233 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
22342234 const error_union_ty = self.air.getRefType(ty_op.ty);
2235 const error_ty = error_union_ty.errorUnionSet();
2236 const payload_ty = error_union_ty.errorUnionPayload();
2235 const error_ty = error_union_ty.errorUnionSet(mod);
2236 const payload_ty = error_union_ty.errorUnionPayload(mod);
22372237 const operand = try self.resolveInst(ty_op.operand);
22382238 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;
22392239
......@@ -2256,8 +2256,8 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
22562256 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
22572257 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
22582258 const error_union_ty = self.air.getRefType(ty_op.ty);
2259 const error_ty = error_union_ty.errorUnionSet();
2260 const payload_ty = error_union_ty.errorUnionPayload();
2259 const error_ty = error_union_ty.errorUnionSet(mod);
2260 const payload_ty = error_union_ty.errorUnionPayload(mod);
22612261 const operand = try self.resolveInst(ty_op.operand);
22622262 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;
22632263
......@@ -4871,7 +4871,7 @@ fn isErr(
48714871 error_union_ty: Type,
48724872) !MCValue {
48734873 const mod = self.bin_file.options.module.?;
4874 const error_type = error_union_ty.errorUnionSet();
4874 const error_type = error_union_ty.errorUnionSet(mod);
48754875
48764876 if (error_type.errorSetIsEmpty(mod)) {
48774877 return MCValue{ .immediate = 0 }; // always false
src/arch/sparc64/CodeGen.zig+10-10
......@@ -2707,12 +2707,12 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
27072707}
27082708
27092709fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
2710 const mod = self.bin_file.options.module.?;
27102711 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
27112712 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
27122713 const error_union_ty = self.typeOf(ty_op.operand);
2713 const payload_ty = error_union_ty.errorUnionPayload();
2714 const payload_ty = error_union_ty.errorUnionPayload(mod);
27142715 const mcv = try self.resolveInst(ty_op.operand);
2715 const mod = self.bin_file.options.module.?;
27162716 if (!payload_ty.hasRuntimeBits(mod)) break :result mcv;
27172717
27182718 return self.fail("TODO implement unwrap error union error for non-empty payloads", .{});
......@@ -2721,11 +2721,11 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
27212721}
27222722
27232723fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
2724 const mod = self.bin_file.options.module.?;
27242725 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
27252726 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
27262727 const error_union_ty = self.typeOf(ty_op.operand);
2727 const payload_ty = error_union_ty.errorUnionPayload();
2728 const mod = self.bin_file.options.module.?;
2728 const payload_ty = error_union_ty.errorUnionPayload(mod);
27292729 if (!payload_ty.hasRuntimeBits(mod)) break :result MCValue.none;
27302730
27312731 return self.fail("TODO implement unwrap error union payload for non-empty payloads", .{});
......@@ -2735,12 +2735,12 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
27352735
27362736/// E to E!T
27372737fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
2738 const mod = self.bin_file.options.module.?;
27382739 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
27392740 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
27402741 const error_union_ty = self.air.getRefType(ty_op.ty);
2741 const payload_ty = error_union_ty.errorUnionPayload();
2742 const payload_ty = error_union_ty.errorUnionPayload(mod);
27422743 const mcv = try self.resolveInst(ty_op.operand);
2743 const mod = self.bin_file.options.module.?;
27442744 if (!payload_ty.hasRuntimeBits(mod)) break :result mcv;
27452745
27462746 return self.fail("TODO implement wrap errunion error for non-empty payloads", .{});
......@@ -3529,8 +3529,8 @@ fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void {
35293529/// Given an error union, returns the payload
35303530fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {
35313531 const mod = self.bin_file.options.module.?;
3532 const err_ty = error_union_ty.errorUnionSet();
3533 const payload_ty = error_union_ty.errorUnionPayload();
3532 const err_ty = error_union_ty.errorUnionSet(mod);
3533 const payload_ty = error_union_ty.errorUnionPayload(mod);
35343534 if (err_ty.errorSetIsEmpty(mod)) {
35353535 return error_union_mcv;
35363536 }
......@@ -4168,8 +4168,8 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
41684168
41694169fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
41704170 const mod = self.bin_file.options.module.?;
4171 const error_type = ty.errorUnionSet();
4172 const payload_type = ty.errorUnionPayload();
4171 const error_type = ty.errorUnionSet(mod);
4172 const payload_type = ty.errorUnionPayload(mod);
41734173
41744174 if (!error_type.hasRuntimeBits(mod)) {
41754175 return MCValue{ .immediate = 0 }; // always false
src/arch/wasm/CodeGen.zig+21-20
......@@ -1264,7 +1264,7 @@ fn genFunc(func: *CodeGen) InnerError!void {
12641264 if (func_type.returns.len != 0 and func.air.instructions.len > 0) {
12651265 const inst = @intCast(u32, func.air.instructions.len - 1);
12661266 const last_inst_ty = func.typeOfIndex(inst);
1267 if (!last_inst_ty.hasRuntimeBitsIgnoreComptime(mod) or last_inst_ty.isNoReturn()) {
1267 if (!last_inst_ty.hasRuntimeBitsIgnoreComptime(mod) or last_inst_ty.isNoReturn(mod)) {
12681268 try func.addTag(.@"unreachable");
12691269 }
12701270 }
......@@ -1757,7 +1757,7 @@ fn isByRef(ty: Type, mod: *Module) bool {
17571757 .Int => return ty.intInfo(mod).bits > 64,
17581758 .Float => return ty.floatBits(target) > 64,
17591759 .ErrorUnion => {
1760 const pl_ty = ty.errorUnionPayload();
1760 const pl_ty = ty.errorUnionPayload(mod);
17611761 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
17621762 return false;
17631763 }
......@@ -2256,7 +2256,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
22562256 const result_value = result_value: {
22572257 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and !ret_ty.isError(mod)) {
22582258 break :result_value WValue{ .none = {} };
2259 } else if (ret_ty.isNoReturn()) {
2259 } else if (ret_ty.isNoReturn(mod)) {
22602260 try func.addTag(.@"unreachable");
22612261 break :result_value WValue{ .none = {} };
22622262 } else if (first_param_sret) {
......@@ -2346,7 +2346,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
23462346 const abi_size = ty.abiSize(mod);
23472347 switch (ty.zigTypeTag(mod)) {
23482348 .ErrorUnion => {
2349 const pl_ty = ty.errorUnionPayload();
2349 const pl_ty = ty.errorUnionPayload(mod);
23502350 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
23512351 return func.store(lhs, rhs, Type.anyerror, 0);
23522352 }
......@@ -3111,8 +3111,8 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
31113111 else => return WValue{ .imm32 = 0 },
31123112 },
31133113 .ErrorUnion => {
3114 const error_type = ty.errorUnionSet();
3115 const payload_type = ty.errorUnionPayload();
3114 const error_type = ty.errorUnionSet(mod);
3115 const payload_type = ty.errorUnionPayload(mod);
31163116 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
31173117 // We use the error type directly as the type.
31183118 const is_pl = val.errorUnionIsPayload();
......@@ -3916,10 +3916,10 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro
39163916 const un_op = func.air.instructions.items(.data)[inst].un_op;
39173917 const operand = try func.resolveInst(un_op);
39183918 const err_union_ty = func.typeOf(un_op);
3919 const pl_ty = err_union_ty.errorUnionPayload();
3919 const pl_ty = err_union_ty.errorUnionPayload(mod);
39203920
39213921 const result = result: {
3922 if (err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {
3922 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
39233923 switch (opcode) {
39243924 .i32_ne => break :result WValue{ .imm32 = 0 },
39253925 .i32_eq => break :result WValue{ .imm32 = 1 },
......@@ -3953,7 +3953,7 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo
39533953 const operand = try func.resolveInst(ty_op.operand);
39543954 const op_ty = func.typeOf(ty_op.operand);
39553955 const err_ty = if (op_is_ptr) op_ty.childType(mod) else op_ty;
3956 const payload_ty = err_ty.errorUnionPayload();
3956 const payload_ty = err_ty.errorUnionPayload(mod);
39573957
39583958 const result = result: {
39593959 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
......@@ -3981,10 +3981,10 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
39813981 const operand = try func.resolveInst(ty_op.operand);
39823982 const op_ty = func.typeOf(ty_op.operand);
39833983 const err_ty = if (op_is_ptr) op_ty.childType(mod) else op_ty;
3984 const payload_ty = err_ty.errorUnionPayload();
3984 const payload_ty = err_ty.errorUnionPayload(mod);
39853985
39863986 const result = result: {
3987 if (err_ty.errorUnionSet().errorSetIsEmpty(mod)) {
3987 if (err_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
39883988 break :result WValue{ .imm32 = 0 };
39893989 }
39903990
......@@ -4031,7 +4031,7 @@ fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
40314031
40324032 const operand = try func.resolveInst(ty_op.operand);
40334033 const err_ty = func.air.getRefType(ty_op.ty);
4034 const pl_ty = err_ty.errorUnionPayload();
4034 const pl_ty = err_ty.errorUnionPayload(mod);
40354035
40364036 const result = result: {
40374037 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
......@@ -4044,7 +4044,7 @@ fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
40444044
40454045 // write 'undefined' to the payload
40464046 const payload_ptr = try func.buildPointerOffset(err_union, @intCast(u32, errUnionPayloadOffset(pl_ty, mod)), .new);
4047 const len = @intCast(u32, err_ty.errorUnionPayload().abiSize(mod));
4047 const len = @intCast(u32, err_ty.errorUnionPayload(mod).abiSize(mod));
40484048 try func.memset(Type.u8, payload_ptr, .{ .imm32 = len }, .{ .imm32 = 0xaa });
40494049
40504050 break :result err_union;
......@@ -5362,7 +5362,7 @@ fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
53625362 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
53635363
53645364 const err_set_ty = func.typeOf(ty_op.operand).childType(mod);
5365 const payload_ty = err_set_ty.errorUnionPayload();
5365 const payload_ty = err_set_ty.errorUnionPayload(mod);
53665366 const operand = try func.resolveInst(ty_op.operand);
53675367
53685368 // set error-tag to '0' to annotate error union is non-error
......@@ -6177,10 +6177,10 @@ fn lowerTry(
61776177 return func.fail("TODO: lowerTry for pointers", .{});
61786178 }
61796179
6180 const pl_ty = err_union_ty.errorUnionPayload();
6180 const pl_ty = err_union_ty.errorUnionPayload(mod);
61816181 const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime(mod);
61826182
6183 if (!err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {
6183 if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
61846184 // Block we can jump out of when error is not set
61856185 try func.startBlock(.block, wasm.block_empty);
61866186
......@@ -6742,7 +6742,7 @@ fn callIntrinsic(
67426742
67436743 if (!return_type.hasRuntimeBitsIgnoreComptime(mod)) {
67446744 return WValue.none;
6745 } else if (return_type.isNoReturn()) {
6745 } else if (return_type.isNoReturn(mod)) {
67466746 try func.addTag(.@"unreachable");
67476747 return WValue.none;
67486748 } else if (want_sret_param) {
......@@ -6941,20 +6941,21 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
69416941}
69426942
69436943fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6944 const mod = func.bin_file.base.options.module.?;
69446945 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
69456946
69466947 const operand = try func.resolveInst(ty_op.operand);
69476948 const error_set_ty = func.air.getRefType(ty_op.ty);
69486949 const result = try func.allocLocal(Type.bool);
69496950
6950 const names = error_set_ty.errorSetNames();
6951 const names = error_set_ty.errorSetNames(mod);
69516952 var values = try std.ArrayList(u32).initCapacity(func.gpa, names.len);
69526953 defer values.deinit();
69536954
6954 const mod = func.bin_file.base.options.module.?;
69556955 var lowest: ?u32 = null;
69566956 var highest: ?u32 = null;
6957 for (names) |name| {
6957 for (names) |name_ip| {
6958 const name = mod.intern_pool.stringToSlice(name_ip);
69586959 const err_int = mod.global_error_set.get(name).?;
69596960 if (lowest) |*l| {
69606961 if (err_int < l.*) {
src/arch/x86_64/CodeGen.zig+14-14
......@@ -3612,8 +3612,8 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
36123612 const mod = self.bin_file.options.module.?;
36133613 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
36143614 const err_union_ty = self.typeOf(ty_op.operand);
3615 const err_ty = err_union_ty.errorUnionSet();
3616 const payload_ty = err_union_ty.errorUnionPayload();
3615 const err_ty = err_union_ty.errorUnionSet(mod);
3616 const payload_ty = err_union_ty.errorUnionPayload(mod);
36173617 const operand = try self.resolveInst(ty_op.operand);
36183618
36193619 const result: MCValue = result: {
......@@ -3671,7 +3671,7 @@ fn genUnwrapErrorUnionPayloadMir(
36713671 err_union: MCValue,
36723672) !MCValue {
36733673 const mod = self.bin_file.options.module.?;
3674 const payload_ty = err_union_ty.errorUnionPayload();
3674 const payload_ty = err_union_ty.errorUnionPayload(mod);
36753675
36763676 const result: MCValue = result: {
36773677 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;
......@@ -3731,8 +3731,8 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {
37313731 defer self.register_manager.unlockReg(dst_lock);
37323732
37333733 const eu_ty = src_ty.childType(mod);
3734 const pl_ty = eu_ty.errorUnionPayload();
3735 const err_ty = eu_ty.errorUnionSet();
3734 const pl_ty = eu_ty.errorUnionPayload(mod);
3735 const err_ty = eu_ty.errorUnionSet(mod);
37363736 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, mod));
37373737 const err_abi_size = @intCast(u32, err_ty.abiSize(mod));
37383738 try self.asmRegisterMemory(
......@@ -3771,7 +3771,7 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
37713771 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
37723772
37733773 const eu_ty = src_ty.childType(mod);
3774 const pl_ty = eu_ty.errorUnionPayload();
3774 const pl_ty = eu_ty.errorUnionPayload(mod);
37753775 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, mod));
37763776 const dst_abi_size = @intCast(u32, dst_ty.abiSize(mod));
37773777 try self.asmRegisterMemory(
......@@ -3797,8 +3797,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
37973797 defer self.register_manager.unlockReg(src_lock);
37983798
37993799 const eu_ty = src_ty.childType(mod);
3800 const pl_ty = eu_ty.errorUnionPayload();
3801 const err_ty = eu_ty.errorUnionSet();
3800 const pl_ty = eu_ty.errorUnionPayload(mod);
3801 const err_ty = eu_ty.errorUnionSet(mod);
38023802 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, mod));
38033803 const err_abi_size = @intCast(u32, err_ty.abiSize(mod));
38043804 try self.asmMemoryImmediate(
......@@ -3901,8 +3901,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
39013901 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
39023902
39033903 const eu_ty = self.air.getRefType(ty_op.ty);
3904 const pl_ty = eu_ty.errorUnionPayload();
3905 const err_ty = eu_ty.errorUnionSet();
3904 const pl_ty = eu_ty.errorUnionPayload(mod);
3905 const err_ty = eu_ty.errorUnionSet(mod);
39063906 const operand = try self.resolveInst(ty_op.operand);
39073907
39083908 const result: MCValue = result: {
......@@ -3924,8 +3924,8 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
39243924 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
39253925
39263926 const eu_ty = self.air.getRefType(ty_op.ty);
3927 const pl_ty = eu_ty.errorUnionPayload();
3928 const err_ty = eu_ty.errorUnionSet();
3927 const pl_ty = eu_ty.errorUnionPayload(mod);
3928 const err_ty = eu_ty.errorUnionSet(mod);
39293929
39303930 const result: MCValue = result: {
39313931 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result try self.resolveInst(ty_op.operand);
......@@ -8782,7 +8782,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
87828782
87838783fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !MCValue {
87848784 const mod = self.bin_file.options.module.?;
8785 const err_type = ty.errorUnionSet();
8785 const err_type = ty.errorUnionSet(mod);
87868786
87878787 if (err_type.errorSetIsEmpty(mod)) {
87888788 return MCValue{ .immediate = 0 }; // always false
......@@ -8793,7 +8793,7 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !
87938793 self.eflags_inst = inst;
87948794 }
87958795
8796 const err_off = errUnionErrorOffset(ty.errorUnionPayload(), mod);
8796 const err_off = errUnionErrorOffset(ty.errorUnionPayload(mod), mod);
87978797 switch (operand) {
87988798 .register => |reg| {
87998799 const eu_lock = self.register_manager.lockReg(reg);
src/codegen.zig+6-6
......@@ -139,7 +139,7 @@ pub fn generateLazySymbol(
139139 return generateLazyFunction(bin_file, src_loc, lazy_sym, code, debug_output);
140140 }
141141
142 if (lazy_sym.ty.isAnyError()) {
142 if (lazy_sym.ty.isAnyError(mod)) {
143143 alignment.* = 4;
144144 const err_names = mod.error_name_list.items;
145145 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, err_names.len), endian);
......@@ -670,8 +670,8 @@ pub fn generateSymbol(
670670 return Result.ok;
671671 },
672672 .ErrorUnion => {
673 const error_ty = typed_value.ty.errorUnionSet();
674 const payload_ty = typed_value.ty.errorUnionPayload();
673 const error_ty = typed_value.ty.errorUnionSet(mod);
674 const payload_ty = typed_value.ty.errorUnionPayload(mod);
675675 const is_payload = typed_value.val.errorUnionIsPayload();
676676
677677 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
......@@ -894,7 +894,7 @@ fn lowerParentPtr(
894894 },
895895 .eu_payload_ptr => {
896896 const eu_payload_ptr = parent_ptr.castTag(.eu_payload_ptr).?.data;
897 const pl_ty = eu_payload_ptr.container_ty.errorUnionPayload();
897 const pl_ty = eu_payload_ptr.container_ty.errorUnionPayload(mod);
898898 return lowerParentPtr(
899899 bin_file,
900900 src_loc,
......@@ -1249,8 +1249,8 @@ pub fn genTypedValue(
12491249 }
12501250 },
12511251 .ErrorUnion => {
1252 const error_type = typed_value.ty.errorUnionSet();
1253 const payload_type = typed_value.ty.errorUnionPayload();
1252 const error_type = typed_value.ty.errorUnionSet(mod);
1253 const payload_type = typed_value.ty.errorUnionPayload(mod);
12541254 const is_pl = typed_value.val.errorUnionIsPayload();
12551255
12561256 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
src/codegen/c.zig+20-19
......@@ -465,7 +465,7 @@ pub const Function = struct {
465465 }),
466466 },
467467 .data = switch (key) {
468 .tag_name => .{ .tag_name = try data.tag_name.copy(arena) },
468 .tag_name => .{ .tag_name = data.tag_name },
469469 .never_tail => .{ .never_tail = data.never_tail },
470470 .never_inline => .{ .never_inline = data.never_inline },
471471 },
......@@ -862,8 +862,8 @@ pub const DeclGen = struct {
862862 return writer.writeByte('}');
863863 },
864864 .ErrorUnion => {
865 const payload_ty = ty.errorUnionPayload();
866 const error_ty = ty.errorUnionSet();
865 const payload_ty = ty.errorUnionPayload(mod);
866 const error_ty = ty.errorUnionSet(mod);
867867
868868 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
869869 return dg.renderValue(writer, error_ty, val, location);
......@@ -1252,8 +1252,8 @@ pub const DeclGen = struct {
12521252 }
12531253 },
12541254 .ErrorUnion => {
1255 const payload_ty = ty.errorUnionPayload();
1256 const error_ty = ty.errorUnionSet();
1255 const payload_ty = ty.errorUnionPayload(mod);
1256 const error_ty = ty.errorUnionSet(mod);
12571257 const error_val = if (val.errorUnionIsPayload()) try mod.intValue(Type.anyerror, 0) else val;
12581258
12591259 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
......@@ -4252,6 +4252,7 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
42524252}
42534253
42544254fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {
4255 const mod = f.object.dg.module;
42554256 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
42564257 const extra = f.air.extraData(Air.Block, ty_pl.payload);
42574258 const body = f.air.extra[extra.end..][0..extra.data.body_len];
......@@ -4284,7 +4285,7 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {
42844285 try f.object.indent_writer.insertNewline();
42854286
42864287 // noreturn blocks have no `br` instructions reaching them, so we don't want a label
4287 if (!f.typeOfIndex(inst).isNoReturn()) {
4288 if (!f.typeOfIndex(inst).isNoReturn(mod)) {
42884289 // label must be followed by an expression, include an empty one.
42894290 try writer.print("zig_block_{d}:;\n", .{block_id});
42904291 }
......@@ -4322,10 +4323,10 @@ fn lowerTry(
43224323 const inst_ty = f.typeOfIndex(inst);
43234324 const liveness_condbr = f.liveness.getCondBr(inst);
43244325 const writer = f.object.writer();
4325 const payload_ty = err_union_ty.errorUnionPayload();
4326 const payload_ty = err_union_ty.errorUnionPayload(mod);
43264327 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);
43274328
4328 if (!err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {
4329 if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
43294330 try writer.writeAll("if (");
43304331 if (!payload_has_bits) {
43314332 if (is_ptr)
......@@ -5500,8 +5501,8 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
55005501
55015502 const operand_is_ptr = operand_ty.zigTypeTag(mod) == .Pointer;
55025503 const error_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
5503 const error_ty = error_union_ty.errorUnionSet();
5504 const payload_ty = error_union_ty.errorUnionPayload();
5504 const error_ty = error_union_ty.errorUnionSet(mod);
5505 const payload_ty = error_union_ty.errorUnionPayload(mod);
55055506 const local = try f.allocLocal(inst, inst_ty);
55065507
55075508 if (!payload_ty.hasRuntimeBits(mod) and operand == .local and operand.local == local.new_local) {
......@@ -5539,7 +5540,7 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
55395540 const error_union_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty;
55405541
55415542 const writer = f.object.writer();
5542 if (!error_union_ty.errorUnionPayload().hasRuntimeBits(mod)) {
5543 if (!error_union_ty.errorUnionPayload(mod).hasRuntimeBits(mod)) {
55435544 if (!is_ptr) return .none;
55445545
55455546 const local = try f.allocLocal(inst, inst_ty);
......@@ -5601,9 +5602,9 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
56015602 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
56025603
56035604 const inst_ty = f.typeOfIndex(inst);
5604 const payload_ty = inst_ty.errorUnionPayload();
5605 const payload_ty = inst_ty.errorUnionPayload(mod);
56055606 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(mod);
5606 const err_ty = inst_ty.errorUnionSet();
5607 const err_ty = inst_ty.errorUnionSet(mod);
56075608 const err = try f.resolveInst(ty_op.operand);
56085609 try reap(f, inst, &.{ty_op.operand});
56095610
......@@ -5642,8 +5643,8 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
56425643 const operand = try f.resolveInst(ty_op.operand);
56435644 const error_union_ty = f.typeOf(ty_op.operand).childType(mod);
56445645
5645 const error_ty = error_union_ty.errorUnionSet();
5646 const payload_ty = error_union_ty.errorUnionPayload();
5646 const error_ty = error_union_ty.errorUnionSet(mod);
5647 const payload_ty = error_union_ty.errorUnionPayload(mod);
56475648
56485649 // First, set the non-error value.
56495650 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
......@@ -5691,10 +5692,10 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
56915692 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
56925693
56935694 const inst_ty = f.typeOfIndex(inst);
5694 const payload_ty = inst_ty.errorUnionPayload();
5695 const payload_ty = inst_ty.errorUnionPayload(mod);
56955696 const payload = try f.resolveInst(ty_op.operand);
56965697 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(mod);
5697 const err_ty = inst_ty.errorUnionSet();
5698 const err_ty = inst_ty.errorUnionSet(mod);
56985699 try reap(f, inst, &.{ty_op.operand});
56995700
57005701 const writer = f.object.writer();
......@@ -5729,8 +5730,8 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
57295730 const operand_ty = f.typeOf(un_op);
57305731 const local = try f.allocLocal(inst, Type.bool);
57315732 const err_union_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty;
5732 const payload_ty = err_union_ty.errorUnionPayload();
5733 const error_ty = err_union_ty.errorUnionSet();
5733 const payload_ty = err_union_ty.errorUnionPayload(mod);
5734 const error_ty = err_union_ty.errorUnionSet(mod);
57345735
57355736 try f.writeCValue(writer, local, .Other);
57365737 try writer.writeAll(" = ");
src/codegen/c/type.zig+2-2
......@@ -1680,14 +1680,14 @@ pub const CType = extern union {
16801680 .complete, .parameter, .global => try lookup.typeToIndex(ty, .forward),
16811681 .payload => unreachable,
16821682 }) |fwd_idx| {
1683 const payload_ty = ty.errorUnionPayload();
1683 const payload_ty = ty.errorUnionPayload(mod);
16841684 if (try lookup.typeToIndex(payload_ty, switch (kind) {
16851685 .forward, .forward_parameter => .forward,
16861686 .complete, .parameter => .complete,
16871687 .global => .global,
16881688 .payload => unreachable,
16891689 })) |payload_idx| {
1690 const error_ty = ty.errorUnionSet();
1690 const error_ty = ty.errorUnionSet(mod);
16911691 if (payload_idx == Tag.void.toIndex()) {
16921692 try self.initType(error_ty, kind, lookup);
16931693 } else if (try lookup.typeToIndex(error_ty, kind)) |error_idx| {
src/codegen/llvm.zig+27-47
......@@ -362,15 +362,11 @@ pub const Object = struct {
362362 decl_map: std.AutoHashMapUnmanaged(Module.Decl.Index, *llvm.Value),
363363 /// Serves the same purpose as `decl_map` but only used for the `is_named_enum_value` instruction.
364364 named_enum_map: std.AutoHashMapUnmanaged(Module.Decl.Index, *llvm.Value),
365 /// Maps Zig types to LLVM types. The table memory itself is backed by the GPA of
366 /// the compiler, but the Type/Value memory here is backed by `type_map_arena`.
367 /// TODO we need to remove entries from this map in response to incremental compilation
368 /// but I think the frontend won't tell us about types that get deleted because
369 /// hasRuntimeBits() is false for types.
365 /// Maps Zig types to LLVM types. The table memory is backed by the GPA of
366 /// the compiler.
367 /// TODO when InternPool garbage collection is implemented, this map needs
368 /// to be garbage collected as well.
370369 type_map: TypeMap,
371 /// The backing memory for `type_map`. Periodically garbage collected after flush().
372 /// The code for doing the periodical GC is not yet implemented.
373 type_map_arena: std.heap.ArenaAllocator,
374370 di_type_map: DITypeMap,
375371 /// The LLVM global table which holds the names corresponding to Zig errors.
376372 /// Note that the values are not added until flushModule, when all errors in
......@@ -381,12 +377,7 @@ pub const Object = struct {
381377 /// name collision.
382378 extern_collisions: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, void),
383379
384 pub const TypeMap = std.HashMapUnmanaged(
385 Type,
386 *llvm.Type,
387 Type.HashContext64,
388 std.hash_map.default_max_load_percentage,
389 );
380 pub const TypeMap = std.AutoHashMapUnmanaged(InternPool.Index, *llvm.Type);
390381
391382 /// This is an ArrayHashMap as opposed to a HashMap because in `flushModule` we
392383 /// want to iterate over it while adding entries to it.
......@@ -543,7 +534,6 @@ pub const Object = struct {
543534 .decl_map = .{},
544535 .named_enum_map = .{},
545536 .type_map = .{},
546 .type_map_arena = std.heap.ArenaAllocator.init(gpa),
547537 .di_type_map = .{},
548538 .error_name_table = null,
549539 .extern_collisions = .{},
......@@ -563,7 +553,6 @@ pub const Object = struct {
563553 self.decl_map.deinit(gpa);
564554 self.named_enum_map.deinit(gpa);
565555 self.type_map.deinit(gpa);
566 self.type_map_arena.deinit();
567556 self.extern_collisions.deinit(gpa);
568557 self.* = undefined;
569558 }
......@@ -1462,9 +1451,6 @@ pub const Object = struct {
14621451 return o.lowerDebugTypeImpl(entry, resolve, di_type);
14631452 }
14641453 errdefer assert(o.di_type_map.orderedRemoveContext(ty, .{ .mod = o.module }));
1465 // The Type memory is ephemeral; since we want to store a longer-lived
1466 // reference, we need to copy it here.
1467 gop.key_ptr.* = try ty.copy(o.type_map_arena.allocator());
14681454 const entry: Object.DITypeMap.Entry = .{
14691455 .key_ptr = gop.key_ptr,
14701456 .value_ptr = gop.value_ptr,
......@@ -1868,7 +1854,7 @@ pub const Object = struct {
18681854 return full_di_ty;
18691855 },
18701856 .ErrorUnion => {
1871 const payload_ty = ty.errorUnionPayload();
1857 const payload_ty = ty.errorUnionPayload(mod);
18721858 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
18731859 const err_set_di_ty = try o.lowerDebugType(Type.anyerror, .full);
18741860 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
......@@ -2823,7 +2809,7 @@ pub const DeclGen = struct {
28232809 .Opaque => {
28242810 if (t.ip_index == .anyopaque_type) return dg.context.intType(8);
28252811
2826 const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = mod });
2812 const gop = try dg.object.type_map.getOrPut(gpa, t.toIntern());
28272813 if (gop.found_existing) return gop.value_ptr.*;
28282814
28292815 const opaque_type = mod.intern_pool.indexToKey(t.ip_index).opaque_type;
......@@ -2869,7 +2855,7 @@ pub const DeclGen = struct {
28692855 return dg.context.structType(&fields_buf, 3, .False);
28702856 },
28712857 .ErrorUnion => {
2872 const payload_ty = t.errorUnionPayload();
2858 const payload_ty = t.errorUnionPayload(mod);
28732859 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
28742860 return try dg.lowerType(Type.anyerror);
28752861 }
......@@ -2913,13 +2899,9 @@ pub const DeclGen = struct {
29132899 },
29142900 .ErrorSet => return dg.context.intType(16),
29152901 .Struct => {
2916 const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = mod });
2902 const gop = try dg.object.type_map.getOrPut(gpa, t.toIntern());
29172903 if (gop.found_existing) return gop.value_ptr.*;
29182904
2919 // The Type memory is ephemeral; since we want to store a longer-lived
2920 // reference, we need to copy it here.
2921 gop.key_ptr.* = try t.copy(dg.object.type_map_arena.allocator());
2922
29232905 const struct_type = switch (mod.intern_pool.indexToKey(t.ip_index)) {
29242906 .anon_struct_type => |tuple| {
29252907 const llvm_struct_ty = dg.context.structCreateNamed("");
......@@ -3041,13 +3023,9 @@ pub const DeclGen = struct {
30413023 return llvm_struct_ty;
30423024 },
30433025 .Union => {
3044 const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = mod });
3026 const gop = try dg.object.type_map.getOrPut(gpa, t.toIntern());
30453027 if (gop.found_existing) return gop.value_ptr.*;
30463028
3047 // The Type memory is ephemeral; since we want to store a longer-lived
3048 // reference, we need to copy it here.
3049 gop.key_ptr.* = try t.copy(dg.object.type_map_arena.allocator());
3050
30513029 const layout = t.unionGetLayout(mod);
30523030 const union_obj = mod.typeToUnion(t).?;
30533031
......@@ -3571,7 +3549,7 @@ pub const DeclGen = struct {
35713549 }
35723550 },
35733551 .ErrorUnion => {
3574 const payload_type = tv.ty.errorUnionPayload();
3552 const payload_type = tv.ty.errorUnionPayload(mod);
35753553 const is_pl = tv.val.errorUnionIsPayload();
35763554
35773555 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
......@@ -4130,7 +4108,7 @@ pub const DeclGen = struct {
41304108 const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
41314109 const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, true);
41324110
4133 const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload();
4111 const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload(mod);
41344112 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
41354113 // In this case, we represent pointer to error union the same as pointer
41364114 // to the payload.
......@@ -5368,7 +5346,7 @@ pub const FuncGen = struct {
53685346 const inst_ty = self.typeOfIndex(inst);
53695347 const parent_bb = self.context.createBasicBlock("Block");
53705348
5371 if (inst_ty.isNoReturn()) {
5349 if (inst_ty.isNoReturn(mod)) {
53725350 try self.genBody(body);
53735351 return null;
53745352 }
......@@ -5490,11 +5468,11 @@ pub const FuncGen = struct {
54905468 is_unused: bool,
54915469 ) !?*llvm.Value {
54925470 const mod = fg.dg.module;
5493 const payload_ty = err_union_ty.errorUnionPayload();
5471 const payload_ty = err_union_ty.errorUnionPayload(mod);
54945472 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);
54955473 const err_union_llvm_ty = try fg.dg.lowerType(err_union_ty);
54965474
5497 if (!err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {
5475 if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
54985476 const is_err = err: {
54995477 const err_set_ty = try fg.dg.lowerType(Type.anyerror);
55005478 const zero = err_set_ty.constNull();
......@@ -5601,6 +5579,7 @@ pub const FuncGen = struct {
56015579 }
56025580
56035581 fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5582 const mod = self.dg.module;
56045583 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
56055584 const loop = self.air.extraData(Air.Block, ty_pl.payload);
56065585 const body = self.air.extra[loop.end..][0..loop.data.body_len];
......@@ -5616,7 +5595,7 @@ pub const FuncGen = struct {
56165595 // would have been emitted already. Also the main loop in genBody can
56175596 // be while(true) instead of for(body), which will eliminate 1 branch on
56185597 // a hot path.
5619 if (body.len == 0 or !self.typeOfIndex(body[body.len - 1]).isNoReturn()) {
5598 if (body.len == 0 or !self.typeOfIndex(body[body.len - 1]).isNoReturn(mod)) {
56205599 _ = self.builder.buildBr(loop_block);
56215600 }
56225601 return null;
......@@ -6674,11 +6653,11 @@ pub const FuncGen = struct {
66746653 const operand = try self.resolveInst(un_op);
66756654 const operand_ty = self.typeOf(un_op);
66766655 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
6677 const payload_ty = err_union_ty.errorUnionPayload();
6656 const payload_ty = err_union_ty.errorUnionPayload(mod);
66786657 const err_set_ty = try self.dg.lowerType(Type.anyerror);
66796658 const zero = err_set_ty.constNull();
66806659
6681 if (err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {
6660 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
66826661 const llvm_i1 = self.context.intType(1);
66836662 switch (op) {
66846663 .EQ => return llvm_i1.constInt(1, .False), // 0 == 0
......@@ -6825,7 +6804,7 @@ pub const FuncGen = struct {
68256804 const operand = try self.resolveInst(ty_op.operand);
68266805 const operand_ty = self.typeOf(ty_op.operand);
68276806 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
6828 if (err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {
6807 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
68296808 const err_llvm_ty = try self.dg.lowerType(Type.anyerror);
68306809 if (operand_is_ptr) {
68316810 return operand;
......@@ -6836,7 +6815,7 @@ pub const FuncGen = struct {
68366815
68376816 const err_set_llvm_ty = try self.dg.lowerType(Type.anyerror);
68386817
6839 const payload_ty = err_union_ty.errorUnionPayload();
6818 const payload_ty = err_union_ty.errorUnionPayload(mod);
68406819 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
68416820 if (!operand_is_ptr) return operand;
68426821 return self.builder.buildLoad(err_set_llvm_ty, operand, "");
......@@ -6859,7 +6838,7 @@ pub const FuncGen = struct {
68596838 const operand = try self.resolveInst(ty_op.operand);
68606839 const err_union_ty = self.typeOf(ty_op.operand).childType(mod);
68616840
6862 const payload_ty = err_union_ty.errorUnionPayload();
6841 const payload_ty = err_union_ty.errorUnionPayload(mod);
68636842 const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = try mod.intValue(Type.err_int, 0) });
68646843 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
68656844 _ = self.builder.buildStore(non_error_val, operand);
......@@ -6968,7 +6947,7 @@ pub const FuncGen = struct {
69686947 const mod = self.dg.module;
69696948 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
69706949 const err_un_ty = self.typeOfIndex(inst);
6971 const payload_ty = err_un_ty.errorUnionPayload();
6950 const payload_ty = err_un_ty.errorUnionPayload(mod);
69726951 const operand = try self.resolveInst(ty_op.operand);
69736952 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
69746953 return operand;
......@@ -8787,13 +8766,14 @@ pub const FuncGen = struct {
87878766 const operand = try self.resolveInst(ty_op.operand);
87888767 const error_set_ty = self.air.getRefType(ty_op.ty);
87898768
8790 const names = error_set_ty.errorSetNames();
8769 const names = error_set_ty.errorSetNames(mod);
87918770 const valid_block = self.context.appendBasicBlock(self.llvm_func, "Valid");
87928771 const invalid_block = self.context.appendBasicBlock(self.llvm_func, "Invalid");
87938772 const end_block = self.context.appendBasicBlock(self.llvm_func, "End");
87948773 const switch_instr = self.builder.buildSwitch(operand, invalid_block, @intCast(c_uint, names.len));
87958774
8796 for (names) |name| {
8775 for (names) |name_ip| {
8776 const name = mod.intern_pool.stringToSlice(name_ip);
87978777 const err_int = mod.global_error_set.get(name).?;
87988778 const this_tag_int_value = try self.dg.lowerValue(.{
87998779 .ty = Type.err_int,
......@@ -11095,7 +11075,7 @@ fn isByRef(ty: Type, mod: *Module) bool {
1109511075 else => return ty.hasRuntimeBits(mod),
1109611076 },
1109711077 .ErrorUnion => {
11098 const payload_ty = ty.errorUnionPayload();
11078 const payload_ty = ty.errorUnionPayload(mod);
1109911079 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1110011080 return false;
1110111081 }
src/codegen/spirv.zig+7-6
......@@ -801,7 +801,7 @@ pub const DeclGen = struct {
801801 },
802802 },
803803 .ErrorUnion => {
804 const payload_ty = ty.errorUnionPayload();
804 const payload_ty = ty.errorUnionPayload(mod);
805805 const is_pl = val.errorUnionIsPayload();
806806 const error_val = if (!is_pl) val else try mod.intValue(Type.anyerror, 0);
807807
......@@ -1365,7 +1365,7 @@ pub const DeclGen = struct {
13651365 .Union => return try self.resolveUnionType(ty, null),
13661366 .ErrorSet => return try self.intType(.unsigned, 16),
13671367 .ErrorUnion => {
1368 const payload_ty = ty.errorUnionPayload();
1368 const payload_ty = ty.errorUnionPayload(mod);
13691369 const error_ty_ref = try self.resolveType(Type.anyerror, .indirect);
13701370
13711371 const eu_layout = self.errorUnionLayout(payload_ty);
......@@ -2875,7 +2875,7 @@ pub const DeclGen = struct {
28752875
28762876 const eu_layout = self.errorUnionLayout(payload_ty);
28772877
2878 if (!err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {
2878 if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
28792879 const err_id = if (eu_layout.payload_has_bits)
28802880 try self.extractField(Type.anyerror, err_union_id, eu_layout.errorFieldIndex())
28812881 else
......@@ -2929,12 +2929,12 @@ pub const DeclGen = struct {
29292929 const err_union_ty = self.typeOf(ty_op.operand);
29302930 const err_ty_ref = try self.resolveType(Type.anyerror, .direct);
29312931
2932 if (err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {
2932 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
29332933 // No error possible, so just return undefined.
29342934 return try self.spv.constUndef(err_ty_ref);
29352935 }
29362936
2937 const payload_ty = err_union_ty.errorUnionPayload();
2937 const payload_ty = err_union_ty.errorUnionPayload(mod);
29382938 const eu_layout = self.errorUnionLayout(payload_ty);
29392939
29402940 if (!eu_layout.payload_has_bits) {
......@@ -2948,9 +2948,10 @@ pub const DeclGen = struct {
29482948 fn airWrapErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
29492949 if (self.liveness.isUnused(inst)) return null;
29502950
2951 const mod = self.module;
29512952 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
29522953 const err_union_ty = self.typeOfIndex(inst);
2953 const payload_ty = err_union_ty.errorUnionPayload();
2954 const payload_ty = err_union_ty.errorUnionPayload(mod);
29542955 const operand_id = try self.resolve(ty_op.operand);
29552956 const eu_layout = self.errorUnionLayout(payload_ty);
29562957
src/link/Dwarf.zig+31-23
......@@ -18,6 +18,7 @@ const LinkBlock = File.LinkBlock;
1818const LinkFn = File.LinkFn;
1919const LinkerLoad = @import("../codegen.zig").LinkerLoad;
2020const Module = @import("../Module.zig");
21const InternPool = @import("../InternPool.zig");
2122const StringTable = @import("strtab.zig").StringTable;
2223const Type = @import("../type.zig").Type;
2324const Value = @import("../value.zig").Value;
......@@ -518,9 +519,9 @@ pub const DeclState = struct {
518519 );
519520 },
520521 .ErrorUnion => {
521 const error_ty = ty.errorUnionSet();
522 const payload_ty = ty.errorUnionPayload();
523 const payload_align = if (payload_ty.isNoReturn()) 0 else payload_ty.abiAlignment(mod);
522 const error_ty = ty.errorUnionSet(mod);
523 const payload_ty = ty.errorUnionPayload(mod);
524 const payload_align = if (payload_ty.isNoReturn(mod)) 0 else payload_ty.abiAlignment(mod);
524525 const error_align = Type.anyerror.abiAlignment(mod);
525526 const abi_size = ty.abiSize(mod);
526527 const payload_off = if (error_align >= payload_align) Type.anyerror.abiSize(mod) else 0;
......@@ -534,7 +535,7 @@ pub const DeclState = struct {
534535 const name = try ty.nameAllocArena(arena, mod);
535536 try dbg_info_buffer.writer().print("{s}\x00", .{name});
536537
537 if (!payload_ty.isNoReturn()) {
538 if (!payload_ty.isNoReturn(mod)) {
538539 // DW.AT.member
539540 try dbg_info_buffer.ensureUnusedCapacity(7);
540541 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
......@@ -1266,10 +1267,11 @@ pub fn commitDeclState(
12661267 const symbol = &decl_state.abbrev_table.items[sym_index];
12671268 const ty = symbol.type;
12681269 const deferred: bool = blk: {
1269 if (ty.isAnyError()) break :blk true;
1270 switch (ty.tag()) {
1271 .error_set_inferred => {
1272 if (!ty.castTag(.error_set_inferred).?.data.is_resolved) break :blk true;
1270 if (ty.isAnyError(mod)) break :blk true;
1271 switch (mod.intern_pool.indexToKey(ty.ip_index)) {
1272 .inferred_error_set_type => |ies_index| {
1273 const ies = mod.inferredErrorSetPtr(ies_index);
1274 if (!ies.is_resolved) break :blk true;
12731275 },
12741276 else => {},
12751277 }
......@@ -1290,10 +1292,11 @@ pub fn commitDeclState(
12901292 const symbol = decl_state.abbrev_table.items[target];
12911293 const ty = symbol.type;
12921294 const deferred: bool = blk: {
1293 if (ty.isAnyError()) break :blk true;
1294 switch (ty.tag()) {
1295 .error_set_inferred => {
1296 if (!ty.castTag(.error_set_inferred).?.data.is_resolved) break :blk true;
1295 if (ty.isAnyError(mod)) break :blk true;
1296 switch (mod.intern_pool.indexToKey(ty.ip_index)) {
1297 .inferred_error_set_type => |ies_index| {
1298 const ies = mod.inferredErrorSetPtr(ies_index);
1299 if (!ies.is_resolved) break :blk true;
12971300 },
12981301 else => {},
12991302 }
......@@ -2529,18 +2532,22 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
25292532 defer arena_alloc.deinit();
25302533 const arena = arena_alloc.allocator();
25312534
2532 const error_set = try arena.create(Module.ErrorSet);
2533 const error_ty = try Type.Tag.error_set.create(arena, error_set);
2534 var names = Module.ErrorSet.NameMap{};
2535 try names.ensureUnusedCapacity(arena, module.global_error_set.count());
2536 var it = module.global_error_set.keyIterator();
2537 while (it.next()) |key| {
2538 names.putAssumeCapacityNoClobber(key.*, {});
2535 // TODO: don't create a zig type for this, just make the dwarf info
2536 // without touching the zig type system.
2537 const names = try arena.alloc(InternPool.NullTerminatedString, module.global_error_set.count());
2538 {
2539 var it = module.global_error_set.keyIterator();
2540 var i: usize = 0;
2541 while (it.next()) |key| : (i += 1) {
2542 names[i] = module.intern_pool.getString(key.*).unwrap().?;
2543 }
25392544 }
2540 error_set.names = names;
25412545
2546 std.mem.sort(InternPool.NullTerminatedString, names, {}, InternPool.NullTerminatedString.indexLessThan);
2547
2548 const error_ty = try module.intern(.{ .error_set_type = .{ .names = names } });
25422549 var dbg_info_buffer = std.ArrayList(u8).init(arena);
2543 try addDbgInfoErrorSet(arena, module, error_ty, self.target, &dbg_info_buffer);
2550 try addDbgInfoErrorSet(arena, module, error_ty.toType(), self.target, &dbg_info_buffer);
25442551
25452552 const di_atom_index = try self.createAtom(.di_atom);
25462553 log.debug("updateDeclDebugInfoAllocation in flushModule", .{});
......@@ -2684,8 +2691,9 @@ fn addDbgInfoErrorSet(
26842691 // DW.AT.const_value, DW.FORM.data8
26852692 mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), 0, target_endian);
26862693
2687 const error_names = ty.errorSetNames();
2688 for (error_names) |error_name| {
2694 const error_names = ty.errorSetNames(mod);
2695 for (error_names) |error_name_ip| {
2696 const error_name = mod.intern_pool.stringToSlice(error_name_ip);
26892697 const kv = mod.getErrorValue(error_name) catch unreachable;
26902698 // DW.AT.enumerator
26912699 try dbg_info_buffer.ensureUnusedCapacity(error_name.len + 2 + @sizeOf(u64));
src/print_air.zig-1
......@@ -370,7 +370,6 @@ const Writer = struct {
370370 .none => switch (ty.tag()) {
371371 .inferred_alloc_const => try s.writeAll("(inferred_alloc_const)"),
372372 .inferred_alloc_mut => try s.writeAll("(inferred_alloc_mut)"),
373 else => try ty.print(s, w.module),
374373 },
375374 else => try ty.print(s, w.module),
376375 }
src/type.zig+393-866
......@@ -36,17 +36,9 @@ pub const Type = struct {
3636 pub fn zigTypeTagOrPoison(ty: Type, mod: *const Module) error{GenericPoison}!std.builtin.TypeId {
3737 switch (ty.ip_index) {
3838 .none => switch (ty.tag()) {
39 .error_set,
40 .error_set_single,
41 .error_set_inferred,
42 .error_set_merged,
43 => return .ErrorSet,
44
4539 .inferred_alloc_const,
4640 .inferred_alloc_mut,
4741 => return .Pointer,
48
49 .error_union => return .ErrorUnion,
5042 },
5143 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
5244 .int_type => .Int,
......@@ -55,6 +47,7 @@ pub const Type = struct {
5547 .vector_type => .Vector,
5648 .opt_type => .Optional,
5749 .error_union_type => .ErrorUnion,
50 .error_set_type, .inferred_error_set_type => .ErrorSet,
5851 .struct_type, .anon_struct_type => .Struct,
5952 .union_type => .Union,
6053 .opaque_type => .Opaque,
......@@ -130,9 +123,9 @@ pub const Type = struct {
130123 }
131124 }
132125
133 pub fn baseZigTypeTag(self: Type, mod: *const Module) std.builtin.TypeId {
126 pub fn baseZigTypeTag(self: Type, mod: *Module) std.builtin.TypeId {
134127 return switch (self.zigTypeTag(mod)) {
135 .ErrorUnion => self.errorUnionPayload().baseZigTypeTag(mod),
128 .ErrorUnion => self.errorUnionPayload(mod).baseZigTypeTag(mod),
136129 .Optional => {
137130 return self.optionalChild(mod).baseZigTypeTag(mod);
138131 },
......@@ -294,35 +287,6 @@ pub const Type = struct {
294287 if (a.legacy.tag_if_small_enough == b.legacy.tag_if_small_enough) return true;
295288
296289 switch (a.tag()) {
297 .error_set_inferred => {
298 // Inferred error sets are only equal if both are inferred
299 // and they share the same pointer.
300 const a_ies = a.castTag(.error_set_inferred).?.data;
301 const b_ies = (b.castTag(.error_set_inferred) orelse return false).data;
302 return a_ies == b_ies;
303 },
304
305 .error_set,
306 .error_set_single,
307 .error_set_merged,
308 => {
309 switch (b.tag()) {
310 .error_set, .error_set_single, .error_set_merged => {},
311 else => return false,
312 }
313
314 // Two resolved sets match if their error set names match.
315 // Since they are pre-sorted we compare them element-wise.
316 const a_set = a.errorSetNames();
317 const b_set = b.errorSetNames();
318 if (a_set.len != b_set.len) return false;
319 for (a_set, 0..) |a_item, i| {
320 const b_item = b_set[i];
321 if (!std.mem.eql(u8, a_item, b_item)) return false;
322 }
323 return true;
324 },
325
326290 .inferred_alloc_const,
327291 .inferred_alloc_mut,
328292 => {
......@@ -367,20 +331,6 @@ pub const Type = struct {
367331
368332 return true;
369333 },
370
371 .error_union => {
372 if (b.zigTypeTag(mod) != .ErrorUnion) return false;
373
374 const a_set = a.errorUnionSet();
375 const b_set = b.errorUnionSet();
376 if (!a_set.eql(b_set, mod)) return false;
377
378 const a_payload = a.errorUnionPayload();
379 const b_payload = b.errorUnionPayload();
380 if (!a_payload.eql(b_payload, mod)) return false;
381
382 return true;
383 },
384334 }
385335 }
386336
......@@ -399,28 +349,6 @@ pub const Type = struct {
399349 return;
400350 }
401351 switch (ty.tag()) {
402 .error_set,
403 .error_set_single,
404 .error_set_merged,
405 => {
406 // all are treated like an "error set" for hashing
407 std.hash.autoHash(hasher, std.builtin.TypeId.ErrorSet);
408 std.hash.autoHash(hasher, Tag.error_set);
409
410 const names = ty.errorSetNames();
411 std.hash.autoHash(hasher, names.len);
412 assert(std.sort.isSorted([]const u8, names, u8, std.mem.lessThan));
413 for (names) |name| hasher.update(name);
414 },
415
416 .error_set_inferred => {
417 // inferred error sets are compared using their data pointer
418 const ies: *Module.Fn.InferredErrorSet = ty.castTag(.error_set_inferred).?.data;
419 std.hash.autoHash(hasher, std.builtin.TypeId.ErrorSet);
420 std.hash.autoHash(hasher, Tag.error_set_inferred);
421 std.hash.autoHash(hasher, ies);
422 },
423
424352 .inferred_alloc_const,
425353 .inferred_alloc_mut,
426354 => {
......@@ -439,16 +367,6 @@ pub const Type = struct {
439367 std.hash.autoHash(hasher, info.@"volatile");
440368 std.hash.autoHash(hasher, info.size);
441369 },
442
443 .error_union => {
444 std.hash.autoHash(hasher, std.builtin.TypeId.ErrorUnion);
445
446 const set_ty = ty.errorUnionSet();
447 hashWithHasher(set_ty, hasher, mod);
448
449 const payload_ty = ty.errorUnionPayload();
450 hashWithHasher(payload_ty, hasher, mod);
451 },
452370 }
453371 }
454372
......@@ -484,52 +402,6 @@ pub const Type = struct {
484402 }
485403 };
486404
487 pub fn copy(self: Type, allocator: Allocator) error{OutOfMemory}!Type {
488 if (self.ip_index != .none) {
489 return Type{ .ip_index = self.ip_index, .legacy = undefined };
490 }
491 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) {
492 return Type{
493 .ip_index = .none,
494 .legacy = .{ .tag_if_small_enough = self.legacy.tag_if_small_enough },
495 };
496 } else switch (self.legacy.ptr_otherwise.tag) {
497 .inferred_alloc_const,
498 .inferred_alloc_mut,
499 => unreachable,
500
501 .error_union => {
502 const payload = self.castTag(.error_union).?.data;
503 return Tag.error_union.create(allocator, .{
504 .error_set = try payload.error_set.copy(allocator),
505 .payload = try payload.payload.copy(allocator),
506 });
507 },
508 .error_set_merged => {
509 const names = self.castTag(.error_set_merged).?.data.keys();
510 var duped_names = Module.ErrorSet.NameMap{};
511 try duped_names.ensureTotalCapacity(allocator, names.len);
512 for (names) |name| {
513 duped_names.putAssumeCapacityNoClobber(name, {});
514 }
515 return Tag.error_set_merged.create(allocator, duped_names);
516 },
517 .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),
518 .error_set_inferred => return self.copyPayloadShallow(allocator, Payload.ErrorSetInferred),
519 .error_set_single => return self.copyPayloadShallow(allocator, Payload.Name),
520 }
521 }
522
523 fn copyPayloadShallow(self: Type, allocator: Allocator, comptime T: type) error{OutOfMemory}!Type {
524 const payload = self.cast(T).?;
525 const new_payload = try allocator.create(T);
526 new_payload.* = payload.*;
527 return Type{
528 .ip_index = .none,
529 .legacy = .{ .ptr_otherwise = &new_payload.base },
530 };
531 }
532
533405 pub fn format(ty: Type, comptime unused_fmt_string: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
534406 _ = ty;
535407 _ = unused_fmt_string;
......@@ -575,62 +447,7 @@ pub const Type = struct {
575447 ) @TypeOf(writer).Error!void {
576448 _ = options;
577449 comptime assert(unused_format_string.len == 0);
578 if (start_type.ip_index != .none) {
579 return writer.print("(intern index: {d})", .{@enumToInt(start_type.ip_index)});
580 }
581 if (true) {
582 // This is disabled to work around a stage2 bug where this function recursively
583 // causes more generic function instantiations resulting in an infinite loop
584 // in the compiler.
585 try writer.writeAll("[TODO fix internal compiler bug regarding dump]");
586 return;
587 }
588 var ty = start_type;
589 while (true) {
590 const t = ty.tag();
591 switch (t) {
592 .error_union => {
593 const payload = ty.castTag(.error_union).?.data;
594 try payload.error_set.dump("", .{}, writer);
595 try writer.writeAll("!");
596 ty = payload.payload;
597 continue;
598 },
599 .error_set => {
600 const names = ty.castTag(.error_set).?.data.names.keys();
601 try writer.writeAll("error{");
602 for (names, 0..) |name, i| {
603 if (i != 0) try writer.writeByte(',');
604 try writer.writeAll(name);
605 }
606 try writer.writeAll("}");
607 return;
608 },
609 .error_set_inferred => {
610 const func = ty.castTag(.error_set_inferred).?.data.func;
611 return writer.print("({s} func={d})", .{
612 @tagName(t), func.owner_decl,
613 });
614 },
615 .error_set_merged => {
616 const names = ty.castTag(.error_set_merged).?.data.keys();
617 try writer.writeAll("error{");
618 for (names, 0..) |name, i| {
619 if (i != 0) try writer.writeByte(',');
620 try writer.writeAll(name);
621 }
622 try writer.writeAll("}");
623 return;
624 },
625 .error_set_single => {
626 const name = ty.castTag(.error_set_single).?.data;
627 return writer.print("error{{{s}}}", .{name});
628 },
629 .inferred_alloc_const => return writer.writeAll("(inferred_alloc_const)"),
630 .inferred_alloc_mut => return writer.writeAll("(inferred_alloc_mut)"),
631 }
632 unreachable;
633 }
450 return writer.print("{any}", .{start_type.ip_index});
634451 }
635452
636453 pub const nameAllocArena = nameAlloc;
......@@ -648,45 +465,6 @@ pub const Type = struct {
648465 .none => switch (ty.tag()) {
649466 .inferred_alloc_const => unreachable,
650467 .inferred_alloc_mut => unreachable,
651
652 .error_set_inferred => {
653 const func = ty.castTag(.error_set_inferred).?.data.func;
654
655 try writer.writeAll("@typeInfo(@typeInfo(@TypeOf(");
656 const owner_decl = mod.declPtr(func.owner_decl);
657 try owner_decl.renderFullyQualifiedName(mod, writer);
658 try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set");
659 },
660
661 .error_union => {
662 const error_union = ty.castTag(.error_union).?.data;
663 try print(error_union.error_set, writer, mod);
664 try writer.writeAll("!");
665 try print(error_union.payload, writer, mod);
666 },
667
668 .error_set => {
669 const names = ty.castTag(.error_set).?.data.names.keys();
670 try writer.writeAll("error{");
671 for (names, 0..) |name, i| {
672 if (i != 0) try writer.writeByte(',');
673 try writer.writeAll(name);
674 }
675 try writer.writeAll("}");
676 },
677 .error_set_single => {
678 const name = ty.castTag(.error_set_single).?.data;
679 return writer.print("error{{{s}}}", .{name});
680 },
681 .error_set_merged => {
682 const names = ty.castTag(.error_set_merged).?.data.keys();
683 try writer.writeAll("error{");
684 for (names, 0..) |name, i| {
685 if (i != 0) try writer.writeByte(',');
686 try writer.writeAll(name);
687 }
688 try writer.writeAll("}");
689 },
690468 },
691469 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
692470 .int_type => |int_type| {
......@@ -766,6 +544,24 @@ pub const Type = struct {
766544 try print(error_union_type.payload_type.toType(), writer, mod);
767545 return;
768546 },
547 .inferred_error_set_type => |index| {
548 const ies = mod.inferredErrorSetPtr(index);
549 const func = ies.func;
550
551 try writer.writeAll("@typeInfo(@typeInfo(@TypeOf(");
552 const owner_decl = mod.declPtr(func.owner_decl);
553 try owner_decl.renderFullyQualifiedName(mod, writer);
554 try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set");
555 },
556 .error_set_type => |error_set_type| {
557 const names = error_set_type.names;
558 try writer.writeAll("error{");
559 for (names, 0..) |name, i| {
560 if (i != 0) try writer.writeByte(',');
561 try writer.writeAll(mod.intern_pool.stringToSlice(name));
562 }
563 try writer.writeAll("}");
564 },
769565 .simple_type => |s| return writer.writeAll(@tagName(s)),
770566 .struct_type => |struct_type| {
771567 if (mod.structPtrUnwrap(struct_type.index)) |struct_obj| {
......@@ -881,13 +677,8 @@ pub const Type = struct {
881677 return ty.ip_index;
882678 }
883679
884 pub fn toValue(self: Type, allocator: Allocator) Allocator.Error!Value {
885 if (self.ip_index != .none) return self.ip_index.toValue();
886 switch (self.tag()) {
887 .inferred_alloc_const => unreachable,
888 .inferred_alloc_mut => unreachable,
889 else => return Value.Tag.ty.create(allocator, self),
890 }
680 pub fn toValue(self: Type) Value {
681 return self.toIntern().toValue();
891682 }
892683
893684 const RuntimeBitsError = Module.CompileError || error{NeedLazy};
......@@ -914,14 +705,6 @@ pub const Type = struct {
914705 .empty_struct_type => return false,
915706
916707 .none => switch (ty.tag()) {
917 .error_set_inferred,
918
919 .error_set_single,
920 .error_union,
921 .error_set,
922 .error_set_merged,
923 => return true,
924
925708 .inferred_alloc_const => unreachable,
926709 .inferred_alloc_mut => unreachable,
927710 },
......@@ -951,7 +734,7 @@ pub const Type = struct {
951734 },
952735 .opt_type => |child| {
953736 const child_ty = child.toType();
954 if (child_ty.isNoReturn()) {
737 if (child_ty.isNoReturn(mod)) {
955738 // Then the optional is comptime-known to be null.
956739 return false;
957740 }
......@@ -963,7 +746,10 @@ pub const Type = struct {
963746 return !comptimeOnly(child_ty, mod);
964747 }
965748 },
966 .error_union_type => @panic("TODO"),
749 .error_union_type,
750 .error_set_type,
751 .inferred_error_set_type,
752 => true,
967753
968754 // These are function *bodies*, not pointers.
969755 // They return false here because they are comptime-only types.
......@@ -1103,112 +889,99 @@ pub const Type = struct {
1103889 /// readFrom/writeToMemory are supported only for types with a well-
1104890 /// defined memory layout
1105891 pub fn hasWellDefinedLayout(ty: Type, mod: *Module) bool {
1106 return switch (ty.ip_index) {
1107 .empty_struct_type => false,
892 return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
893 .int_type,
894 .ptr_type,
895 .vector_type,
896 => true,
1108897
1109 .none => switch (ty.tag()) {
1110 .error_set,
1111 .error_set_single,
1112 .error_set_inferred,
1113 .error_set_merged,
1114 .error_union,
1115 => false,
898 .error_union_type,
899 .error_set_type,
900 .inferred_error_set_type,
901 .anon_struct_type,
902 .opaque_type,
903 .anyframe_type,
904 // These are function bodies, not function pointers.
905 .func_type,
906 => false,
1116907
1117 .inferred_alloc_mut => unreachable,
1118 .inferred_alloc_const => unreachable,
1119 },
1120 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
1121 .int_type,
1122 .ptr_type,
1123 .vector_type,
908 .array_type => |array_type| array_type.child.toType().hasWellDefinedLayout(mod),
909 .opt_type => ty.isPtrLikeOptional(mod),
910
911 .simple_type => |t| switch (t) {
912 .f16,
913 .f32,
914 .f64,
915 .f80,
916 .f128,
917 .usize,
918 .isize,
919 .c_char,
920 .c_short,
921 .c_ushort,
922 .c_int,
923 .c_uint,
924 .c_long,
925 .c_ulong,
926 .c_longlong,
927 .c_ulonglong,
928 .c_longdouble,
929 .bool,
930 .void,
1124931 => true,
1125932
1126 .error_union_type,
1127 .anon_struct_type,
1128 .opaque_type,
1129 .anyframe_type,
1130 // These are function bodies, not function pointers.
1131 .func_type,
933 .anyerror,
934 .anyopaque,
935 .atomic_order,
936 .atomic_rmw_op,
937 .calling_convention,
938 .address_space,
939 .float_mode,
940 .reduce_op,
941 .call_modifier,
942 .prefetch_options,
943 .export_options,
944 .extern_options,
945 .type,
946 .comptime_int,
947 .comptime_float,
948 .noreturn,
949 .null,
950 .undefined,
951 .enum_literal,
952 .type_info,
953 .generic_poison,
1132954 => false,
1133955
1134 .array_type => |array_type| array_type.child.toType().hasWellDefinedLayout(mod),
1135 .opt_type => ty.isPtrLikeOptional(mod),
1136
1137 .simple_type => |t| switch (t) {
1138 .f16,
1139 .f32,
1140 .f64,
1141 .f80,
1142 .f128,
1143 .usize,
1144 .isize,
1145 .c_char,
1146 .c_short,
1147 .c_ushort,
1148 .c_int,
1149 .c_uint,
1150 .c_long,
1151 .c_ulong,
1152 .c_longlong,
1153 .c_ulonglong,
1154 .c_longdouble,
1155 .bool,
1156 .void,
1157 => true,
1158
1159 .anyerror,
1160 .anyopaque,
1161 .atomic_order,
1162 .atomic_rmw_op,
1163 .calling_convention,
1164 .address_space,
1165 .float_mode,
1166 .reduce_op,
1167 .call_modifier,
1168 .prefetch_options,
1169 .export_options,
1170 .extern_options,
1171 .type,
1172 .comptime_int,
1173 .comptime_float,
1174 .noreturn,
1175 .null,
1176 .undefined,
1177 .enum_literal,
1178 .type_info,
1179 .generic_poison,
1180 => false,
1181
1182 .var_args_param => unreachable,
1183 },
1184 .struct_type => |struct_type| {
1185 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse {
1186 // Struct with no fields has a well-defined layout of no bits.
1187 return true;
1188 };
1189 return struct_obj.layout != .Auto;
1190 },
1191 .union_type => |union_type| switch (union_type.runtime_tag) {
1192 .none, .safety => mod.unionPtr(union_type.index).layout != .Auto,
1193 .tagged => false,
1194 },
1195 .enum_type => |enum_type| switch (enum_type.tag_mode) {
1196 .auto => false,
1197 .explicit, .nonexhaustive => true,
1198 },
1199
1200 // values, not types
1201 .undef => unreachable,
1202 .un => unreachable,
1203 .simple_value => unreachable,
1204 .extern_func => unreachable,
1205 .int => unreachable,
1206 .float => unreachable,
1207 .ptr => unreachable,
1208 .opt => unreachable,
1209 .enum_tag => unreachable,
1210 .aggregate => unreachable,
956 .var_args_param => unreachable,
957 },
958 .struct_type => |struct_type| {
959 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse {
960 // Struct with no fields has a well-defined layout of no bits.
961 return true;
962 };
963 return struct_obj.layout != .Auto;
964 },
965 .union_type => |union_type| switch (union_type.runtime_tag) {
966 .none, .safety => mod.unionPtr(union_type.index).layout != .Auto,
967 .tagged => false,
1211968 },
969 .enum_type => |enum_type| switch (enum_type.tag_mode) {
970 .auto => false,
971 .explicit, .nonexhaustive => true,
972 },
973
974 // values, not types
975 .undef => unreachable,
976 .un => unreachable,
977 .simple_value => unreachable,
978 .extern_func => unreachable,
979 .int => unreachable,
980 .float => unreachable,
981 .ptr => unreachable,
982 .opt => unreachable,
983 .enum_tag => unreachable,
984 .aggregate => unreachable,
1212985 };
1213986 }
1214987
......@@ -1247,35 +1020,8 @@ pub const Type = struct {
12471020 };
12481021 }
12491022
1250 pub fn isNoReturn(ty: Type) bool {
1251 switch (@enumToInt(ty.ip_index)) {
1252 @enumToInt(InternPool.Index.first_type)...@enumToInt(InternPool.Index.noreturn_type) - 1 => return false,
1253
1254 @enumToInt(InternPool.Index.noreturn_type) => return true,
1255
1256 @enumToInt(InternPool.Index.noreturn_type) + 1...@enumToInt(InternPool.Index.last_type) => return false,
1257
1258 @enumToInt(InternPool.Index.first_value)...@enumToInt(InternPool.Index.last_value) => unreachable,
1259 @enumToInt(InternPool.Index.generic_poison) => unreachable,
1260
1261 // TODO add empty error sets here
1262 // TODO add enums with no fields here
1263 else => return false,
1264
1265 @enumToInt(InternPool.Index.none) => switch (ty.tag()) {
1266 .error_set => {
1267 const err_set_obj = ty.castTag(.error_set).?.data;
1268 const names = err_set_obj.names.keys();
1269 return names.len == 0;
1270 },
1271 .error_set_merged => {
1272 const name_map = ty.castTag(.error_set_merged).?.data;
1273 const names = name_map.keys();
1274 return names.len == 0;
1275 },
1276 else => return false,
1277 },
1278 }
1023 pub fn isNoReturn(ty: Type, mod: *Module) bool {
1024 return mod.intern_pool.isNoReturn(ty.ip_index);
12791025 }
12801026
12811027 /// Returns 0 if the pointer is naturally aligned and the element type is 0-bit.
......@@ -1353,21 +1099,6 @@ pub const Type = struct {
13531099
13541100 switch (ty.ip_index) {
13551101 .empty_struct_type => return AbiAlignmentAdvanced{ .scalar = 0 },
1356 .none => switch (ty.tag()) {
1357
1358 // TODO revisit this when we have the concept of the error tag type
1359 .error_set_inferred,
1360 .error_set_single,
1361 .error_set,
1362 .error_set_merged,
1363 => return AbiAlignmentAdvanced{ .scalar = 2 },
1364
1365 .error_union => return abiAlignmentAdvancedErrorUnion(ty, mod, strat),
1366
1367 .inferred_alloc_const,
1368 .inferred_alloc_mut,
1369 => unreachable,
1370 },
13711102 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
13721103 .int_type => |int_type| {
13731104 if (int_type.bits == 0) return AbiAlignmentAdvanced{ .scalar = 0 };
......@@ -1388,7 +1119,11 @@ pub const Type = struct {
13881119 },
13891120
13901121 .opt_type => return abiAlignmentAdvancedOptional(ty, mod, strat),
1391 .error_union_type => return abiAlignmentAdvancedErrorUnion(ty, mod, strat),
1122 .error_union_type => |info| return abiAlignmentAdvancedErrorUnion(ty, mod, strat, info.payload_type.toType()),
1123
1124 // TODO revisit this when we have the concept of the error tag type
1125 .error_set_type, .inferred_error_set_type => return AbiAlignmentAdvanced{ .scalar = 2 },
1126
13921127 // represents machine code; not a pointer
13931128 .func_type => |func_type| return AbiAlignmentAdvanced{
13941129 .scalar = if (func_type.alignment.toByteUnitsOptional()) |a|
......@@ -1572,14 +1307,14 @@ pub const Type = struct {
15721307 ty: Type,
15731308 mod: *Module,
15741309 strat: AbiAlignmentAdvancedStrat,
1310 payload_ty: Type,
15751311 ) Module.CompileError!AbiAlignmentAdvanced {
15761312 // This code needs to be kept in sync with the equivalent switch prong
15771313 // in abiSizeAdvanced.
1578 const data = ty.castTag(.error_union).?.data;
15791314 const code_align = abiAlignment(Type.anyerror, mod);
15801315 switch (strat) {
15811316 .eager, .sema => {
1582 if (!(data.payload.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
1317 if (!(payload_ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
15831318 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },
15841319 else => |e| return e,
15851320 })) {
......@@ -1587,11 +1322,11 @@ pub const Type = struct {
15871322 }
15881323 return AbiAlignmentAdvanced{ .scalar = @max(
15891324 code_align,
1590 (try data.payload.abiAlignmentAdvanced(mod, strat)).scalar,
1325 (try payload_ty.abiAlignmentAdvanced(mod, strat)).scalar,
15911326 ) };
15921327 },
15931328 .lazy => |arena| {
1594 switch (try data.payload.abiAlignmentAdvanced(mod, strat)) {
1329 switch (try payload_ty.abiAlignmentAdvanced(mod, strat)) {
15951330 .scalar => |payload_align| {
15961331 return AbiAlignmentAdvanced{
15971332 .scalar = @max(code_align, payload_align),
......@@ -1728,55 +1463,6 @@ pub const Type = struct {
17281463 switch (ty.ip_index) {
17291464 .empty_struct_type => return AbiSizeAdvanced{ .scalar = 0 },
17301465
1731 .none => switch (ty.tag()) {
1732 .inferred_alloc_const => unreachable,
1733 .inferred_alloc_mut => unreachable,
1734
1735 // TODO revisit this when we have the concept of the error tag type
1736 .error_set_inferred,
1737 .error_set,
1738 .error_set_merged,
1739 .error_set_single,
1740 => return AbiSizeAdvanced{ .scalar = 2 },
1741
1742 .error_union => {
1743 // This code needs to be kept in sync with the equivalent switch prong
1744 // in abiAlignmentAdvanced.
1745 const data = ty.castTag(.error_union).?.data;
1746 const code_size = abiSize(Type.anyerror, mod);
1747 if (!(data.payload.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
1748 error.NeedLazy => return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(strat.lazy, ty) },
1749 else => |e| return e,
1750 })) {
1751 // Same as anyerror.
1752 return AbiSizeAdvanced{ .scalar = code_size };
1753 }
1754 const code_align = abiAlignment(Type.anyerror, mod);
1755 const payload_align = abiAlignment(data.payload, mod);
1756 const payload_size = switch (try data.payload.abiSizeAdvanced(mod, strat)) {
1757 .scalar => |elem_size| elem_size,
1758 .val => switch (strat) {
1759 .sema => unreachable,
1760 .eager => unreachable,
1761 .lazy => |arena| return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(arena, ty) },
1762 },
1763 };
1764
1765 var size: u64 = 0;
1766 if (code_align > payload_align) {
1767 size += code_size;
1768 size = std.mem.alignForwardGeneric(u64, size, payload_align);
1769 size += payload_size;
1770 size = std.mem.alignForwardGeneric(u64, size, code_align);
1771 } else {
1772 size += payload_size;
1773 size = std.mem.alignForwardGeneric(u64, size, code_align);
1774 size += code_size;
1775 size = std.mem.alignForwardGeneric(u64, size, payload_align);
1776 }
1777 return AbiSizeAdvanced{ .scalar = size };
1778 },
1779 },
17801466 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
17811467 .int_type => |int_type| {
17821468 if (int_type.bits == 0) return AbiSizeAdvanced{ .scalar = 0 };
......@@ -1816,12 +1502,52 @@ pub const Type = struct {
18161502 .val = try Value.Tag.lazy_size.create(strat.lazy, ty),
18171503 },
18181504 };
1819 const result = std.mem.alignForwardGeneric(u32, total_bytes, alignment);
1820 return AbiSizeAdvanced{ .scalar = result };
1821 },
1505 const result = std.mem.alignForwardGeneric(u32, total_bytes, alignment);
1506 return AbiSizeAdvanced{ .scalar = result };
1507 },
1508
1509 .opt_type => return ty.abiSizeAdvancedOptional(mod, strat),
1510
1511 // TODO revisit this when we have the concept of the error tag type
1512 .error_set_type, .inferred_error_set_type => return AbiSizeAdvanced{ .scalar = 2 },
1513
1514 .error_union_type => |error_union_type| {
1515 const payload_ty = error_union_type.payload_type.toType();
1516 // This code needs to be kept in sync with the equivalent switch prong
1517 // in abiAlignmentAdvanced.
1518 const code_size = abiSize(Type.anyerror, mod);
1519 if (!(payload_ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
1520 error.NeedLazy => return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(strat.lazy, ty) },
1521 else => |e| return e,
1522 })) {
1523 // Same as anyerror.
1524 return AbiSizeAdvanced{ .scalar = code_size };
1525 }
1526 const code_align = abiAlignment(Type.anyerror, mod);
1527 const payload_align = abiAlignment(payload_ty, mod);
1528 const payload_size = switch (try payload_ty.abiSizeAdvanced(mod, strat)) {
1529 .scalar => |elem_size| elem_size,
1530 .val => switch (strat) {
1531 .sema => unreachable,
1532 .eager => unreachable,
1533 .lazy => |arena| return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(arena, ty) },
1534 },
1535 };
18221536
1823 .opt_type => return ty.abiSizeAdvancedOptional(mod, strat),
1824 .error_union_type => @panic("TODO"),
1537 var size: u64 = 0;
1538 if (code_align > payload_align) {
1539 size += code_size;
1540 size = std.mem.alignForwardGeneric(u64, size, payload_align);
1541 size += payload_size;
1542 size = std.mem.alignForwardGeneric(u64, size, code_align);
1543 } else {
1544 size += payload_size;
1545 size = std.mem.alignForwardGeneric(u64, size, code_align);
1546 size += code_size;
1547 size = std.mem.alignForwardGeneric(u64, size, payload_align);
1548 }
1549 return AbiSizeAdvanced{ .scalar = size };
1550 },
18251551 .func_type => unreachable, // represents machine code; not a pointer
18261552 .simple_type => |t| switch (t) {
18271553 .bool,
......@@ -1982,7 +1708,7 @@ pub const Type = struct {
19821708 ) Module.CompileError!AbiSizeAdvanced {
19831709 const child_ty = ty.optionalChild(mod);
19841710
1985 if (child_ty.isNoReturn()) {
1711 if (child_ty.isNoReturn(mod)) {
19861712 return AbiSizeAdvanced{ .scalar = 0 };
19871713 }
19881714
......@@ -2041,147 +1767,137 @@ pub const Type = struct {
20411767
20421768 const strat: AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;
20431769
2044 switch (ty.ip_index) {
2045 .none => switch (ty.tag()) {
2046 .inferred_alloc_const => unreachable,
2047 .inferred_alloc_mut => unreachable,
2048
2049 .error_set,
2050 .error_set_single,
2051 .error_set_inferred,
2052 .error_set_merged,
2053 => return 16, // TODO revisit this when we have the concept of the error tag type
1770 switch (mod.intern_pool.indexToKey(ty.ip_index)) {
1771 .int_type => |int_type| return int_type.bits,
1772 .ptr_type => |ptr_type| switch (ptr_type.size) {
1773 .Slice => return target.ptrBitWidth() * 2,
1774 else => return target.ptrBitWidth() * 2,
1775 },
1776 .anyframe_type => return target.ptrBitWidth(),
1777
1778 .array_type => |array_type| {
1779 const len = array_type.len + @boolToInt(array_type.sentinel != .none);
1780 if (len == 0) return 0;
1781 const elem_ty = array_type.child.toType();
1782 const elem_size = std.math.max(elem_ty.abiAlignment(mod), elem_ty.abiSize(mod));
1783 if (elem_size == 0) return 0;
1784 const elem_bit_size = try bitSizeAdvanced(elem_ty, mod, opt_sema);
1785 return (len - 1) * 8 * elem_size + elem_bit_size;
1786 },
1787 .vector_type => |vector_type| {
1788 const child_ty = vector_type.child.toType();
1789 const elem_bit_size = try bitSizeAdvanced(child_ty, mod, opt_sema);
1790 return elem_bit_size * vector_type.len;
1791 },
1792 .opt_type => {
1793 // Optionals and error unions are not packed so their bitsize
1794 // includes padding bits.
1795 return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;
1796 },
1797
1798 // TODO revisit this when we have the concept of the error tag type
1799 .error_set_type, .inferred_error_set_type => return 16,
1800
1801 .error_union_type => {
1802 // Optionals and error unions are not packed so their bitsize
1803 // includes padding bits.
1804 return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;
1805 },
1806 .func_type => unreachable, // represents machine code; not a pointer
1807 .simple_type => |t| switch (t) {
1808 .f16 => return 16,
1809 .f32 => return 32,
1810 .f64 => return 64,
1811 .f80 => return 80,
1812 .f128 => return 128,
1813
1814 .usize,
1815 .isize,
1816 => return target.ptrBitWidth(),
1817
1818 .c_char => return target.c_type_bit_size(.char),
1819 .c_short => return target.c_type_bit_size(.short),
1820 .c_ushort => return target.c_type_bit_size(.ushort),
1821 .c_int => return target.c_type_bit_size(.int),
1822 .c_uint => return target.c_type_bit_size(.uint),
1823 .c_long => return target.c_type_bit_size(.long),
1824 .c_ulong => return target.c_type_bit_size(.ulong),
1825 .c_longlong => return target.c_type_bit_size(.longlong),
1826 .c_ulonglong => return target.c_type_bit_size(.ulonglong),
1827 .c_longdouble => return target.c_type_bit_size(.longdouble),
1828
1829 .bool => return 1,
1830 .void => return 0,
20541831
2055 .error_union => {
2056 // Optionals and error unions are not packed so their bitsize
2057 // includes padding bits.
2058 return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;
2059 },
1832 // TODO revisit this when we have the concept of the error tag type
1833 .anyerror => return 16,
1834
1835 .anyopaque => unreachable,
1836 .type => unreachable,
1837 .comptime_int => unreachable,
1838 .comptime_float => unreachable,
1839 .noreturn => unreachable,
1840 .null => unreachable,
1841 .undefined => unreachable,
1842 .enum_literal => unreachable,
1843 .generic_poison => unreachable,
1844 .var_args_param => unreachable,
1845
1846 .atomic_order => unreachable, // missing call to resolveTypeFields
1847 .atomic_rmw_op => unreachable, // missing call to resolveTypeFields
1848 .calling_convention => unreachable, // missing call to resolveTypeFields
1849 .address_space => unreachable, // missing call to resolveTypeFields
1850 .float_mode => unreachable, // missing call to resolveTypeFields
1851 .reduce_op => unreachable, // missing call to resolveTypeFields
1852 .call_modifier => unreachable, // missing call to resolveTypeFields
1853 .prefetch_options => unreachable, // missing call to resolveTypeFields
1854 .export_options => unreachable, // missing call to resolveTypeFields
1855 .extern_options => unreachable, // missing call to resolveTypeFields
1856 .type_info => unreachable, // missing call to resolveTypeFields
20601857 },
2061 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2062 .int_type => |int_type| return int_type.bits,
2063 .ptr_type => |ptr_type| switch (ptr_type.size) {
2064 .Slice => return target.ptrBitWidth() * 2,
2065 else => return target.ptrBitWidth() * 2,
2066 },
2067 .anyframe_type => return target.ptrBitWidth(),
2068
2069 .array_type => |array_type| {
2070 const len = array_type.len + @boolToInt(array_type.sentinel != .none);
2071 if (len == 0) return 0;
2072 const elem_ty = array_type.child.toType();
2073 const elem_size = std.math.max(elem_ty.abiAlignment(mod), elem_ty.abiSize(mod));
2074 if (elem_size == 0) return 0;
2075 const elem_bit_size = try bitSizeAdvanced(elem_ty, mod, opt_sema);
2076 return (len - 1) * 8 * elem_size + elem_bit_size;
2077 },
2078 .vector_type => |vector_type| {
2079 const child_ty = vector_type.child.toType();
2080 const elem_bit_size = try bitSizeAdvanced(child_ty, mod, opt_sema);
2081 return elem_bit_size * vector_type.len;
2082 },
2083 .opt_type => {
2084 // Optionals and error unions are not packed so their bitsize
2085 // includes padding bits.
2086 return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;
2087 },
2088 .error_union_type => @panic("TODO"),
2089 .func_type => unreachable, // represents machine code; not a pointer
2090 .simple_type => |t| switch (t) {
2091 .f16 => return 16,
2092 .f32 => return 32,
2093 .f64 => return 64,
2094 .f80 => return 80,
2095 .f128 => return 128,
2096
2097 .usize,
2098 .isize,
2099 => return target.ptrBitWidth(),
2100
2101 .c_char => return target.c_type_bit_size(.char),
2102 .c_short => return target.c_type_bit_size(.short),
2103 .c_ushort => return target.c_type_bit_size(.ushort),
2104 .c_int => return target.c_type_bit_size(.int),
2105 .c_uint => return target.c_type_bit_size(.uint),
2106 .c_long => return target.c_type_bit_size(.long),
2107 .c_ulong => return target.c_type_bit_size(.ulong),
2108 .c_longlong => return target.c_type_bit_size(.longlong),
2109 .c_ulonglong => return target.c_type_bit_size(.ulonglong),
2110 .c_longdouble => return target.c_type_bit_size(.longdouble),
2111
2112 .bool => return 1,
2113 .void => return 0,
2114
2115 // TODO revisit this when we have the concept of the error tag type
2116 .anyerror => return 16,
2117
2118 .anyopaque => unreachable,
2119 .type => unreachable,
2120 .comptime_int => unreachable,
2121 .comptime_float => unreachable,
2122 .noreturn => unreachable,
2123 .null => unreachable,
2124 .undefined => unreachable,
2125 .enum_literal => unreachable,
2126 .generic_poison => unreachable,
2127 .var_args_param => unreachable,
2128
2129 .atomic_order => unreachable, // missing call to resolveTypeFields
2130 .atomic_rmw_op => unreachable, // missing call to resolveTypeFields
2131 .calling_convention => unreachable, // missing call to resolveTypeFields
2132 .address_space => unreachable, // missing call to resolveTypeFields
2133 .float_mode => unreachable, // missing call to resolveTypeFields
2134 .reduce_op => unreachable, // missing call to resolveTypeFields
2135 .call_modifier => unreachable, // missing call to resolveTypeFields
2136 .prefetch_options => unreachable, // missing call to resolveTypeFields
2137 .export_options => unreachable, // missing call to resolveTypeFields
2138 .extern_options => unreachable, // missing call to resolveTypeFields
2139 .type_info => unreachable, // missing call to resolveTypeFields
2140 },
2141 .struct_type => |struct_type| {
2142 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return 0;
2143 if (struct_obj.layout != .Packed) {
2144 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
2145 }
2146 if (opt_sema) |sema| _ = try sema.resolveTypeLayout(ty);
2147 assert(struct_obj.haveLayout());
2148 return try struct_obj.backing_int_ty.bitSizeAdvanced(mod, opt_sema);
2149 },
2150
2151 .anon_struct_type => {
2152 if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);
1858 .struct_type => |struct_type| {
1859 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return 0;
1860 if (struct_obj.layout != .Packed) {
21531861 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
2154 },
1862 }
1863 if (opt_sema) |sema| _ = try sema.resolveTypeLayout(ty);
1864 assert(struct_obj.haveLayout());
1865 return try struct_obj.backing_int_ty.bitSizeAdvanced(mod, opt_sema);
1866 },
21551867
2156 .union_type => |union_type| {
2157 if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);
2158 if (ty.containerLayout(mod) != .Packed) {
2159 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
2160 }
2161 const union_obj = mod.unionPtr(union_type.index);
2162 assert(union_obj.haveFieldTypes());
1868 .anon_struct_type => {
1869 if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);
1870 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
1871 },
21631872
2164 var size: u64 = 0;
2165 for (union_obj.fields.values()) |field| {
2166 size = @max(size, try bitSizeAdvanced(field.ty, mod, opt_sema));
2167 }
2168 return size;
2169 },
2170 .opaque_type => unreachable,
2171 .enum_type => |enum_type| return bitSizeAdvanced(enum_type.tag_ty.toType(), mod, opt_sema),
1873 .union_type => |union_type| {
1874 if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);
1875 if (ty.containerLayout(mod) != .Packed) {
1876 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
1877 }
1878 const union_obj = mod.unionPtr(union_type.index);
1879 assert(union_obj.haveFieldTypes());
21721880
2173 // values, not types
2174 .undef => unreachable,
2175 .un => unreachable,
2176 .simple_value => unreachable,
2177 .extern_func => unreachable,
2178 .int => unreachable,
2179 .float => unreachable,
2180 .ptr => unreachable,
2181 .opt => unreachable,
2182 .enum_tag => unreachable,
2183 .aggregate => unreachable,
1881 var size: u64 = 0;
1882 for (union_obj.fields.values()) |field| {
1883 size = @max(size, try bitSizeAdvanced(field.ty, mod, opt_sema));
1884 }
1885 return size;
21841886 },
1887 .opaque_type => unreachable,
1888 .enum_type => |enum_type| return bitSizeAdvanced(enum_type.tag_ty.toType(), mod, opt_sema),
1889
1890 // values, not types
1891 .undef => unreachable,
1892 .un => unreachable,
1893 .simple_value => unreachable,
1894 .extern_func => unreachable,
1895 .int => unreachable,
1896 .float => unreachable,
1897 .ptr => unreachable,
1898 .opt => unreachable,
1899 .enum_tag => unreachable,
1900 .aggregate => unreachable,
21851901 }
21861902 }
21871903
......@@ -2210,7 +1926,7 @@ pub const Type = struct {
22101926 return payload_ty.layoutIsResolved(mod);
22111927 },
22121928 .ErrorUnion => {
2213 const payload_ty = ty.errorUnionPayload();
1929 const payload_ty = ty.errorUnionPayload(mod);
22141930 return payload_ty.layoutIsResolved(mod);
22151931 },
22161932 else => return true,
......@@ -2223,8 +1939,6 @@ pub const Type = struct {
22231939 .inferred_alloc_const,
22241940 .inferred_alloc_mut,
22251941 => true,
2226
2227 else => false,
22281942 },
22291943 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
22301944 .ptr_type => |ptr_info| ptr_info.size == .One,
......@@ -2245,8 +1959,6 @@ pub const Type = struct {
22451959 .inferred_alloc_const,
22461960 .inferred_alloc_mut,
22471961 => .One,
2248
2249 else => null,
22501962 },
22511963 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
22521964 .ptr_type => |ptr_info| ptr_info.size,
......@@ -2534,69 +2246,43 @@ pub const Type = struct {
25342246 }
25352247
25362248 /// Asserts that the type is an error union.
2537 pub fn errorUnionPayload(ty: Type) Type {
2538 return switch (ty.ip_index) {
2539 .anyerror_void_error_union_type => Type.void,
2540 .none => switch (ty.tag()) {
2541 .error_union => ty.castTag(.error_union).?.data.payload,
2542 else => unreachable,
2543 },
2544 else => @panic("TODO"),
2545 };
2249 pub fn errorUnionPayload(ty: Type, mod: *Module) Type {
2250 return mod.intern_pool.indexToKey(ty.ip_index).error_union_type.payload_type.toType();
25462251 }
25472252
2548 pub fn errorUnionSet(ty: Type) Type {
2549 return switch (ty.ip_index) {
2550 .anyerror_void_error_union_type => Type.anyerror,
2551 .none => switch (ty.tag()) {
2552 .error_union => ty.castTag(.error_union).?.data.error_set,
2553 else => unreachable,
2554 },
2555 else => @panic("TODO"),
2556 };
2253 /// Asserts that the type is an error union.
2254 pub fn errorUnionSet(ty: Type, mod: *Module) Type {
2255 return mod.intern_pool.indexToKey(ty.ip_index).error_union_type.error_set_type.toType();
25572256 }
25582257
25592258 /// Returns false for unresolved inferred error sets.
2560 pub fn errorSetIsEmpty(ty: Type, mod: *const Module) bool {
2561 switch (ty.ip_index) {
2562 .none => switch (ty.tag()) {
2563 .error_set_inferred => {
2564 const inferred_error_set = ty.castTag(.error_set_inferred).?.data;
2259 pub fn errorSetIsEmpty(ty: Type, mod: *Module) bool {
2260 return switch (ty.ip_index) {
2261 .anyerror_type => false,
2262 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2263 .error_set_type => |error_set_type| error_set_type.names.len == 0,
2264 .inferred_error_set_type => |index| {
2265 const inferred_error_set = mod.inferredErrorSetPtr(index);
25652266 // Can't know for sure.
25662267 if (!inferred_error_set.is_resolved) return false;
25672268 if (inferred_error_set.is_anyerror) return false;
25682269 return inferred_error_set.errors.count() == 0;
25692270 },
2570 .error_set_single => return false,
2571 .error_set => {
2572 const err_set_obj = ty.castTag(.error_set).?.data;
2573 return err_set_obj.names.count() == 0;
2574 },
2575 .error_set_merged => {
2576 const name_map = ty.castTag(.error_set_merged).?.data;
2577 return name_map.count() == 0;
2578 },
25792271 else => unreachable,
25802272 },
2581 .anyerror_type => return false,
2582 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2583 else => @panic("TODO"),
2584 },
2585 }
2273 };
25862274 }
25872275
25882276 /// Returns true if it is an error set that includes anyerror, false otherwise.
25892277 /// Note that the result may be a false negative if the type did not get error set
25902278 /// resolution prior to this call.
2591 pub fn isAnyError(ty: Type) bool {
2279 pub fn isAnyError(ty: Type, mod: *Module) bool {
25922280 return switch (ty.ip_index) {
2593 .none => switch (ty.tag()) {
2594 .error_set_inferred => ty.castTag(.error_set_inferred).?.data.is_anyerror,
2281 .anyerror_type => true,
2282 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2283 .inferred_error_set_type => |i| mod.inferredErrorSetPtr(i).is_anyerror,
25952284 else => false,
25962285 },
2597 .anyerror_type => true,
2598 // TODO handle error_set_inferred here
2599 else => false,
26002286 };
26012287 }
26022288
......@@ -2610,30 +2296,50 @@ pub const Type = struct {
26102296 /// Returns whether ty, which must be an error set, includes an error `name`.
26112297 /// Might return a false negative if `ty` is an inferred error set and not fully
26122298 /// resolved yet.
2613 pub fn errorSetHasField(ty: Type, name: []const u8) bool {
2614 if (ty.isAnyError()) {
2615 return true;
2616 }
2617
2618 switch (ty.tag()) {
2619 .error_set_single => {
2620 const data = ty.castTag(.error_set_single).?.data;
2621 return std.mem.eql(u8, data, name);
2622 },
2623 .error_set_inferred => {
2624 const data = ty.castTag(.error_set_inferred).?.data;
2625 return data.errors.contains(name);
2626 },
2627 .error_set_merged => {
2628 const data = ty.castTag(.error_set_merged).?.data;
2629 return data.contains(name);
2299 pub fn errorSetHasFieldIp(
2300 ip: *const InternPool,
2301 ty: InternPool.Index,
2302 name: InternPool.NullTerminatedString,
2303 ) bool {
2304 return switch (ty) {
2305 .anyerror_type => true,
2306 else => switch (ip.indexToKey(ty)) {
2307 .error_set_type => |error_set_type| {
2308 return error_set_type.nameIndex(ip, name) != null;
2309 },
2310 .inferred_error_set_type => |index| {
2311 const ies = ip.inferredErrorSetPtrConst(index);
2312 if (ies.is_anyerror) return true;
2313 return ies.errors.contains(name);
2314 },
2315 else => unreachable,
26302316 },
2631 .error_set => {
2632 const data = ty.castTag(.error_set).?.data;
2633 return data.names.contains(name);
2317 };
2318 }
2319
2320 /// Returns whether ty, which must be an error set, includes an error `name`.
2321 /// Might return a false negative if `ty` is an inferred error set and not fully
2322 /// resolved yet.
2323 pub fn errorSetHasField(ty: Type, name: []const u8, mod: *Module) bool {
2324 const ip = &mod.intern_pool;
2325 return switch (ty.ip_index) {
2326 .anyerror_type => true,
2327 else => switch (ip.indexToKey(ty.ip_index)) {
2328 .error_set_type => |error_set_type| {
2329 // If the string is not interned, then the field certainly is not present.
2330 const field_name_interned = ip.getString(name).unwrap() orelse return false;
2331 return error_set_type.nameIndex(ip, field_name_interned) != null;
2332 },
2333 .inferred_error_set_type => |index| {
2334 const ies = ip.inferredErrorSetPtr(index);
2335 if (ies.is_anyerror) return true;
2336 // If the string is not interned, then the field certainly is not present.
2337 const field_name_interned = ip.getString(name).unwrap() orelse return false;
2338 return ies.errors.contains(field_name_interned);
2339 },
2340 else => unreachable,
26342341 },
2635 else => unreachable,
2636 }
2342 };
26372343 }
26382344
26392345 /// Asserts the type is an array or vector or struct.
......@@ -2727,14 +2433,6 @@ pub const Type = struct {
27272433 var ty = starting_ty;
27282434
27292435 while (true) switch (ty.ip_index) {
2730 .none => switch (ty.tag()) {
2731 .error_set, .error_set_single, .error_set_inferred, .error_set_merged => {
2732 // TODO revisit this when error sets support custom int types
2733 return .{ .signedness = .unsigned, .bits = 16 };
2734 },
2735
2736 else => unreachable,
2737 },
27382436 .anyerror_type => {
27392437 // TODO revisit this when error sets support custom int types
27402438 return .{ .signedness = .unsigned, .bits = 16 };
......@@ -2760,6 +2458,9 @@ pub const Type = struct {
27602458 .enum_type => |enum_type| ty = enum_type.tag_ty.toType(),
27612459 .vector_type => |vector_type| ty = vector_type.child.toType(),
27622460
2461 // TODO revisit this when error sets support custom int types
2462 .error_set_type, .inferred_error_set_type => return .{ .signedness = .unsigned, .bits = 16 },
2463
27632464 .anon_struct_type => unreachable,
27642465
27652466 .ptr_type => unreachable,
......@@ -2932,13 +2633,6 @@ pub const Type = struct {
29322633 .empty_struct_type => return Value.empty_struct,
29332634
29342635 .none => switch (ty.tag()) {
2935 .error_union,
2936 .error_set_single,
2937 .error_set,
2938 .error_set_merged,
2939 .error_set_inferred,
2940 => return null,
2941
29422636 .inferred_alloc_const => unreachable,
29432637 .inferred_alloc_mut => unreachable,
29442638 },
......@@ -2955,6 +2649,8 @@ pub const Type = struct {
29552649 .error_union_type,
29562650 .func_type,
29572651 .anyframe_type,
2652 .error_set_type,
2653 .inferred_error_set_type,
29582654 => return null,
29592655
29602656 .array_type => |array_type| {
......@@ -3130,18 +2826,6 @@ pub const Type = struct {
31302826 return switch (ty.ip_index) {
31312827 .empty_struct_type => false,
31322828
3133 .none => switch (ty.tag()) {
3134 .error_set,
3135 .error_set_single,
3136 .error_set_inferred,
3137 .error_set_merged,
3138 => false,
3139
3140 .inferred_alloc_mut => unreachable,
3141 .inferred_alloc_const => unreachable,
3142
3143 .error_union => return ty.errorUnionPayload().comptimeOnly(mod),
3144 },
31452829 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
31462830 .int_type => false,
31472831 .ptr_type => |ptr_type| {
......@@ -3160,6 +2844,11 @@ pub const Type = struct {
31602844 .vector_type => |vector_type| vector_type.child.toType().comptimeOnly(mod),
31612845 .opt_type => |child| child.toType().comptimeOnly(mod),
31622846 .error_union_type => |error_union_type| error_union_type.payload_type.toType().comptimeOnly(mod),
2847
2848 .error_set_type,
2849 .inferred_error_set_type,
2850 => false,
2851
31632852 // These are function bodies, not function pointers.
31642853 .func_type => true,
31652854
......@@ -3418,17 +3107,11 @@ pub const Type = struct {
34183107 }
34193108
34203109 // Asserts that `ty` is an error set and not `anyerror`.
3421 pub fn errorSetNames(ty: Type) []const []const u8 {
3422 return switch (ty.tag()) {
3423 .error_set_single => blk: {
3424 // Work around coercion problems
3425 const tmp: *const [1][]const u8 = &ty.castTag(.error_set_single).?.data;
3426 break :blk tmp;
3427 },
3428 .error_set_merged => ty.castTag(.error_set_merged).?.data.keys(),
3429 .error_set => ty.castTag(.error_set).?.data.names.keys(),
3430 .error_set_inferred => {
3431 const inferred_error_set = ty.castTag(.error_set_inferred).?.data;
3110 pub fn errorSetNames(ty: Type, mod: *Module) []const InternPool.NullTerminatedString {
3111 return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3112 .error_set_type => |x| x.names,
3113 .inferred_error_set_type => |index| {
3114 const inferred_error_set = mod.inferredErrorSetPtr(index);
34323115 assert(inferred_error_set.is_resolved);
34333116 assert(!inferred_error_set.is_anyerror);
34343117 return inferred_error_set.errors.keys();
......@@ -3437,26 +3120,6 @@ pub const Type = struct {
34373120 };
34383121 }
34393122
3440 /// Merge lhs with rhs.
3441 /// Asserts that lhs and rhs are both error sets and are resolved.
3442 pub fn errorSetMerge(lhs: Type, arena: Allocator, rhs: Type) !Type {
3443 const lhs_names = lhs.errorSetNames();
3444 const rhs_names = rhs.errorSetNames();
3445 var names: Module.ErrorSet.NameMap = .{};
3446 try names.ensureUnusedCapacity(arena, lhs_names.len);
3447 for (lhs_names) |name| {
3448 names.putAssumeCapacityNoClobber(name, {});
3449 }
3450 for (rhs_names) |name| {
3451 try names.put(arena, name, {});
3452 }
3453
3454 // names must be sorted
3455 Module.ErrorSet.sortNames(&names);
3456
3457 return try Tag.error_set_merged.create(arena, names);
3458 }
3459
34603123 pub fn enumFields(ty: Type, mod: *Module) []const InternPool.NullTerminatedString {
34613124 return mod.intern_pool.indexToKey(ty.ip_index).enum_type.names;
34623125 }
......@@ -3748,30 +3411,19 @@ pub const Type = struct {
37483411 }
37493412
37503413 pub fn declSrcLocOrNull(ty: Type, mod: *Module) ?Module.SrcLoc {
3751 switch (ty.ip_index) {
3752 .empty_struct_type => return null,
3753 .none => switch (ty.tag()) {
3754 .error_set => {
3755 const error_set = ty.castTag(.error_set).?.data;
3756 return error_set.srcLoc(mod);
3757 },
3758
3759 else => return null,
3414 return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3415 .struct_type => |struct_type| {
3416 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
3417 return struct_obj.srcLoc(mod);
37603418 },
3761 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3762 .struct_type => |struct_type| {
3763 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
3764 return struct_obj.srcLoc(mod);
3765 },
3766 .union_type => |union_type| {
3767 const union_obj = mod.unionPtr(union_type.index);
3768 return union_obj.srcLoc(mod);
3769 },
3770 .opaque_type => |opaque_type| mod.opaqueSrcLoc(opaque_type),
3771 .enum_type => |enum_type| mod.declPtr(enum_type.decl).srcLoc(mod),
3772 else => null,
3419 .union_type => |union_type| {
3420 const union_obj = mod.unionPtr(union_type.index);
3421 return union_obj.srcLoc(mod);
37733422 },
3774 }
3423 .opaque_type => |opaque_type| mod.opaqueSrcLoc(opaque_type),
3424 .enum_type => |enum_type| mod.declPtr(enum_type.decl).srcLoc(mod),
3425 else => null,
3426 };
37753427 }
37763428
37773429 pub fn getOwnerDecl(ty: Type, mod: *Module) Module.Decl.Index {
......@@ -3779,39 +3431,25 @@ pub const Type = struct {
37793431 }
37803432
37813433 pub fn getOwnerDeclOrNull(ty: Type, mod: *Module) ?Module.Decl.Index {
3782 switch (ty.ip_index) {
3783 .none => switch (ty.tag()) {
3784 .error_set => {
3785 const error_set = ty.castTag(.error_set).?.data;
3786 return error_set.owner_decl;
3787 },
3788
3789 else => return null,
3434 return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3435 .struct_type => |struct_type| {
3436 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return null;
3437 return struct_obj.owner_decl;
37903438 },
3791 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3792 .struct_type => |struct_type| {
3793 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return null;
3794 return struct_obj.owner_decl;
3795 },
3796 .union_type => |union_type| {
3797 const union_obj = mod.unionPtr(union_type.index);
3798 return union_obj.owner_decl;
3799 },
3800 .opaque_type => |opaque_type| opaque_type.decl,
3801 .enum_type => |enum_type| enum_type.decl,
3802 else => null,
3439 .union_type => |union_type| {
3440 const union_obj = mod.unionPtr(union_type.index);
3441 return union_obj.owner_decl;
38033442 },
3804 }
3443 .opaque_type => |opaque_type| opaque_type.decl,
3444 .enum_type => |enum_type| enum_type.decl,
3445 else => null,
3446 };
38053447 }
38063448
38073449 pub fn isGenericPoison(ty: Type) bool {
38083450 return ty.ip_index == .generic_poison_type;
38093451 }
38103452
3811 pub fn isBoundFn(ty: Type) bool {
3812 return ty.ip_index == .none and ty.tag() == .bound_fn;
3813 }
3814
38153453 /// This enum does not directly correspond to `std.builtin.TypeId` because
38163454 /// it has extra enum tags in it, as a way of using less memory. For example,
38173455 /// even though Zig recognizes `*align(10) i32` and `*i32` both as Pointer types
......@@ -3827,54 +3465,8 @@ pub const Type = struct {
38273465 inferred_alloc_const, // See last_no_payload_tag below.
38283466 // After this, the tag requires a payload.
38293467
3830 error_union,
3831 error_set,
3832 error_set_single,
3833 /// The type is the inferred error set of a specific function.
3834 error_set_inferred,
3835 error_set_merged,
3836
38373468 pub const last_no_payload_tag = Tag.inferred_alloc_const;
38383469 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
3839
3840 pub fn Type(comptime t: Tag) type {
3841 return switch (t) {
3842 .inferred_alloc_const,
3843 .inferred_alloc_mut,
3844 => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
3845
3846 .error_set => Payload.ErrorSet,
3847 .error_set_inferred => Payload.ErrorSetInferred,
3848 .error_set_merged => Payload.ErrorSetMerged,
3849
3850 .error_union => Payload.ErrorUnion,
3851 .error_set_single => Payload.Name,
3852 };
3853 }
3854
3855 pub fn init(comptime t: Tag) file_struct.Type {
3856 comptime std.debug.assert(@enumToInt(t) < Tag.no_payload_count);
3857 return file_struct.Type{
3858 .ip_index = .none,
3859 .legacy = .{ .tag_if_small_enough = t },
3860 };
3861 }
3862
3863 pub fn create(comptime t: Tag, ally: Allocator, data: Data(t)) error{OutOfMemory}!file_struct.Type {
3864 const p = try ally.create(t.Type());
3865 p.* = .{
3866 .base = .{ .tag = t },
3867 .data = data,
3868 };
3869 return file_struct.Type{
3870 .ip_index = .none,
3871 .legacy = .{ .ptr_otherwise = &p.base },
3872 };
3873 }
3874
3875 pub fn Data(comptime t: Tag) type {
3876 return std.meta.fieldInfo(t.Type(), .data).type;
3877 }
38783470 };
38793471
38803472 pub fn isTuple(ty: Type, mod: *Module) bool {
......@@ -3928,37 +3520,6 @@ pub const Type = struct {
39283520 pub const Payload = struct {
39293521 tag: Tag,
39303522
3931 pub const Len = struct {
3932 base: Payload,
3933 data: u64,
3934 };
3935
3936 pub const Bits = struct {
3937 base: Payload,
3938 data: u16,
3939 };
3940
3941 pub const ErrorSet = struct {
3942 pub const base_tag = Tag.error_set;
3943
3944 base: Payload = Payload{ .tag = base_tag },
3945 data: *Module.ErrorSet,
3946 };
3947
3948 pub const ErrorSetMerged = struct {
3949 pub const base_tag = Tag.error_set_merged;
3950
3951 base: Payload = Payload{ .tag = base_tag },
3952 data: Module.ErrorSet.NameMap,
3953 };
3954
3955 pub const ErrorSetInferred = struct {
3956 pub const base_tag = Tag.error_set_inferred;
3957
3958 base: Payload = Payload{ .tag = base_tag },
3959 data: *Module.Fn.InferredErrorSet,
3960 };
3961
39623523 /// TODO: remove this data structure since we have `InternPool.Key.PtrType`.
39633524 pub const Pointer = struct {
39643525 data: Data,
......@@ -4010,27 +3571,6 @@ pub const Type = struct {
40103571 }
40113572 };
40123573 };
4013
4014 pub const ErrorUnion = struct {
4015 pub const base_tag = Tag.error_union;
4016
4017 base: Payload = Payload{ .tag = base_tag },
4018 data: struct {
4019 error_set: Type,
4020 payload: Type,
4021 },
4022 };
4023
4024 pub const Decl = struct {
4025 base: Payload,
4026 data: *Module.Decl,
4027 };
4028
4029 pub const Name = struct {
4030 base: Payload,
4031 /// memory is owned by `Module`
4032 data: []const u8,
4033 };
40343574 };
40353575
40363576 pub const @"u1": Type = .{ .ip_index = .u1_type, .legacy = undefined };
......@@ -4164,19 +3704,6 @@ pub const Type = struct {
41643704 return mod.optionalType(child_type.ip_index);
41653705 }
41663706
4167 pub fn errorUnion(
4168 arena: Allocator,
4169 error_set: Type,
4170 payload: Type,
4171 mod: *Module,
4172 ) Allocator.Error!Type {
4173 assert(error_set.zigTypeTag(mod) == .ErrorSet);
4174 return Type.Tag.error_union.create(arena, .{
4175 .error_set = error_set,
4176 .payload = payload,
4177 });
4178 }
4179
41803707 pub fn smallestUnsignedBits(max: u64) u16 {
41813708 if (max == 0) return 0;
41823709 const base = std.math.log2(max);
src/value.zig+9-9
......@@ -260,7 +260,7 @@ pub const Value = struct {
260260 const new_payload = try arena.create(Payload.Ty);
261261 new_payload.* = .{
262262 .base = payload.base,
263 .data = try payload.data.copy(arena),
263 .data = payload.data,
264264 };
265265 return Value{
266266 .ip_index = .none,
......@@ -281,7 +281,7 @@ pub const Value = struct {
281281 .base = payload.base,
282282 .data = .{
283283 .container_ptr = try payload.data.container_ptr.copy(arena),
284 .container_ty = try payload.data.container_ty.copy(arena),
284 .container_ty = payload.data.container_ty,
285285 },
286286 };
287287 return Value{
......@@ -296,7 +296,7 @@ pub const Value = struct {
296296 .base = payload.base,
297297 .data = .{
298298 .field_val = try payload.data.field_val.copy(arena),
299 .field_ty = try payload.data.field_ty.copy(arena),
299 .field_ty = payload.data.field_ty,
300300 },
301301 };
302302 return Value{
......@@ -311,7 +311,7 @@ pub const Value = struct {
311311 .base = payload.base,
312312 .data = .{
313313 .array_ptr = try payload.data.array_ptr.copy(arena),
314 .elem_ty = try payload.data.elem_ty.copy(arena),
314 .elem_ty = payload.data.elem_ty,
315315 .index = payload.data.index,
316316 },
317317 };
......@@ -327,7 +327,7 @@ pub const Value = struct {
327327 .base = payload.base,
328328 .data = .{
329329 .container_ptr = try payload.data.container_ptr.copy(arena),
330 .container_ty = try payload.data.container_ty.copy(arena),
330 .container_ty = payload.data.container_ty,
331331 .field_index = payload.data.field_index,
332332 },
333333 };
......@@ -1870,7 +1870,7 @@ pub const Value = struct {
18701870 .eu_payload => {
18711871 const a_payload = a.castTag(.eu_payload).?.data;
18721872 const b_payload = b.castTag(.eu_payload).?.data;
1873 const payload_ty = ty.errorUnionPayload();
1873 const payload_ty = ty.errorUnionPayload(mod);
18741874 return eqlAdvanced(a_payload, payload_ty, b_payload, payload_ty, mod, opt_sema);
18751875 },
18761876 .eu_payload_ptr => {
......@@ -2163,14 +2163,14 @@ pub const Value = struct {
21632163 .ErrorUnion => {
21642164 if (val.tag() == .@"error") {
21652165 std.hash.autoHash(hasher, false); // error
2166 const sub_ty = ty.errorUnionSet();
2166 const sub_ty = ty.errorUnionSet(mod);
21672167 val.hash(sub_ty, hasher, mod);
21682168 return;
21692169 }
21702170
21712171 if (val.castTag(.eu_payload)) |payload| {
21722172 std.hash.autoHash(hasher, true); // payload
2173 const sub_ty = ty.errorUnionPayload();
2173 const sub_ty = ty.errorUnionPayload(mod);
21742174 payload.data.hash(sub_ty, hasher, mod);
21752175 return;
21762176 } else unreachable;
......@@ -2272,7 +2272,7 @@ pub const Value = struct {
22722272 payload.data.hashUncoerced(child_ty, hasher, mod);
22732273 } else std.hash.autoHash(hasher, std.builtin.TypeId.Null),
22742274 .ErrorSet, .ErrorUnion => if (val.getError()) |err| hasher.update(err) else {
2275 const pl_ty = ty.errorUnionPayload();
2275 const pl_ty = ty.errorUnionPayload(mod);
22762276 val.castTag(.eu_payload).?.data.hashUncoerced(pl_ty, hasher, mod);
22772277 },
22782278 .Enum, .EnumLiteral, .Union => {