authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-12 16:22:37-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:46:17-07:00
log88dbd62bcbac24c09791a7838d2f08c2f540967a
tree9935a67bb6644fc448513eb728a1f22a587a89fb
parentd89807efbb1bd5af0a92544298fc08ad6ba2d255

stage2: move enum tag values into the InternPool

I'm seeing a new assertion trip: the call to `enumTagFieldIndex` in the implementation of `@Type` is attempting to query the field index of an union's enum tag, but the type of the enum tag value provided is not the same as the union's tag type. Most likely this is a problem with type coercion, since values are now typed. Another problem is that I added some hacks in std.builtin because I didn't see any convenient way to access them from Sema. That should definitely be cleaned up before merging this branch.

19 files changed, 768 insertions(+), 671 deletions(-)

lib/std/builtin.zig+7
......@@ -223,6 +223,13 @@ pub const SourceLocation = struct {
223223pub const TypeId = std.meta.Tag(Type);
224224pub const TypeInfo = @compileError("deprecated; use Type");
225225
226/// TODO this is a temporary alias because I don't see any handy methods in
227/// Sema for accessing inner declarations.
228pub const PtrSize = Type.Pointer.Size;
229/// TODO this is a temporary alias because I don't see any handy methods in
230/// Sema for accessing inner declarations.
231pub const TmpContainerLayoutAlias = Type.ContainerLayout;
232
226233/// This data structure is used by the Zig language code generation and
227234/// therefore must be kept in sync with the compiler implementation.
228235pub const Type = union(enum) {
src/Air.zig+3
......@@ -845,6 +845,7 @@ pub const Inst = struct {
845845
846846 pub const Ref = enum(u32) {
847847 u1_type = @enumToInt(InternPool.Index.u1_type),
848 u5_type = @enumToInt(InternPool.Index.u5_type),
848849 u8_type = @enumToInt(InternPool.Index.u8_type),
849850 i8_type = @enumToInt(InternPool.Index.i8_type),
850851 u16_type = @enumToInt(InternPool.Index.u16_type),
......@@ -913,6 +914,8 @@ pub const Inst = struct {
913914 zero_u8 = @enumToInt(InternPool.Index.zero_u8),
914915 one = @enumToInt(InternPool.Index.one),
915916 one_usize = @enumToInt(InternPool.Index.one_usize),
917 one_u5 = @enumToInt(InternPool.Index.one_u5),
918 four_u5 = @enumToInt(InternPool.Index.four_u5),
916919 negative_one = @enumToInt(InternPool.Index.negative_one),
917920 calling_convention_c = @enumToInt(InternPool.Index.calling_convention_c),
918921 calling_convention_inline = @enumToInt(InternPool.Index.calling_convention_inline),
src/InternPool.zig+218-97
......@@ -144,6 +144,9 @@ pub const Key = union(enum) {
144144 opaque_type: OpaqueType,
145145 enum_type: EnumType,
146146
147 /// Typed `undefined`. This will never be `none`; untyped `undefined` is represented
148 /// via `simple_value` and has a named `Index` tag for it.
149 undef: Index,
147150 simple_value: SimpleValue,
148151 extern_func: struct {
149152 ty: Index,
......@@ -155,13 +158,12 @@ pub const Key = union(enum) {
155158 lib_name: u32,
156159 },
157160 int: Key.Int,
161 /// A specific enum tag, indicated by the integer tag value.
162 enum_tag: Key.EnumTag,
158163 float: Key.Float,
159164 ptr: Ptr,
160165 opt: Opt,
161 enum_tag: struct {
162 ty: Index,
163 tag: BigIntConst,
164 },
166
165167 /// An instance of a struct, array, or vector.
166168 /// Each element/field stored as an `Index`.
167169 /// In the case of sentinel-terminated arrays, the sentinel value *is* stored,
......@@ -284,21 +286,33 @@ pub const Key = union(enum) {
284286 };
285287
286288 /// Look up field index based on field name.
287 pub fn nameIndex(self: EnumType, ip: InternPool, name: NullTerminatedString) ?usize {
289 pub fn nameIndex(self: EnumType, ip: *const InternPool, name: NullTerminatedString) ?u32 {
288290 const map = &ip.maps.items[@enumToInt(self.names_map.unwrap().?)];
289291 const adapter: NullTerminatedString.Adapter = .{ .strings = self.names };
290 return map.getIndexAdapted(name, adapter);
292 const field_index = map.getIndexAdapted(name, adapter) orelse return null;
293 return @intCast(u32, field_index);
291294 }
292295
293296 /// Look up field index based on tag value.
294297 /// Asserts that `values_map` is not `none`.
295298 /// This function returns `null` when `tag_val` does not have the
296299 /// integer tag type of the enum.
297 pub fn tagValueIndex(self: EnumType, ip: InternPool, tag_val: Index) ?usize {
300 pub fn tagValueIndex(self: EnumType, ip: *const InternPool, tag_val: Index) ?u32 {
298301 assert(tag_val != .none);
299 const map = &ip.maps.items[@enumToInt(self.values_map.unwrap().?)];
300 const adapter: Index.Adapter = .{ .indexes = self.values };
301 return map.getIndexAdapted(tag_val, adapter);
302 if (self.values_map.unwrap()) |values_map| {
303 const map = &ip.maps.items[@enumToInt(values_map)];
304 const adapter: Index.Adapter = .{ .indexes = self.values };
305 const field_index = map.getIndexAdapted(tag_val, adapter) orelse return null;
306 return @intCast(u32, field_index);
307 }
308 // Auto-numbered enum. Convert `tag_val` to field index.
309 switch (ip.indexToKey(tag_val).int.storage) {
310 .u64 => |x| {
311 if (x >= self.names.len) return null;
312 return @intCast(u32, x);
313 },
314 .i64, .big_int => return null, // out of range
315 }
302316 }
303317 };
304318
......@@ -362,6 +376,13 @@ pub const Key = union(enum) {
362376 };
363377 };
364378
379 pub const EnumTag = struct {
380 /// The enum type.
381 ty: Index,
382 /// The integer tag value which has the integer tag type of the enum.
383 int: Index,
384 };
385
365386 pub const Float = struct {
366387 ty: Index,
367388 /// The storage used must match the size of the float type being represented.
......@@ -436,6 +457,8 @@ pub const Key = union(enum) {
436457 .struct_type,
437458 .union_type,
438459 .un,
460 .undef,
461 .enum_tag,
439462 => |info| std.hash.autoHash(hasher, info),
440463
441464 .opaque_type => |opaque_type| std.hash.autoHash(hasher, opaque_type.decl),
......@@ -471,12 +494,6 @@ pub const Key = union(enum) {
471494 }
472495 },
473496
474 .enum_tag => |enum_tag| {
475 std.hash.autoHash(hasher, enum_tag.ty);
476 std.hash.autoHash(hasher, enum_tag.tag.positive);
477 for (enum_tag.tag.limbs) |limb| std.hash.autoHash(hasher, limb);
478 },
479
480497 .aggregate => |aggregate| {
481498 std.hash.autoHash(hasher, aggregate.ty);
482499 for (aggregate.fields) |field| std.hash.autoHash(hasher, field);
......@@ -522,6 +539,10 @@ pub const Key = union(enum) {
522539 const b_info = b.simple_value;
523540 return a_info == b_info;
524541 },
542 .undef => |a_info| {
543 const b_info = b.undef;
544 return a_info == b_info;
545 },
525546 .extern_func => |a_info| {
526547 const b_info = b.extern_func;
527548 return std.meta.eql(a_info, b_info);
......@@ -542,6 +563,10 @@ pub const Key = union(enum) {
542563 const b_info = b.un;
543564 return std.meta.eql(a_info, b_info);
544565 },
566 .enum_tag => |a_info| {
567 const b_info = b.enum_tag;
568 return std.meta.eql(a_info, b_info);
569 },
545570
546571 .ptr => |a_info| {
547572 const b_info = b.ptr;
......@@ -612,13 +637,6 @@ pub const Key = union(enum) {
612637 };
613638 },
614639
615 .enum_tag => |a_info| {
616 const b_info = b.enum_tag;
617 _ = a_info;
618 _ = b_info;
619 @panic("TODO");
620 },
621
622640 .opaque_type => |a_info| {
623641 const b_info = b.opaque_type;
624642 return a_info.decl == b_info.decl;
......@@ -636,7 +654,7 @@ pub const Key = union(enum) {
636654 }
637655
638656 pub fn typeOf(key: Key) Index {
639 switch (key) {
657 return switch (key) {
640658 .int_type,
641659 .ptr_type,
642660 .array_type,
......@@ -648,7 +666,7 @@ pub const Key = union(enum) {
648666 .union_type,
649667 .opaque_type,
650668 .enum_type,
651 => return .type_type,
669 => .type_type,
652670
653671 inline .ptr,
654672 .int,
......@@ -658,18 +676,20 @@ pub const Key = union(enum) {
658676 .enum_tag,
659677 .aggregate,
660678 .un,
661 => |x| return x.ty,
679 => |x| x.ty,
680
681 .undef => |x| x,
662682
663683 .simple_value => |s| switch (s) {
664 .undefined => return .undefined_type,
665 .void => return .void_type,
666 .null => return .null_type,
667 .false, .true => return .bool_type,
668 .empty_struct => return .empty_struct_type,
669 .@"unreachable" => return .noreturn_type,
684 .undefined => .undefined_type,
685 .void => .void_type,
686 .null => .null_type,
687 .false, .true => .bool_type,
688 .empty_struct => .empty_struct_type,
689 .@"unreachable" => .noreturn_type,
670690 .generic_poison => unreachable,
671691 },
672 }
692 };
673693 }
674694};
675695
......@@ -693,6 +713,7 @@ pub const Index = enum(u32) {
693713 pub const last_value: Index = .empty_struct;
694714
695715 u1_type,
716 u5_type,
696717 u8_type,
697718 i8_type,
698719 u16_type,
......@@ -769,6 +790,10 @@ pub const Index = enum(u32) {
769790 one,
770791 /// `1` (usize)
771792 one_usize,
793 /// `1` (u5)
794 one_u5,
795 /// `4` (u5)
796 four_u5,
772797 /// `-1` (comptime_int)
773798 negative_one,
774799 /// `std.builtin.CallingConvention.C`
......@@ -834,6 +859,12 @@ pub const static_keys = [_]Key{
834859 .bits = 1,
835860 } },
836861
862 // u5_type
863 .{ .int_type = .{
864 .signedness = .unsigned,
865 .bits = 5,
866 } },
867
837868 .{ .int_type = .{
838869 .signedness = .unsigned,
839870 .bits = 8,
......@@ -1021,25 +1052,30 @@ pub const static_keys = [_]Key{
10211052 .storage = .{ .u64 = 1 },
10221053 } },
10231054
1055 // one_u5
1056 .{ .int = .{
1057 .ty = .u5_type,
1058 .storage = .{ .u64 = 1 },
1059 } },
1060 // four_u5
1061 .{ .int = .{
1062 .ty = .u5_type,
1063 .storage = .{ .u64 = 4 },
1064 } },
1065 // negative_one
10241066 .{ .int = .{
10251067 .ty = .comptime_int_type,
10261068 .storage = .{ .i64 = -1 },
10271069 } },
1028
1070 // calling_convention_c
10291071 .{ .enum_tag = .{
10301072 .ty = .calling_convention_type,
1031 .tag = .{
1032 .limbs = &.{@enumToInt(std.builtin.CallingConvention.C)},
1033 .positive = true,
1034 },
1073 .int = .one_u5,
10351074 } },
1036
1075 // calling_convention_inline
10371076 .{ .enum_tag = .{
10381077 .ty = .calling_convention_type,
1039 .tag = .{
1040 .limbs = &.{@enumToInt(std.builtin.CallingConvention.Inline)},
1041 .positive = true,
1042 },
1078 .int = .four_u5,
10431079 } },
10441080
10451081 .{ .simple_value = .void },
......@@ -1118,6 +1154,10 @@ pub const Tag = enum(u8) {
11181154 /// `data` is `Module.Union.Index`.
11191155 type_union_safety,
11201156
1157 /// Typed `undefined`.
1158 /// `data` is `Index` of the type.
1159 /// Untyped `undefined` is stored instead via `simple_value`.
1160 undef,
11211161 /// A value that can be represented with only an enum tag.
11221162 /// data is SimpleValue enum value.
11231163 simple_value,
......@@ -1132,7 +1172,7 @@ pub const Tag = enum(u8) {
11321172 /// already contains the optional type corresponding to this payload.
11331173 opt_payload,
11341174 /// An optional value that is null.
1135 /// data is Index of the payload type.
1175 /// data is Index of the optional type.
11361176 opt_null,
11371177 /// Type: u8
11381178 /// data is integer value
......@@ -1155,18 +1195,18 @@ pub const Tag = enum(u8) {
11551195 /// A comptime_int that fits in an i32.
11561196 /// data is integer value bitcasted to u32.
11571197 int_comptime_int_i32,
1198 /// An integer value that fits in 32 bits with an explicitly provided type.
1199 /// data is extra index of `IntSmall`.
1200 int_small,
11581201 /// A positive integer value.
1159 /// data is a limbs index to Int.
1202 /// data is a limbs index to `Int`.
11601203 int_positive,
11611204 /// A negative integer value.
1162 /// data is a limbs index to Int.
1205 /// data is a limbs index to `Int`.
11631206 int_negative,
1164 /// An enum tag identified by a positive integer value.
1165 /// data is a limbs index to Int.
1166 enum_tag_positive,
1167 /// An enum tag identified by a negative integer value.
1168 /// data is a limbs index to Int.
1169 enum_tag_negative,
1207 /// An enum tag value.
1208 /// data is extra index of `Key.EnumTag`.
1209 enum_tag,
11701210 /// An f16 value.
11711211 /// data is float value bitcasted to u16 and zero-extended.
11721212 float_f16,
......@@ -1404,6 +1444,11 @@ pub const Int = struct {
14041444 limbs_len: u32,
14051445};
14061446
1447pub const IntSmall = struct {
1448 ty: Index,
1449 value: u32,
1450};
1451
14071452/// A f64 value, broken up into 2 u32 parts.
14081453pub const Float64 = struct {
14091454 piece0: u32,
......@@ -1479,15 +1524,28 @@ pub fn init(ip: *InternPool, gpa: Allocator) !void {
14791524 try ip.items.ensureUnusedCapacity(gpa, static_keys.len);
14801525 try ip.map.ensureUnusedCapacity(gpa, static_keys.len);
14811526 try ip.extra.ensureUnusedCapacity(gpa, static_keys.len);
1482 try ip.limbs.ensureUnusedCapacity(gpa, 2);
14831527
14841528 // This inserts all the statically-known values into the intern pool in the
14851529 // order expected.
14861530 for (static_keys) |key| _ = ip.get(gpa, key) catch unreachable;
14871531
1488 // Sanity check.
1489 assert(ip.indexToKey(.bool_true).simple_value == .true);
1490 assert(ip.indexToKey(.bool_false).simple_value == .false);
1532 if (std.debug.runtime_safety) {
1533 // Sanity check.
1534 assert(ip.indexToKey(.bool_true).simple_value == .true);
1535 assert(ip.indexToKey(.bool_false).simple_value == .false);
1536
1537 const cc_inline = ip.indexToKey(.calling_convention_inline).enum_tag.int;
1538 const cc_c = ip.indexToKey(.calling_convention_c).enum_tag.int;
1539
1540 assert(ip.indexToKey(cc_inline).int.storage.u64 ==
1541 @enumToInt(std.builtin.CallingConvention.Inline));
1542
1543 assert(ip.indexToKey(cc_c).int.storage.u64 ==
1544 @enumToInt(std.builtin.CallingConvention.C));
1545
1546 assert(ip.indexToKey(ip.typeOf(cc_inline)).int_type.bits ==
1547 @typeInfo(@typeInfo(std.builtin.CallingConvention).Enum.tag_type).Int.bits);
1548 }
14911549
14921550 assert(ip.items.len == static_keys.len);
14931551}
......@@ -1634,6 +1692,7 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
16341692 .type_enum_explicit => indexToKeyEnum(ip, data, .explicit),
16351693 .type_enum_nonexhaustive => indexToKeyEnum(ip, data, .nonexhaustive),
16361694
1695 .undef => .{ .undef = @intToEnum(Index, data) },
16371696 .opt_null => .{ .opt = .{
16381697 .ty = @intToEnum(Index, data),
16391698 .val = .none,
......@@ -1687,8 +1746,13 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
16871746 } },
16881747 .int_positive => indexToKeyBigInt(ip, data, true),
16891748 .int_negative => indexToKeyBigInt(ip, data, false),
1690 .enum_tag_positive => @panic("TODO"),
1691 .enum_tag_negative => @panic("TODO"),
1749 .int_small => {
1750 const info = ip.extraData(IntSmall, data);
1751 return .{ .int = .{
1752 .ty = info.ty,
1753 .storage = .{ .u64 = info.value },
1754 } };
1755 },
16921756 .float_f16 => .{ .float = .{
16931757 .ty = .f16_type,
16941758 .storage = .{ .f16 = @bitCast(f16, @intCast(u16, data)) },
......@@ -1734,6 +1798,7 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
17341798 };
17351799 },
17361800 .union_value => .{ .un = ip.extraData(Key.Union, data) },
1801 .enum_tag => .{ .enum_tag = ip.extraData(Key.EnumTag, data) },
17371802 };
17381803}
17391804
......@@ -1896,6 +1961,13 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
18961961 .data = @enumToInt(simple_value),
18971962 });
18981963 },
1964 .undef => |ty| {
1965 assert(ty != .none);
1966 ip.items.appendAssumeCapacity(.{
1967 .tag = .undef,
1968 .data = @enumToInt(ty),
1969 });
1970 },
18991971
19001972 .struct_type => |struct_type| {
19011973 ip.items.appendAssumeCapacity(if (struct_type.index.unwrap()) |i| .{
......@@ -2112,10 +2184,32 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
21122184 }
21132185 switch (int.storage) {
21142186 .big_int => |big_int| {
2187 if (big_int.to(u32)) |casted| {
2188 ip.items.appendAssumeCapacity(.{
2189 .tag = .int_small,
2190 .data = try ip.addExtra(gpa, IntSmall{
2191 .ty = int.ty,
2192 .value = casted,
2193 }),
2194 });
2195 return @intToEnum(Index, ip.items.len - 1);
2196 } else |_| {}
2197
21152198 const tag: Tag = if (big_int.positive) .int_positive else .int_negative;
21162199 try addInt(ip, gpa, int.ty, tag, big_int.limbs);
21172200 },
2118 inline .i64, .u64 => |x| {
2201 inline .u64, .i64 => |x| {
2202 if (std.math.cast(u32, x)) |casted| {
2203 ip.items.appendAssumeCapacity(.{
2204 .tag = .int_small,
2205 .data = try ip.addExtra(gpa, IntSmall{
2206 .ty = int.ty,
2207 .value = casted,
2208 }),
2209 });
2210 return @intToEnum(Index, ip.items.len - 1);
2211 }
2212
21192213 var buf: [2]Limb = undefined;
21202214 const big_int = BigIntMutable.init(&buf, x).toConst();
21212215 const tag: Tag = if (big_int.positive) .int_positive else .int_negative;
......@@ -2124,6 +2218,16 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
21242218 }
21252219 },
21262220
2221 .enum_tag => |enum_tag| {
2222 assert(enum_tag.ty != .none);
2223 assert(enum_tag.int != .none);
2224
2225 ip.items.appendAssumeCapacity(.{
2226 .tag = .enum_tag,
2227 .data = try ip.addExtra(gpa, enum_tag),
2228 });
2229 },
2230
21272231 .float => |float| {
21282232 switch (float.ty) {
21292233 .f16_type => ip.items.appendAssumeCapacity(.{
......@@ -2164,11 +2268,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
21642268 }
21652269 },
21662270
2167 .enum_tag => |enum_tag| {
2168 const tag: Tag = if (enum_tag.tag.positive) .enum_tag_positive else .enum_tag_negative;
2169 try addInt(ip, gpa, enum_tag.ty, tag, enum_tag.tag.limbs);
2170 },
2171
21722271 .aggregate => |aggregate| {
21732272 if (aggregate.fields.len == 0) {
21742273 ip.items.appendAssumeCapacity(.{
......@@ -2671,44 +2770,59 @@ pub fn slicePtrType(ip: InternPool, i: Index) Index {
26712770
26722771/// Given an existing value, returns the same value but with the supplied type.
26732772/// Only some combinations are allowed:
2674/// * int to int
2773/// * int <=> int
2774/// * int <=> enum
26752775pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index {
26762776 switch (ip.indexToKey(val)) {
2677 .int => |int| {
2678 // The key cannot be passed directly to `get`, otherwise in the case of
2679 // big_int storage, the limbs would be invalidated before they are read.
2680 // Here we pre-reserve the limbs to ensure that the logic in `addInt` will
2681 // not use an invalidated limbs pointer.
2682 switch (int.storage) {
2683 .u64 => |x| return ip.get(gpa, .{ .int = .{
2684 .ty = new_ty,
2685 .storage = .{ .u64 = x },
2686 } }),
2687 .i64 => |x| return ip.get(gpa, .{ .int = .{
2688 .ty = new_ty,
2689 .storage = .{ .i64 = x },
2690 } }),
2691
2692 .big_int => |big_int| {
2693 const positive = big_int.positive;
2694 const limbs = ip.limbsSliceToIndex(big_int.limbs);
2695 // This line invalidates the limbs slice, but the indexes computed in the
2696 // previous line are still correct.
2697 try reserveLimbs(ip, gpa, @typeInfo(Int).Struct.fields.len + big_int.limbs.len);
2698 return ip.get(gpa, .{ .int = .{
2699 .ty = new_ty,
2700 .storage = .{ .big_int = .{
2701 .limbs = ip.limbsIndexToSlice(limbs),
2702 .positive = positive,
2703 } },
2704 } });
2705 },
2706 }
2777 .int => |int| switch (ip.indexToKey(new_ty)) {
2778 .enum_type => return ip.get(gpa, .{ .enum_tag = .{
2779 .ty = new_ty,
2780 .int = val,
2781 } }),
2782 else => return getCoercedInts(ip, gpa, int, new_ty),
2783 },
2784 .enum_tag => |enum_tag| {
2785 // Assume new_ty is an integer type.
2786 return getCoercedInts(ip, gpa, ip.indexToKey(enum_tag.int).int, new_ty);
27072787 },
27082788 else => unreachable,
27092789 }
27102790}
27112791
2792/// Asserts `val` has an integer type.
2793/// Assumes `new_ty` is an integer type.
2794pub fn getCoercedInts(ip: *InternPool, gpa: Allocator, int: Key.Int, new_ty: Index) Allocator.Error!Index {
2795 // The key cannot be passed directly to `get`, otherwise in the case of
2796 // big_int storage, the limbs would be invalidated before they are read.
2797 // Here we pre-reserve the limbs to ensure that the logic in `addInt` will
2798 // not use an invalidated limbs pointer.
2799 switch (int.storage) {
2800 .u64 => |x| return ip.get(gpa, .{ .int = .{
2801 .ty = new_ty,
2802 .storage = .{ .u64 = x },
2803 } }),
2804 .i64 => |x| return ip.get(gpa, .{ .int = .{
2805 .ty = new_ty,
2806 .storage = .{ .i64 = x },
2807 } }),
2808
2809 .big_int => |big_int| {
2810 const positive = big_int.positive;
2811 const limbs = ip.limbsSliceToIndex(big_int.limbs);
2812 // This line invalidates the limbs slice, but the indexes computed in the
2813 // previous line are still correct.
2814 try reserveLimbs(ip, gpa, @typeInfo(Int).Struct.fields.len + big_int.limbs.len);
2815 return ip.get(gpa, .{ .int = .{
2816 .ty = new_ty,
2817 .storage = .{ .big_int = .{
2818 .limbs = ip.limbsIndexToSlice(limbs),
2819 .positive = positive,
2820 } },
2821 } });
2822 },
2823 }
2824}
2825
27122826pub fn indexToStruct(ip: *InternPool, val: Index) Module.Struct.OptionalIndex {
27132827 const tags = ip.items.items(.tag);
27142828 if (val == .none) return .none;
......@@ -2805,6 +2919,7 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void {
28052919 .type_union_safety,
28062920 => @sizeOf(Module.Union) + @sizeOf(Module.Namespace) + @sizeOf(Module.Decl),
28072921
2922 .undef => 0,
28082923 .simple_type => 0,
28092924 .simple_value => 0,
28102925 .ptr_int => @sizeOf(PtrInt),
......@@ -2817,15 +2932,15 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void {
28172932 .int_usize => 0,
28182933 .int_comptime_int_u32 => 0,
28192934 .int_comptime_int_i32 => 0,
2935 .int_small => @sizeOf(IntSmall),
28202936
28212937 .int_positive,
28222938 .int_negative,
2823 .enum_tag_positive,
2824 .enum_tag_negative,
28252939 => b: {
28262940 const int = ip.limbData(Int, data);
28272941 break :b @sizeOf(Int) + int.limbs_len * 8;
28282942 },
2943 .enum_tag => @sizeOf(Key.EnumTag),
28292944
28302945 .float_f16 => 0,
28312946 .float_f32 => 0,
......@@ -2958,3 +3073,9 @@ pub fn stringToSlice(ip: InternPool, s: NullTerminatedString) [:0]const u8 {
29583073pub fn typeOf(ip: InternPool, index: Index) Index {
29593074 return ip.indexToKey(index).typeOf();
29603075}
3076
3077/// Assumes that the enum's field indexes equal its value tags.
3078pub fn toEnum(ip: InternPool, comptime E: type, i: Index) E {
3079 const int = ip.indexToKey(i).enum_tag.int;
3080 return @intToEnum(E, ip.indexToKey(int).int.storage.u64);
3081}
src/Module.zig+44-3
......@@ -6896,6 +6896,43 @@ pub fn ptrIntValue_ptronly(mod: *Module, ty: Type, x: u64) Allocator.Error!Value
68966896 return i.toValue();
68976897}
68986898
6899/// Creates an enum tag value based on the integer tag value.
6900pub fn enumValue(mod: *Module, ty: Type, tag_int: InternPool.Index) Allocator.Error!Value {
6901 if (std.debug.runtime_safety) {
6902 const tag = ty.zigTypeTag(mod);
6903 assert(tag == .Enum);
6904 }
6905 const i = try intern(mod, .{ .enum_tag = .{
6906 .ty = ty.ip_index,
6907 .int = tag_int,
6908 } });
6909 return i.toValue();
6910}
6911
6912/// Creates an enum tag value based on the field index according to source code
6913/// declaration order.
6914pub fn enumValueFieldIndex(mod: *Module, ty: Type, field_index: u32) Allocator.Error!Value {
6915 const ip = &mod.intern_pool;
6916 const gpa = mod.gpa;
6917 const enum_type = ip.indexToKey(ty.ip_index).enum_type;
6918
6919 if (enum_type.values.len == 0) {
6920 // Auto-numbered fields.
6921 return (try ip.get(gpa, .{ .enum_tag = .{
6922 .ty = ty.ip_index,
6923 .int = try ip.get(gpa, .{ .int = .{
6924 .ty = enum_type.tag_ty,
6925 .storage = .{ .u64 = field_index },
6926 } }),
6927 } })).toValue();
6928 }
6929
6930 return (try ip.get(gpa, .{ .enum_tag = .{
6931 .ty = ty.ip_index,
6932 .int = enum_type.values[field_index],
6933 } })).toValue();
6934}
6935
68996936pub fn intValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value {
69006937 if (std.debug.runtime_safety) {
69016938 const tag = ty.zigTypeTag(mod);
......@@ -6967,8 +7004,8 @@ pub fn smallestUnsignedInt(mod: *Module, max: u64) Allocator.Error!Type {
69677004/// `max`. Asserts that neither value is undef.
69687005/// TODO: if #3806 is implemented, this becomes trivial
69697006pub fn intFittingRange(mod: *Module, min: Value, max: Value) !Type {
6970 assert(!min.isUndef());
6971 assert(!max.isUndef());
7007 assert(!min.isUndef(mod));
7008 assert(!max.isUndef(mod));
69727009
69737010 if (std.debug.runtime_safety) {
69747011 assert(Value.order(min, max, mod).compare(.lte));
......@@ -6990,7 +7027,7 @@ pub fn intFittingRange(mod: *Module, min: Value, max: Value) !Type {
69907027/// twos-complement integer; otherwise in an unsigned integer.
69917028/// Asserts that `val` is not undef. If `val` is negative, asserts that `sign` is true.
69927029pub fn intBitsForValue(mod: *Module, val: Value, sign: bool) u16 {
6993 assert(!val.isUndef());
7030 assert(!val.isUndef(mod));
69947031
69957032 const key = mod.intern_pool.indexToKey(val.ip_index);
69967033 switch (key.int.storage) {
......@@ -7193,3 +7230,7 @@ pub fn fieldSrcLoc(mod: *Module, owner_decl_index: Decl.Index, query: FieldSrcQu
71937230 return owner_decl.srcLoc(mod);
71947231 }
71957232}
7233
7234pub fn toEnum(mod: *Module, comptime E: type, val: Value) E {
7235 return mod.intern_pool.toEnum(E, val.ip_index);
7236}
src/Sema.zig+249-238
......@@ -1904,8 +1904,9 @@ fn resolveDefinedValue(
19041904 src: LazySrcLoc,
19051905 air_ref: Air.Inst.Ref,
19061906) CompileError!?Value {
1907 const mod = sema.mod;
19071908 if (try sema.resolveMaybeUndefVal(air_ref)) |val| {
1908 if (val.isUndef()) {
1909 if (val.isUndef(mod)) {
19091910 if (block.is_typeof) return null;
19101911 return sema.failWithUseOfUndef(block, src);
19111912 }
......@@ -4333,7 +4334,7 @@ fn validateUnionInit(
43334334
43344335 const tag_ty = union_ty.unionTagTypeHypothetical(mod);
43354336 const enum_field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name, mod).?);
4336 const tag_val = try Value.Tag.enum_field_index.create(sema.arena, enum_field_index);
4337 const tag_val = try mod.enumValueFieldIndex(tag_ty, enum_field_index);
43374338
43384339 if (init_val) |val| {
43394340 // Our task is to delete all the `field_ptr` and `store` instructions, and insert
......@@ -4832,7 +4833,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
48324833
48334834 const elem_ty = operand_ty.elemType2(mod);
48344835 if (try sema.resolveMaybeUndefVal(operand)) |val| {
4835 if (val.isUndef()) {
4836 if (val.isUndef(mod)) {
48364837 return sema.fail(block, src, "cannot dereference undefined value", .{});
48374838 }
48384839 } else if (!(try sema.validateRunTimeType(elem_ty, false))) {
......@@ -6194,15 +6195,16 @@ fn lookupInNamespace(
61946195}
61956196
61966197fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {
6198 const mod = sema.mod;
61976199 const func_val = (try sema.resolveMaybeUndefVal(func_inst)) orelse return null;
6198 if (func_val.isUndef()) return null;
6200 if (func_val.isUndef(mod)) return null;
61996201 const owner_decl_index = switch (func_val.tag()) {
62006202 .extern_fn => func_val.castTag(.extern_fn).?.data.owner_decl,
62016203 .function => func_val.castTag(.function).?.data.owner_decl,
6202 .decl_ref => sema.mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data.owner_decl,
6204 .decl_ref => mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data.owner_decl,
62036205 else => return null,
62046206 };
6205 return sema.mod.declPtr(owner_decl_index);
6207 return mod.declPtr(owner_decl_index);
62066208}
62076209
62086210pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {
......@@ -8106,7 +8108,7 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
81068108 const operand = try sema.coerce(block, Type.anyerror, uncasted_operand, operand_src);
81078109
81088110 if (try sema.resolveMaybeUndefVal(operand)) |val| {
8109 if (val.isUndef()) {
8111 if (val.isUndef(mod)) {
81108112 return sema.addConstUndef(Type.err_int);
81118113 }
81128114 switch (val.tag()) {
......@@ -8326,7 +8328,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
83268328 };
83278329 return sema.failWithOwnedErrorMsg(msg);
83288330 }
8329 if (int_val.isUndef()) {
8331 if (int_val.isUndef(mod)) {
83308332 return sema.failWithUseOfUndef(block, operand_src);
83318333 }
83328334 if (!(try sema.enumHasInt(dest_ty, int_val))) {
......@@ -11472,7 +11474,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1147211474 if (f != null) continue;
1147311475 cases_len += 1;
1147411476
11475 const item_val = try Value.Tag.enum_field_index.create(sema.arena, @intCast(u32, i));
11477 const item_val = try mod.enumValueFieldIndex(operand_ty, @intCast(u32, i));
1147611478 const item_ref = try sema.addConstant(operand_ty, item_val);
1147711479 case_block.inline_case_capture = item_ref;
1147811480
......@@ -12208,7 +12210,7 @@ fn zirShl(
1220812210 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(rhs);
1220912211
1221012212 if (maybe_rhs_val) |rhs_val| {
12211 if (rhs_val.isUndef()) {
12213 if (rhs_val.isUndef(mod)) {
1221212214 return sema.addConstUndef(sema.typeOf(lhs));
1221312215 }
1221412216 // If rhs is 0, return lhs without doing any calculations.
......@@ -12255,7 +12257,7 @@ fn zirShl(
1225512257 }
1225612258
1225712259 const runtime_src = if (maybe_lhs_val) |lhs_val| rs: {
12258 if (lhs_val.isUndef()) return sema.addConstUndef(lhs_ty);
12260 if (lhs_val.isUndef(mod)) return sema.addConstUndef(lhs_ty);
1225912261 const rhs_val = maybe_rhs_val orelse {
1226012262 if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) {
1226112263 return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be comptime-known", .{});
......@@ -12389,7 +12391,7 @@ fn zirShr(
1238912391 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(rhs);
1239012392
1239112393 const runtime_src = if (maybe_rhs_val) |rhs_val| rs: {
12392 if (rhs_val.isUndef()) {
12394 if (rhs_val.isUndef(mod)) {
1239312395 return sema.addConstUndef(lhs_ty);
1239412396 }
1239512397 // If rhs is 0, return lhs without doing any calculations.
......@@ -12434,7 +12436,7 @@ fn zirShr(
1243412436 });
1243512437 }
1243612438 if (maybe_lhs_val) |lhs_val| {
12437 if (lhs_val.isUndef()) {
12439 if (lhs_val.isUndef(mod)) {
1243812440 return sema.addConstUndef(lhs_ty);
1243912441 }
1244012442 if (air_tag == .shr_exact) {
......@@ -12578,7 +12580,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1257812580 }
1257912581
1258012582 if (try sema.resolveMaybeUndefVal(operand)) |val| {
12581 if (val.isUndef()) {
12583 if (val.isUndef(mod)) {
1258212584 return sema.addConstUndef(operand_type);
1258312585 } else if (operand_type.zigTypeTag(mod) == .Vector) {
1258412586 const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen(mod));
......@@ -13154,7 +13156,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1315413156 if (rhs_scalar_ty.isAnyFloat()) {
1315513157 // We handle float negation here to ensure negative zero is represented in the bits.
1315613158 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {
13157 if (rhs_val.isUndef()) return sema.addConstUndef(rhs_ty);
13159 if (rhs_val.isUndef(mod)) return sema.addConstUndef(rhs_ty);
1315813160 return sema.addConstant(rhs_ty, try rhs_val.floatNeg(rhs_ty, sema.arena, sema.mod));
1315913161 }
1316013162 try sema.requireRuntimeBlock(block, src, null);
......@@ -13297,7 +13299,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1329713299 switch (scalar_tag) {
1329813300 .Int, .ComptimeInt, .ComptimeFloat => {
1329913301 if (maybe_lhs_val) |lhs_val| {
13300 if (!lhs_val.isUndef()) {
13302 if (!lhs_val.isUndef(mod)) {
1330113303 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
1330213304 const scalar_zero = switch (scalar_tag) {
1330313305 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
......@@ -13312,7 +13314,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1331213314 }
1331313315 }
1331413316 if (maybe_rhs_val) |rhs_val| {
13315 if (rhs_val.isUndef()) {
13317 if (rhs_val.isUndef(mod)) {
1331613318 return sema.failWithUseOfUndef(block, rhs_src);
1331713319 }
1331813320 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
......@@ -13326,7 +13328,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1332613328
1332713329 const runtime_src = rs: {
1332813330 if (maybe_lhs_val) |lhs_val| {
13329 if (lhs_val.isUndef()) {
13331 if (lhs_val.isUndef(mod)) {
1333013332 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {
1333113333 if (maybe_rhs_val) |rhs_val| {
1333213334 if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) {
......@@ -13434,7 +13436,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1343413436 // If the lhs is undefined, compile error because there is a possible
1343513437 // value for which the division would result in a remainder.
1343613438 if (maybe_lhs_val) |lhs_val| {
13437 if (lhs_val.isUndef()) {
13439 if (lhs_val.isUndef(mod)) {
1343813440 return sema.failWithUseOfUndef(block, rhs_src);
1343913441 } else {
1344013442 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
......@@ -13451,7 +13453,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1345113453 }
1345213454 }
1345313455 if (maybe_rhs_val) |rhs_val| {
13454 if (rhs_val.isUndef()) {
13456 if (rhs_val.isUndef(mod)) {
1345513457 return sema.failWithUseOfUndef(block, rhs_src);
1345613458 }
1345713459 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
......@@ -13611,7 +13613,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1361113613 // value (zero) for which the division would be illegal behavior.
1361213614 // If the lhs is undefined, result is undefined.
1361313615 if (maybe_lhs_val) |lhs_val| {
13614 if (!lhs_val.isUndef()) {
13616 if (!lhs_val.isUndef(mod)) {
1361513617 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
1361613618 const scalar_zero = switch (scalar_tag) {
1361713619 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
......@@ -13626,7 +13628,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1362613628 }
1362713629 }
1362813630 if (maybe_rhs_val) |rhs_val| {
13629 if (rhs_val.isUndef()) {
13631 if (rhs_val.isUndef(mod)) {
1363013632 return sema.failWithUseOfUndef(block, rhs_src);
1363113633 }
1363213634 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
......@@ -13635,7 +13637,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1363513637 // TODO: if the RHS is one, return the LHS directly
1363613638 }
1363713639 if (maybe_lhs_val) |lhs_val| {
13638 if (lhs_val.isUndef()) {
13640 if (lhs_val.isUndef(mod)) {
1363913641 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {
1364013642 if (maybe_rhs_val) |rhs_val| {
1364113643 if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) {
......@@ -13732,7 +13734,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1373213734 // value (zero) for which the division would be illegal behavior.
1373313735 // If the lhs is undefined, result is undefined.
1373413736 if (maybe_lhs_val) |lhs_val| {
13735 if (!lhs_val.isUndef()) {
13737 if (!lhs_val.isUndef(mod)) {
1373613738 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
1373713739 const scalar_zero = switch (scalar_tag) {
1373813740 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
......@@ -13747,7 +13749,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1374713749 }
1374813750 }
1374913751 if (maybe_rhs_val) |rhs_val| {
13750 if (rhs_val.isUndef()) {
13752 if (rhs_val.isUndef(mod)) {
1375113753 return sema.failWithUseOfUndef(block, rhs_src);
1375213754 }
1375313755 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
......@@ -13755,7 +13757,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1375513757 }
1375613758 }
1375713759 if (maybe_lhs_val) |lhs_val| {
13758 if (lhs_val.isUndef()) {
13760 if (lhs_val.isUndef(mod)) {
1375913761 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {
1376013762 if (maybe_rhs_val) |rhs_val| {
1376113763 if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) {
......@@ -13977,7 +13979,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1397713979 // then emit a compile error saying you have to pick one.
1397813980 if (is_int) {
1397913981 if (maybe_lhs_val) |lhs_val| {
13980 if (lhs_val.isUndef()) {
13982 if (lhs_val.isUndef(mod)) {
1398113983 return sema.failWithUseOfUndef(block, lhs_src);
1398213984 }
1398313985 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
......@@ -13995,7 +13997,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1399513997 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
1399613998 }
1399713999 if (maybe_rhs_val) |rhs_val| {
13998 if (rhs_val.isUndef()) {
14000 if (rhs_val.isUndef(mod)) {
1399914001 return sema.failWithUseOfUndef(block, rhs_src);
1400014002 }
1400114003 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
......@@ -14024,7 +14026,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1402414026 }
1402514027 // float operands
1402614028 if (maybe_rhs_val) |rhs_val| {
14027 if (rhs_val.isUndef()) {
14029 if (rhs_val.isUndef(mod)) {
1402814030 return sema.failWithUseOfUndef(block, rhs_src);
1402914031 }
1403014032 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
......@@ -14034,7 +14036,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1403414036 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);
1403514037 }
1403614038 if (maybe_lhs_val) |lhs_val| {
14037 if (lhs_val.isUndef() or !(try lhs_val.compareAllWithZeroAdvanced(.gte, sema))) {
14039 if (lhs_val.isUndef(mod) or !(try lhs_val.compareAllWithZeroAdvanced(.gte, sema))) {
1403814040 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
1403914041 }
1404014042 return sema.addConstant(
......@@ -14155,12 +14157,12 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1415514157 // If the lhs is undefined, result is undefined.
1415614158 if (is_int) {
1415714159 if (maybe_lhs_val) |lhs_val| {
14158 if (lhs_val.isUndef()) {
14160 if (lhs_val.isUndef(mod)) {
1415914161 return sema.failWithUseOfUndef(block, lhs_src);
1416014162 }
1416114163 }
1416214164 if (maybe_rhs_val) |rhs_val| {
14163 if (rhs_val.isUndef()) {
14165 if (rhs_val.isUndef(mod)) {
1416414166 return sema.failWithUseOfUndef(block, rhs_src);
1416514167 }
1416614168 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
......@@ -14179,7 +14181,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1417914181 }
1418014182 // float operands
1418114183 if (maybe_rhs_val) |rhs_val| {
14182 if (rhs_val.isUndef()) {
14184 if (rhs_val.isUndef(mod)) {
1418314185 return sema.failWithUseOfUndef(block, rhs_src);
1418414186 }
1418514187 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
......@@ -14187,7 +14189,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1418714189 }
1418814190 }
1418914191 if (maybe_lhs_val) |lhs_val| {
14190 if (lhs_val.isUndef()) {
14192 if (lhs_val.isUndef(mod)) {
1419114193 return sema.addConstUndef(resolved_type);
1419214194 }
1419314195 if (maybe_rhs_val) |rhs_val| {
......@@ -14257,12 +14259,12 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1425714259 // If the lhs is undefined, result is undefined.
1425814260 if (is_int) {
1425914261 if (maybe_lhs_val) |lhs_val| {
14260 if (lhs_val.isUndef()) {
14262 if (lhs_val.isUndef(mod)) {
1426114263 return sema.failWithUseOfUndef(block, lhs_src);
1426214264 }
1426314265 }
1426414266 if (maybe_rhs_val) |rhs_val| {
14265 if (rhs_val.isUndef()) {
14267 if (rhs_val.isUndef(mod)) {
1426614268 return sema.failWithUseOfUndef(block, rhs_src);
1426714269 }
1426814270 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
......@@ -14281,7 +14283,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1428114283 }
1428214284 // float operands
1428314285 if (maybe_rhs_val) |rhs_val| {
14284 if (rhs_val.isUndef()) {
14286 if (rhs_val.isUndef(mod)) {
1428514287 return sema.failWithUseOfUndef(block, rhs_src);
1428614288 }
1428714289 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
......@@ -14289,7 +14291,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1428914291 }
1429014292 }
1429114293 if (maybe_lhs_val) |lhs_val| {
14292 if (lhs_val.isUndef()) {
14294 if (lhs_val.isUndef(mod)) {
1429314295 return sema.addConstUndef(resolved_type);
1429414296 }
1429514297 if (maybe_rhs_val) |rhs_val| {
......@@ -14372,18 +14374,18 @@ fn zirOverflowArithmetic(
1437214374 // to the result, even if it is undefined..
1437314375 // Otherwise, if either of the argument is undefined, undefined is returned.
1437414376 if (maybe_lhs_val) |lhs_val| {
14375 if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
14377 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
1437614378 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = rhs };
1437714379 }
1437814380 }
1437914381 if (maybe_rhs_val) |rhs_val| {
14380 if (!rhs_val.isUndef() and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
14382 if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
1438114383 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };
1438214384 }
1438314385 }
1438414386 if (maybe_lhs_val) |lhs_val| {
1438514387 if (maybe_rhs_val) |rhs_val| {
14386 if (lhs_val.isUndef() or rhs_val.isUndef()) {
14388 if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) {
1438714389 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
1438814390 }
1438914391
......@@ -14396,12 +14398,12 @@ fn zirOverflowArithmetic(
1439614398 // If the rhs is zero, then the result is lhs and no overflow occured.
1439714399 // Otherwise, if either result is undefined, both results are undefined.
1439814400 if (maybe_rhs_val) |rhs_val| {
14399 if (rhs_val.isUndef()) {
14401 if (rhs_val.isUndef(mod)) {
1440014402 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
1440114403 } else if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
1440214404 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };
1440314405 } else if (maybe_lhs_val) |lhs_val| {
14404 if (lhs_val.isUndef()) {
14406 if (lhs_val.isUndef(mod)) {
1440514407 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
1440614408 }
1440714409
......@@ -14416,7 +14418,7 @@ fn zirOverflowArithmetic(
1441614418 // Otherwise, if either of the arguments is undefined, both results are undefined.
1441714419 const scalar_one = try mod.intValue(dest_ty.scalarType(mod), 1);
1441814420 if (maybe_lhs_val) |lhs_val| {
14419 if (!lhs_val.isUndef()) {
14421 if (!lhs_val.isUndef(mod)) {
1442014422 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
1442114423 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };
1442214424 } else if (try sema.compareAll(lhs_val, .eq, try maybeRepeated(sema, dest_ty, scalar_one), dest_ty)) {
......@@ -14426,7 +14428,7 @@ fn zirOverflowArithmetic(
1442614428 }
1442714429
1442814430 if (maybe_rhs_val) |rhs_val| {
14429 if (!rhs_val.isUndef()) {
14431 if (!rhs_val.isUndef(mod)) {
1443014432 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
1443114433 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = rhs };
1443214434 } else if (try sema.compareAll(rhs_val, .eq, try maybeRepeated(sema, dest_ty, scalar_one), dest_ty)) {
......@@ -14437,7 +14439,7 @@ fn zirOverflowArithmetic(
1443714439
1443814440 if (maybe_lhs_val) |lhs_val| {
1443914441 if (maybe_rhs_val) |rhs_val| {
14440 if (lhs_val.isUndef() or rhs_val.isUndef()) {
14442 if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) {
1444114443 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
1444214444 }
1444314445
......@@ -14451,18 +14453,18 @@ fn zirOverflowArithmetic(
1445114453 // If rhs is zero, the result is lhs (even if undefined) and no overflow occurred.
1445214454 // Oterhwise if either of the arguments is undefined, both results are undefined.
1445314455 if (maybe_lhs_val) |lhs_val| {
14454 if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
14456 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
1445514457 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };
1445614458 }
1445714459 }
1445814460 if (maybe_rhs_val) |rhs_val| {
14459 if (!rhs_val.isUndef() and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
14461 if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
1446014462 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };
1446114463 }
1446214464 }
1446314465 if (maybe_lhs_val) |lhs_val| {
1446414466 if (maybe_rhs_val) |rhs_val| {
14465 if (lhs_val.isUndef() or rhs_val.isUndef()) {
14467 if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) {
1446614468 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
1446714469 }
1446814470
......@@ -14606,12 +14608,12 @@ fn analyzeArithmetic(
1460614608 // overflow (max_int), causing illegal behavior.
1460714609 // For floats: either operand being undef makes the result undef.
1460814610 if (maybe_lhs_val) |lhs_val| {
14609 if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
14611 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
1461014612 return casted_rhs;
1461114613 }
1461214614 }
1461314615 if (maybe_rhs_val) |rhs_val| {
14614 if (rhs_val.isUndef()) {
14616 if (rhs_val.isUndef(mod)) {
1461514617 if (is_int) {
1461614618 return sema.failWithUseOfUndef(block, rhs_src);
1461714619 } else {
......@@ -14624,7 +14626,7 @@ fn analyzeArithmetic(
1462414626 }
1462514627 const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .add_optimized else .add;
1462614628 if (maybe_lhs_val) |lhs_val| {
14627 if (lhs_val.isUndef()) {
14629 if (lhs_val.isUndef(mod)) {
1462814630 if (is_int) {
1462914631 return sema.failWithUseOfUndef(block, lhs_src);
1463014632 } else {
......@@ -14653,13 +14655,13 @@ fn analyzeArithmetic(
1465314655 // If either of the operands are zero, the other operand is returned.
1465414656 // If either of the operands are undefined, the result is undefined.
1465514657 if (maybe_lhs_val) |lhs_val| {
14656 if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
14658 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
1465714659 return casted_rhs;
1465814660 }
1465914661 }
1466014662 const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .addwrap_optimized else .addwrap;
1466114663 if (maybe_rhs_val) |rhs_val| {
14662 if (rhs_val.isUndef()) {
14664 if (rhs_val.isUndef(mod)) {
1466314665 return sema.addConstUndef(resolved_type);
1466414666 }
1466514667 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
......@@ -14678,12 +14680,12 @@ fn analyzeArithmetic(
1467814680 // If either of the operands are zero, then the other operand is returned.
1467914681 // If either of the operands are undefined, the result is undefined.
1468014682 if (maybe_lhs_val) |lhs_val| {
14681 if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
14683 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
1468214684 return casted_rhs;
1468314685 }
1468414686 }
1468514687 if (maybe_rhs_val) |rhs_val| {
14686 if (rhs_val.isUndef()) {
14688 if (rhs_val.isUndef(mod)) {
1468714689 return sema.addConstUndef(resolved_type);
1468814690 }
1468914691 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
......@@ -14708,7 +14710,7 @@ fn analyzeArithmetic(
1470814710 // overflow, causing illegal behavior.
1470914711 // For floats: either operand being undef makes the result undef.
1471014712 if (maybe_rhs_val) |rhs_val| {
14711 if (rhs_val.isUndef()) {
14713 if (rhs_val.isUndef(mod)) {
1471214714 if (is_int) {
1471314715 return sema.failWithUseOfUndef(block, rhs_src);
1471414716 } else {
......@@ -14721,7 +14723,7 @@ fn analyzeArithmetic(
1472114723 }
1472214724 const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .sub_optimized else .sub;
1472314725 if (maybe_lhs_val) |lhs_val| {
14724 if (lhs_val.isUndef()) {
14726 if (lhs_val.isUndef(mod)) {
1472514727 if (is_int) {
1472614728 return sema.failWithUseOfUndef(block, lhs_src);
1472714729 } else {
......@@ -14750,7 +14752,7 @@ fn analyzeArithmetic(
1475014752 // If the RHS is zero, then the other operand is returned, even if it is undefined.
1475114753 // If either of the operands are undefined, the result is undefined.
1475214754 if (maybe_rhs_val) |rhs_val| {
14753 if (rhs_val.isUndef()) {
14755 if (rhs_val.isUndef(mod)) {
1475414756 return sema.addConstUndef(resolved_type);
1475514757 }
1475614758 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
......@@ -14759,7 +14761,7 @@ fn analyzeArithmetic(
1475914761 }
1476014762 const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .subwrap_optimized else .subwrap;
1476114763 if (maybe_lhs_val) |lhs_val| {
14762 if (lhs_val.isUndef()) {
14764 if (lhs_val.isUndef(mod)) {
1476314765 return sema.addConstUndef(resolved_type);
1476414766 }
1476514767 if (maybe_rhs_val) |rhs_val| {
......@@ -14775,7 +14777,7 @@ fn analyzeArithmetic(
1477514777 // If the RHS is zero, result is LHS.
1477614778 // If either of the operands are undefined, result is undefined.
1477714779 if (maybe_rhs_val) |rhs_val| {
14778 if (rhs_val.isUndef()) {
14780 if (rhs_val.isUndef(mod)) {
1477914781 return sema.addConstUndef(resolved_type);
1478014782 }
1478114783 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
......@@ -14783,7 +14785,7 @@ fn analyzeArithmetic(
1478314785 }
1478414786 }
1478514787 if (maybe_lhs_val) |lhs_val| {
14786 if (lhs_val.isUndef()) {
14788 if (lhs_val.isUndef(mod)) {
1478714789 return sema.addConstUndef(resolved_type);
1478814790 }
1478914791 if (maybe_rhs_val) |rhs_val| {
......@@ -14814,7 +14816,7 @@ fn analyzeArithmetic(
1481414816 else => unreachable,
1481514817 };
1481614818 if (maybe_lhs_val) |lhs_val| {
14817 if (!lhs_val.isUndef()) {
14819 if (!lhs_val.isUndef(mod)) {
1481814820 if (lhs_val.isNan(mod)) {
1481914821 return sema.addConstant(resolved_type, lhs_val);
1482014822 }
......@@ -14844,7 +14846,7 @@ fn analyzeArithmetic(
1484414846 }
1484514847 const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .mul_optimized else .mul;
1484614848 if (maybe_rhs_val) |rhs_val| {
14847 if (rhs_val.isUndef()) {
14849 if (rhs_val.isUndef(mod)) {
1484814850 if (is_int) {
1484914851 return sema.failWithUseOfUndef(block, rhs_src);
1485014852 } else {
......@@ -14874,7 +14876,7 @@ fn analyzeArithmetic(
1487414876 return casted_lhs;
1487514877 }
1487614878 if (maybe_lhs_val) |lhs_val| {
14877 if (lhs_val.isUndef()) {
14879 if (lhs_val.isUndef(mod)) {
1487814880 if (is_int) {
1487914881 return sema.failWithUseOfUndef(block, lhs_src);
1488014882 } else {
......@@ -14908,7 +14910,7 @@ fn analyzeArithmetic(
1490814910 else => unreachable,
1490914911 };
1491014912 if (maybe_lhs_val) |lhs_val| {
14911 if (!lhs_val.isUndef()) {
14913 if (!lhs_val.isUndef(mod)) {
1491214914 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
1491314915 const zero_val = if (is_vector) b: {
1491414916 break :b try Value.Tag.repeated.create(sema.arena, scalar_zero);
......@@ -14922,7 +14924,7 @@ fn analyzeArithmetic(
1492214924 }
1492314925 const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .mulwrap_optimized else .mulwrap;
1492414926 if (maybe_rhs_val) |rhs_val| {
14925 if (rhs_val.isUndef()) {
14927 if (rhs_val.isUndef(mod)) {
1492614928 return sema.addConstUndef(resolved_type);
1492714929 }
1492814930 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
......@@ -14935,7 +14937,7 @@ fn analyzeArithmetic(
1493514937 return casted_lhs;
1493614938 }
1493714939 if (maybe_lhs_val) |lhs_val| {
14938 if (lhs_val.isUndef()) {
14940 if (lhs_val.isUndef(mod)) {
1493914941 return sema.addConstUndef(resolved_type);
1494014942 }
1494114943 return sema.addConstant(
......@@ -14956,7 +14958,7 @@ fn analyzeArithmetic(
1495614958 else => unreachable,
1495714959 };
1495814960 if (maybe_lhs_val) |lhs_val| {
14959 if (!lhs_val.isUndef()) {
14961 if (!lhs_val.isUndef(mod)) {
1496014962 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
1496114963 const zero_val = if (is_vector) b: {
1496214964 break :b try Value.Tag.repeated.create(sema.arena, scalar_zero);
......@@ -14969,7 +14971,7 @@ fn analyzeArithmetic(
1496914971 }
1497014972 }
1497114973 if (maybe_rhs_val) |rhs_val| {
14972 if (rhs_val.isUndef()) {
14974 if (rhs_val.isUndef(mod)) {
1497314975 return sema.addConstUndef(resolved_type);
1497414976 }
1497514977 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
......@@ -14982,7 +14984,7 @@ fn analyzeArithmetic(
1498214984 return casted_lhs;
1498314985 }
1498414986 if (maybe_lhs_val) |lhs_val| {
14985 if (lhs_val.isUndef()) {
14987 if (lhs_val.isUndef(mod)) {
1498614988 return sema.addConstUndef(resolved_type);
1498714989 }
1498814990
......@@ -15100,7 +15102,7 @@ fn analyzePtrArithmetic(
1510015102 const runtime_src = rs: {
1510115103 if (opt_ptr_val) |ptr_val| {
1510215104 if (opt_off_val) |offset_val| {
15103 if (ptr_val.isUndef()) return sema.addConstUndef(new_ptr_ty);
15105 if (ptr_val.isUndef(mod)) return sema.addConstUndef(new_ptr_ty);
1510415106
1510515107 const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt(mod));
1510615108 if (offset_int == 0) return ptr;
......@@ -15363,7 +15365,7 @@ fn zirCmpEq(
1536315365 const runtime_src: LazySrcLoc = src: {
1536415366 if (try sema.resolveMaybeUndefVal(lhs)) |lval| {
1536515367 if (try sema.resolveMaybeUndefVal(rhs)) |rval| {
15366 if (lval.isUndef() or rval.isUndef()) {
15368 if (lval.isUndef(mod) or rval.isUndef(mod)) {
1536715369 return sema.addConstUndef(Type.bool);
1536815370 }
1536915371 // TODO optimisation opportunity: evaluate if mem.eql is faster with the names,
......@@ -15425,7 +15427,7 @@ fn analyzeCmpUnionTag(
1542515427 const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src);
1542615428
1542715429 if (try sema.resolveMaybeUndefVal(coerced_tag)) |enum_val| {
15428 if (enum_val.isUndef()) return sema.addConstUndef(Type.bool);
15430 if (enum_val.isUndef(mod)) return sema.addConstUndef(Type.bool);
1542915431 const field_ty = union_ty.unionFieldType(enum_val, sema.mod);
1543015432 if (field_ty.zigTypeTag(mod) == .NoReturn) {
1543115433 return Air.Inst.Ref.bool_false;
......@@ -15527,9 +15529,9 @@ fn cmpSelf(
1552715529 const resolved_type = sema.typeOf(casted_lhs);
1552815530 const runtime_src: LazySrcLoc = src: {
1552915531 if (try sema.resolveMaybeUndefVal(casted_lhs)) |lhs_val| {
15530 if (lhs_val.isUndef()) return sema.addConstUndef(Type.bool);
15532 if (lhs_val.isUndef(mod)) return sema.addConstUndef(Type.bool);
1553115533 if (try sema.resolveMaybeUndefVal(casted_rhs)) |rhs_val| {
15532 if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool);
15534 if (rhs_val.isUndef(mod)) return sema.addConstUndef(Type.bool);
1553315535
1553415536 if (resolved_type.zigTypeTag(mod) == .Vector) {
1553515537 const result_ty = try mod.vectorType(.{
......@@ -15557,7 +15559,7 @@ fn cmpSelf(
1555715559 // bool eq/neq more efficiently.
1555815560 if (resolved_type.zigTypeTag(mod) == .Bool) {
1555915561 if (try sema.resolveMaybeUndefVal(casted_rhs)) |rhs_val| {
15560 if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool);
15562 if (rhs_val.isUndef(mod)) return sema.addConstUndef(Type.bool);
1556115563 return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(mod), lhs_src);
1556215564 }
1556315565 }
......@@ -15892,68 +15894,69 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1589215894 const src = inst_data.src();
1589315895 const ty = try sema.resolveType(block, src, inst_data.operand);
1589415896 const type_info_ty = try sema.getBuiltinType("Type");
15897 const type_info_tag_ty = type_info_ty.unionTagType(mod).?;
1589515898
1589615899 switch (ty.zigTypeTag(mod)) {
1589715900 .Type => return sema.addConstant(
1589815901 type_info_ty,
1589915902 try Value.Tag.@"union".create(sema.arena, .{
15900 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Type)),
15903 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.Type)),
1590115904 .val = Value.void,
1590215905 }),
1590315906 ),
1590415907 .Void => return sema.addConstant(
1590515908 type_info_ty,
1590615909 try Value.Tag.@"union".create(sema.arena, .{
15907 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Void)),
15910 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.Void)),
1590815911 .val = Value.void,
1590915912 }),
1591015913 ),
1591115914 .Bool => return sema.addConstant(
1591215915 type_info_ty,
1591315916 try Value.Tag.@"union".create(sema.arena, .{
15914 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Bool)),
15917 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.Bool)),
1591515918 .val = Value.void,
1591615919 }),
1591715920 ),
1591815921 .NoReturn => return sema.addConstant(
1591915922 type_info_ty,
1592015923 try Value.Tag.@"union".create(sema.arena, .{
15921 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.NoReturn)),
15924 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.NoReturn)),
1592215925 .val = Value.void,
1592315926 }),
1592415927 ),
1592515928 .ComptimeFloat => return sema.addConstant(
1592615929 type_info_ty,
1592715930 try Value.Tag.@"union".create(sema.arena, .{
15928 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.ComptimeFloat)),
15931 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.ComptimeFloat)),
1592915932 .val = Value.void,
1593015933 }),
1593115934 ),
1593215935 .ComptimeInt => return sema.addConstant(
1593315936 type_info_ty,
1593415937 try Value.Tag.@"union".create(sema.arena, .{
15935 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.ComptimeInt)),
15938 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.ComptimeInt)),
1593615939 .val = Value.void,
1593715940 }),
1593815941 ),
1593915942 .Undefined => return sema.addConstant(
1594015943 type_info_ty,
1594115944 try Value.Tag.@"union".create(sema.arena, .{
15942 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Undefined)),
15945 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.Undefined)),
1594315946 .val = Value.void,
1594415947 }),
1594515948 ),
1594615949 .Null => return sema.addConstant(
1594715950 type_info_ty,
1594815951 try Value.Tag.@"union".create(sema.arena, .{
15949 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Null)),
15952 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.Null)),
1595015953 .val = Value.void,
1595115954 }),
1595215955 ),
1595315956 .EnumLiteral => return sema.addConstant(
1595415957 type_info_ty,
1595515958 try Value.Tag.@"union".create(sema.arena, .{
15956 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.EnumLiteral)),
15959 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.EnumLiteral)),
1595715960 .val = Value.void,
1595815961 }),
1595915962 ),
......@@ -16040,10 +16043,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1604016043 else
1604116044 Value.null;
1604216045
16046 const callconv_ty = try sema.getBuiltinType("CallingConvention");
16047
1604316048 const field_values = try sema.arena.create([6]Value);
1604416049 field_values.* = .{
1604516050 // calling_convention: CallingConvention,
16046 try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.cc)),
16051 try mod.enumValueFieldIndex(callconv_ty, @enumToInt(info.cc)),
1604716052 // alignment: comptime_int,
1604816053 try mod.intValue(Type.comptime_int, ty.abiAlignment(mod)),
1604916054 // is_generic: bool,
......@@ -16059,26 +16064,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1605916064 return sema.addConstant(
1606016065 type_info_ty,
1606116066 try Value.Tag.@"union".create(sema.arena, .{
16062 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Fn)),
16067 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.Fn)),
1606316068 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
1606416069 }),
1606516070 );
1606616071 },
1606716072 .Int => {
16073 const signedness_ty = try sema.getBuiltinType("Signedness");
1606816074 const info = ty.intInfo(mod);
1606916075 const field_values = try sema.arena.alloc(Value, 2);
1607016076 // signedness: Signedness,
16071 field_values[0] = try Value.Tag.enum_field_index.create(
16072 sema.arena,
16073 @enumToInt(info.signedness),
16074 );
16077 field_values[0] = try mod.enumValueFieldIndex(signedness_ty, @enumToInt(info.signedness));
1607516078 // bits: u16,
1607616079 field_values[1] = try mod.intValue(Type.u16, info.bits);
1607716080
1607816081 return sema.addConstant(
1607916082 type_info_ty,
1608016083 try Value.Tag.@"union".create(sema.arena, .{
16081 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Int)),
16084 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.Int)),
1608216085 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
1608316086 }),
1608416087 );
......@@ -16091,7 +16094,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1609116094 return sema.addConstant(
1609216095 type_info_ty,
1609316096 try Value.Tag.@"union".create(sema.arena, .{
16094 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Float)),
16097 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.Float)),
1609516098 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
1609616099 }),
1609716100 );
......@@ -16103,10 +16106,13 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1610316106 else
1610416107 try info.pointee_type.lazyAbiAlignment(mod, sema.arena);
1610516108
16109 const addrspace_ty = try sema.getBuiltinType("AddressSpace");
16110 const ptr_size_ty = try sema.getBuiltinType("PtrSize");
16111
1610616112 const field_values = try sema.arena.create([8]Value);
1610716113 field_values.* = .{
1610816114 // size: Size,
16109 try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.size)),
16115 try mod.enumValueFieldIndex(ptr_size_ty, @enumToInt(info.size)),
1611016116 // is_const: bool,
1611116117 Value.makeBool(!info.mutable),
1611216118 // is_volatile: bool,
......@@ -16114,7 +16120,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1611416120 // alignment: comptime_int,
1611516121 alignment,
1611616122 // address_space: AddressSpace
16117 try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.@"addrspace")),
16123 try mod.enumValueFieldIndex(addrspace_ty, @enumToInt(info.@"addrspace")),
1611816124 // child: type,
1611916125 try Value.Tag.ty.create(sema.arena, info.pointee_type),
1612016126 // is_allowzero: bool,
......@@ -16126,7 +16132,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1612616132 return sema.addConstant(
1612716133 type_info_ty,
1612816134 try Value.Tag.@"union".create(sema.arena, .{
16129 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Pointer)),
16135 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.Pointer)),
1613016136 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
1613116137 }),
1613216138 );
......@@ -16144,7 +16150,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1614416150 return sema.addConstant(
1614516151 type_info_ty,
1614616152 try Value.Tag.@"union".create(sema.arena, .{
16147 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Array)),
16153 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.Array)),
1614816154 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
1614916155 }),
1615016156 );
......@@ -16160,7 +16166,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1616016166 return sema.addConstant(
1616116167 type_info_ty,
1616216168 try Value.Tag.@"union".create(sema.arena, .{
16163 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Vector)),
16169 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.Vector)),
1616416170 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
1616516171 }),
1616616172 );
......@@ -16173,7 +16179,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1617316179 return sema.addConstant(
1617416180 type_info_ty,
1617516181 try Value.Tag.@"union".create(sema.arena, .{
16176 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Optional)),
16182 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.Optional)),
1617716183 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
1617816184 }),
1617916185 );
......@@ -16263,7 +16269,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1626316269 return sema.addConstant(
1626416270 type_info_ty,
1626516271 try Value.Tag.@"union".create(sema.arena, .{
16266 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.ErrorSet)),
16272 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.ErrorSet)),
1626716273 .val = errors_val,
1626816274 }),
1626916275 );
......@@ -16278,7 +16284,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1627816284 return sema.addConstant(
1627916285 type_info_ty,
1628016286 try Value.Tag.@"union".create(sema.arena, .{
16281 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.ErrorUnion)),
16287 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.ErrorUnion)),
1628216288 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
1628316289 }),
1628416290 );
......@@ -16365,7 +16371,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1636516371 return sema.addConstant(
1636616372 type_info_ty,
1636716373 try Value.Tag.@"union".create(sema.arena, .{
16368 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Enum)),
16374 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.Enum)),
1636916375 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
1637016376 }),
1637116377 );
......@@ -16454,13 +16460,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1645416460 break :v try Value.Tag.opt_payload.create(sema.arena, ty_val);
1645516461 } else Value.null;
1645616462
16463 const container_layout_ty = try sema.getBuiltinType("TmpContainerLayoutAlias");
16464
1645716465 const field_values = try sema.arena.create([4]Value);
1645816466 field_values.* = .{
1645916467 // layout: ContainerLayout,
16460 try Value.Tag.enum_field_index.create(
16461 sema.arena,
16462 @enumToInt(layout),
16463 ),
16468 try mod.enumValueFieldIndex(container_layout_ty, @enumToInt(layout)),
1646416469
1646516470 // tag_type: ?type,
1646616471 enum_tag_ty_val,
......@@ -16473,7 +16478,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1647316478 return sema.addConstant(
1647416479 type_info_ty,
1647516480 try Value.Tag.@"union".create(sema.arena, .{
16476 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Union)),
16481 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.Union)),
1647716482 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
1647816483 }),
1647916484 );
......@@ -16625,13 +16630,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1662516630 }
1662616631 };
1662716632
16633 const container_layout_ty = try sema.getBuiltinType("TmpContainerLayoutAlias");
16634
1662816635 const field_values = try sema.arena.create([5]Value);
1662916636 field_values.* = .{
1663016637 // layout: ContainerLayout,
16631 try Value.Tag.enum_field_index.create(
16632 sema.arena,
16633 @enumToInt(layout),
16634 ),
16638 try mod.enumValueFieldIndex(container_layout_ty, @enumToInt(layout)),
1663516639 // backing_integer: ?type,
1663616640 backing_integer_val,
1663716641 // fields: []const StructField,
......@@ -16645,7 +16649,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1664516649 return sema.addConstant(
1664616650 type_info_ty,
1664716651 try Value.Tag.@"union".create(sema.arena, .{
16648 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Struct)),
16652 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.Struct)),
1664916653 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
1665016654 }),
1665116655 );
......@@ -16665,7 +16669,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1666516669 return sema.addConstant(
1666616670 type_info_ty,
1666716671 try Value.Tag.@"union".create(sema.arena, .{
16668 .tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.Opaque)),
16672 .tag = try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.Opaque)),
1666916673 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
1667016674 }),
1667116675 );
......@@ -16912,7 +16916,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1691216916
1691316917 const operand = try sema.coerce(block, Type.bool, uncasted_operand, operand_src);
1691416918 if (try sema.resolveMaybeUndefVal(operand)) |val| {
16915 return if (val.isUndef())
16919 return if (val.isUndef(mod))
1691616920 sema.addConstUndef(Type.bool)
1691716921 else if (val.toBool(mod))
1691816922 Air.Inst.Ref.bool_false
......@@ -17879,7 +17883,7 @@ fn unionInit(
1787917883 if (try sema.resolveMaybeUndefVal(init)) |init_val| {
1788017884 const tag_ty = union_ty.unionTagTypeHypothetical(mod);
1788117885 const enum_field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name, mod).?);
17882 const tag_val = try Value.Tag.enum_field_index.create(sema.arena, enum_field_index);
17886 const tag_val = try mod.enumValueFieldIndex(tag_ty, enum_field_index);
1788317887 return sema.addConstant(union_ty, try Value.Tag.@"union".create(sema.arena, .{
1788417888 .tag = tag_val,
1788517889 .val = init_val,
......@@ -17980,7 +17984,7 @@ fn zirStructInit(
1798017984 const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src);
1798117985 const tag_ty = resolved_ty.unionTagTypeHypothetical(mod);
1798217986 const enum_field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name, mod).?);
17983 const tag_val = try Value.Tag.enum_field_index.create(sema.arena, enum_field_index);
17987 const tag_val = try mod.enumValueFieldIndex(tag_ty, enum_field_index);
1798417988
1798517989 const init_inst = try sema.resolveInst(item.data.init);
1798617990 if (try sema.resolveMaybeUndefVal(init_inst)) |val| {
......@@ -18614,7 +18618,7 @@ fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1861418618 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1861518619 const operand = try sema.resolveInst(inst_data.operand);
1861618620 if (try sema.resolveMaybeUndefVal(operand)) |val| {
18617 if (val.isUndef()) return sema.addConstUndef(Type.u1);
18621 if (val.isUndef(mod)) return sema.addConstUndef(Type.u1);
1861818622 if (val.toBool(mod)) return sema.addConstant(Type.u1, try mod.intValue(Type.u1, 1));
1861918623 return sema.addConstant(Type.u1, try mod.intValue(Type.u1, 0));
1862018624 }
......@@ -18673,7 +18677,7 @@ fn zirUnaryMath(
1867318677 .child = scalar_ty.ip_index,
1867418678 });
1867518679 if (try sema.resolveMaybeUndefVal(operand)) |val| {
18676 if (val.isUndef())
18680 if (val.isUndef(mod))
1867718681 return sema.addConstUndef(result_ty);
1867818682
1867918683 const elems = try sema.arena.alloc(Value, vec_len);
......@@ -18692,7 +18696,7 @@ fn zirUnaryMath(
1869218696 },
1869318697 .ComptimeFloat, .Float => {
1869418698 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
18695 if (operand_val.isUndef())
18699 if (operand_val.isUndef(mod))
1869618700 return sema.addConstUndef(operand_ty);
1869718701 const result_val = try eval(operand_val, operand_ty, sema.arena, sema.mod);
1869818702 return sema.addConstant(operand_ty, result_val);
......@@ -18809,7 +18813,7 @@ fn zirReify(
1880918813 const signedness_val = struct_val[0];
1881018814 const bits_val = struct_val[1];
1881118815
18812 const signedness = signedness_val.toEnum(std.builtin.Signedness);
18816 const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);
1881318817 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
1881418818 const ty = try mod.intType(signedness, bits);
1881518819 return sema.addType(ty);
......@@ -18874,7 +18878,7 @@ fn zirReify(
1887418878 break :t elem_ty;
1887518879 };
1887618880
18877 const ptr_size = size_val.toEnum(std.builtin.Type.Pointer.Size);
18881 const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val);
1887818882
1887918883 var actual_sentinel: ?Value = null;
1888018884 if (!sentinel_val.isNull(mod)) {
......@@ -18927,7 +18931,7 @@ fn zirReify(
1892718931 .mutable = !is_const_val.toBool(mod),
1892818932 .@"volatile" = is_volatile_val.toBool(mod),
1892918933 .@"align" = abi_align,
18930 .@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace),
18934 .@"addrspace" = mod.toEnum(std.builtin.AddressSpace, address_space_val),
1893118935 .pointee_type = try elem_ty.copy(sema.arena),
1893218936 .@"allowzero" = is_allowzero_val.toBool(mod),
1893318937 .sentinel = actual_sentinel,
......@@ -19033,7 +19037,7 @@ fn zirReify(
1903319037 const is_tuple_val = struct_val[4];
1903419038 assert(struct_val.len == 5);
1903519039
19036 const layout = layout_val.toEnum(std.builtin.Type.ContainerLayout);
19040 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
1903719041
1903819042 // Decls
1903919043 if (decls_val.sliceLen(mod) > 0) {
......@@ -19208,7 +19212,7 @@ fn zirReify(
1920819212 if (decls_val.sliceLen(mod) > 0) {
1920919213 return sema.fail(block, src, "reified unions must have no decls", .{});
1921019214 }
19211 const layout = layout_val.toEnum(std.builtin.Type.ContainerLayout);
19215 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
1921219216
1921319217 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
1921419218 errdefer new_decl_arena.deinit();
......@@ -19309,7 +19313,7 @@ fn zirReify(
1930919313 }
1931019314
1931119315 if (explicit_enum_info) |tag_info| {
19312 const enum_index = tag_info.nameIndex(mod.intern_pool, field_name_ip) orelse {
19316 const enum_index = tag_info.nameIndex(&mod.intern_pool, field_name_ip) orelse {
1931319317 const msg = msg: {
1931419318 const msg = try sema.errMsg(block, src, "no field named '{s}' in enum '{}'", .{ field_name, union_obj.tag_ty.fmt(mod) });
1931519319 errdefer msg.destroy(gpa);
......@@ -19402,7 +19406,7 @@ fn zirReify(
1940219406 const struct_val: []const Value = union_val.val.castTag(.aggregate).?.data;
1940319407 // TODO use reflection instead of magic numbers here
1940419408 // calling_convention: CallingConvention,
19405 const cc = struct_val[0].toEnum(std.builtin.CallingConvention);
19409 const cc = mod.toEnum(std.builtin.CallingConvention, struct_val[0]);
1940619410 // alignment: comptime_int,
1940719411 const alignment_val = struct_val[1];
1940819412 // is_generic: bool,
......@@ -20180,7 +20184,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2018020184 }
2018120185
2018220186 if (try sema.resolveMaybeUndefVal(ptr)) |operand_val| {
20183 if (!dest_ty.ptrAllowsZero(mod) and operand_val.isUndef()) {
20187 if (!dest_ty.ptrAllowsZero(mod) and operand_val.isUndef(mod)) {
2018420188 return sema.failWithUseOfUndef(block, operand_src);
2018520189 }
2018620190 if (!dest_ty.ptrAllowsZero(mod) and operand_val.isNull(mod)) {
......@@ -20315,7 +20319,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2031520319 }
2031620320
2031720321 if (try sema.resolveMaybeUndefValIntable(operand)) |val| {
20318 if (val.isUndef()) return sema.addConstUndef(dest_ty);
20322 if (val.isUndef(mod)) return sema.addConstUndef(dest_ty);
2031920323 if (!is_vector) {
2032020324 return sema.addConstant(
2032120325 dest_ty,
......@@ -20419,7 +20423,7 @@ fn zirBitCount(
2041920423 .child = result_scalar_ty.ip_index,
2042020424 });
2042120425 if (try sema.resolveMaybeUndefVal(operand)) |val| {
20422 if (val.isUndef()) return sema.addConstUndef(result_ty);
20426 if (val.isUndef(mod)) return sema.addConstUndef(result_ty);
2042320427
2042420428 const elems = try sema.arena.alloc(Value, vec_len);
2042520429 const scalar_ty = operand_ty.scalarType(mod);
......@@ -20439,7 +20443,7 @@ fn zirBitCount(
2043920443 },
2044020444 .Int => {
2044120445 if (try sema.resolveMaybeUndefVal(operand)) |val| {
20442 if (val.isUndef()) return sema.addConstUndef(result_scalar_ty);
20446 if (val.isUndef(mod)) return sema.addConstUndef(result_scalar_ty);
2044320447 try sema.resolveLazyValue(val);
2044420448 return sema.addIntUnsigned(result_scalar_ty, comptimeOp(val, operand_ty, mod));
2044520449 } else {
......@@ -20476,7 +20480,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2047620480 switch (operand_ty.zigTypeTag(mod)) {
2047720481 .Int => {
2047820482 const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {
20479 if (val.isUndef()) return sema.addConstUndef(operand_ty);
20483 if (val.isUndef(mod)) return sema.addConstUndef(operand_ty);
2048020484 const result_val = try val.byteSwap(operand_ty, mod, sema.arena);
2048120485 return sema.addConstant(operand_ty, result_val);
2048220486 } else operand_src;
......@@ -20486,7 +20490,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2048620490 },
2048720491 .Vector => {
2048820492 const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {
20489 if (val.isUndef())
20493 if (val.isUndef(mod))
2049020494 return sema.addConstUndef(operand_ty);
2049120495
2049220496 const vec_len = operand_ty.vectorLen(mod);
......@@ -20524,7 +20528,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2052420528 switch (operand_ty.zigTypeTag(mod)) {
2052520529 .Int => {
2052620530 const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {
20527 if (val.isUndef()) return sema.addConstUndef(operand_ty);
20531 if (val.isUndef(mod)) return sema.addConstUndef(operand_ty);
2052820532 const result_val = try val.bitReverse(operand_ty, mod, sema.arena);
2052920533 return sema.addConstant(operand_ty, result_val);
2053020534 } else operand_src;
......@@ -20534,7 +20538,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2053420538 },
2053520539 .Vector => {
2053620540 const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {
20537 if (val.isUndef())
20541 if (val.isUndef(mod))
2053820542 return sema.addConstUndef(operand_ty);
2053920543
2054020544 const vec_len = operand_ty.vectorLen(mod);
......@@ -21072,7 +21076,7 @@ fn resolveExportOptions(
2107221076
2107321077 const linkage_operand = try sema.fieldVal(block, src, options, "linkage", linkage_src);
2107421078 const linkage_val = try sema.resolveConstValue(block, linkage_src, linkage_operand, "linkage of exported value must be comptime-known");
21075 const linkage = linkage_val.toEnum(std.builtin.GlobalLinkage);
21079 const linkage = mod.toEnum(std.builtin.GlobalLinkage, linkage_val);
2107621080
2107721081 const section_operand = try sema.fieldVal(block, src, options, "section", section_src);
2107821082 const section_opt_val = try sema.resolveConstValue(block, section_src, section_operand, "linksection of exported value must be comptime-known");
......@@ -21084,7 +21088,7 @@ fn resolveExportOptions(
2108421088
2108521089 const visibility_operand = try sema.fieldVal(block, src, options, "visibility", visibility_src);
2108621090 const visibility_val = try sema.resolveConstValue(block, visibility_src, visibility_operand, "visibility of exported value must be comptime-known");
21087 const visibility = visibility_val.toEnum(std.builtin.SymbolVisibility);
21091 const visibility = mod.toEnum(std.builtin.SymbolVisibility, visibility_val);
2108821092
2108921093 if (name.len < 1) {
2109021094 return sema.fail(block, name_src, "exported symbol name cannot be empty", .{});
......@@ -21112,11 +21116,12 @@ fn resolveBuiltinEnum(
2111221116 comptime name: []const u8,
2111321117 reason: []const u8,
2111421118) CompileError!@field(std.builtin, name) {
21119 const mod = sema.mod;
2111521120 const ty = try sema.getBuiltinType(name);
2111621121 const air_ref = try sema.resolveInst(zir_ref);
2111721122 const coerced = try sema.coerce(block, ty, air_ref, src);
2111821123 const val = try sema.resolveConstValue(block, src, coerced, reason);
21119 return val.toEnum(@field(std.builtin, name));
21124 return mod.toEnum(@field(std.builtin, name), val);
2112021125}
2112121126
2112221127fn resolveAtomicOrder(
......@@ -21198,7 +21203,7 @@ fn zirCmpxchg(
2119821203 const runtime_src = if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| rs: {
2119921204 if (try sema.resolveMaybeUndefVal(expected_value)) |expected_val| {
2120021205 if (try sema.resolveMaybeUndefVal(new_value)) |new_val| {
21201 if (expected_val.isUndef() or new_val.isUndef()) {
21206 if (expected_val.isUndef(mod) or new_val.isUndef(mod)) {
2120221207 // TODO: this should probably cause the memory stored at the pointer
2120321208 // to become undef as well
2120421209 return sema.addConstUndef(result_ty);
......@@ -21248,7 +21253,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
2124821253 .child = scalar_ty.ip_index,
2124921254 });
2125021255 if (try sema.resolveMaybeUndefVal(scalar)) |scalar_val| {
21251 if (scalar_val.isUndef()) return sema.addConstUndef(vector_ty);
21256 if (scalar_val.isUndef(mod)) return sema.addConstUndef(vector_ty);
2125221257
2125321258 return sema.addConstant(
2125421259 vector_ty,
......@@ -21300,7 +21305,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
2130021305 }
2130121306
2130221307 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
21303 if (operand_val.isUndef()) return sema.addConstUndef(scalar_ty);
21308 if (operand_val.isUndef(mod)) return sema.addConstUndef(scalar_ty);
2130421309
2130521310 var accum: Value = try operand_val.elemValue(mod, 0);
2130621311 var i: u32 = 1;
......@@ -21420,7 +21425,7 @@ fn analyzeShuffle(
2142021425 var i: usize = 0;
2142121426 while (i < mask_len) : (i += 1) {
2142221427 const elem = try mask.elemValue(sema.mod, i);
21423 if (elem.isUndef()) continue;
21428 if (elem.isUndef(mod)) continue;
2142421429 const int = elem.toSignedInt(mod);
2142521430 var unsigned: u32 = undefined;
2142621431 var chosen: u32 = undefined;
......@@ -21458,7 +21463,7 @@ fn analyzeShuffle(
2145821463 i = 0;
2145921464 while (i < mask_len) : (i += 1) {
2146021465 const mask_elem_val = try mask.elemValue(sema.mod, i);
21461 if (mask_elem_val.isUndef()) {
21466 if (mask_elem_val.isUndef(mod)) {
2146221467 values[i] = Value.undef;
2146321468 continue;
2146421469 }
......@@ -21559,13 +21564,13 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2155921564 const maybe_b = try sema.resolveMaybeUndefVal(b);
2156021565
2156121566 const runtime_src = if (maybe_pred) |pred_val| rs: {
21562 if (pred_val.isUndef()) return sema.addConstUndef(vec_ty);
21567 if (pred_val.isUndef(mod)) return sema.addConstUndef(vec_ty);
2156321568
2156421569 if (maybe_a) |a_val| {
21565 if (a_val.isUndef()) return sema.addConstUndef(vec_ty);
21570 if (a_val.isUndef(mod)) return sema.addConstUndef(vec_ty);
2156621571
2156721572 if (maybe_b) |b_val| {
21568 if (b_val.isUndef()) return sema.addConstUndef(vec_ty);
21573 if (b_val.isUndef(mod)) return sema.addConstUndef(vec_ty);
2156921574
2157021575 const elems = try sema.gpa.alloc(Value, vec_len);
2157121576 for (elems, 0..) |*elem, i| {
......@@ -21587,16 +21592,16 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2158721592 }
2158821593 } else {
2158921594 if (maybe_b) |b_val| {
21590 if (b_val.isUndef()) return sema.addConstUndef(vec_ty);
21595 if (b_val.isUndef(mod)) return sema.addConstUndef(vec_ty);
2159121596 }
2159221597 break :rs a_src;
2159321598 }
2159421599 } else rs: {
2159521600 if (maybe_a) |a_val| {
21596 if (a_val.isUndef()) return sema.addConstUndef(vec_ty);
21601 if (a_val.isUndef(mod)) return sema.addConstUndef(vec_ty);
2159721602 }
2159821603 if (maybe_b) |b_val| {
21599 if (b_val.isUndef()) return sema.addConstUndef(vec_ty);
21604 if (b_val.isUndef(mod)) return sema.addConstUndef(vec_ty);
2160021605 }
2160121606 break :rs pred_src;
2160221607 };
......@@ -21803,10 +21808,10 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
2180321808
2180421809 const runtime_src = if (maybe_mulend1) |mulend1_val| rs: {
2180521810 if (maybe_mulend2) |mulend2_val| {
21806 if (mulend2_val.isUndef()) return sema.addConstUndef(ty);
21811 if (mulend2_val.isUndef(mod)) return sema.addConstUndef(ty);
2180721812
2180821813 if (maybe_addend) |addend_val| {
21809 if (addend_val.isUndef()) return sema.addConstUndef(ty);
21814 if (addend_val.isUndef(mod)) return sema.addConstUndef(ty);
2181021815 const result_val = try Value.mulAdd(ty, mulend1_val, mulend2_val, addend_val, sema.arena, sema.mod);
2181121816 return sema.addConstant(ty, result_val);
2181221817 } else {
......@@ -21814,16 +21819,16 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
2181421819 }
2181521820 } else {
2181621821 if (maybe_addend) |addend_val| {
21817 if (addend_val.isUndef()) return sema.addConstUndef(ty);
21822 if (addend_val.isUndef(mod)) return sema.addConstUndef(ty);
2181821823 }
2181921824 break :rs mulend2_src;
2182021825 }
2182121826 } else rs: {
2182221827 if (maybe_mulend2) |mulend2_val| {
21823 if (mulend2_val.isUndef()) return sema.addConstUndef(ty);
21828 if (mulend2_val.isUndef(mod)) return sema.addConstUndef(ty);
2182421829 }
2182521830 if (maybe_addend) |addend_val| {
21826 if (addend_val.isUndef()) return sema.addConstUndef(ty);
21831 if (addend_val.isUndef(mod)) return sema.addConstUndef(ty);
2182721832 }
2182821833 break :rs mulend1_src;
2182921834 };
......@@ -21859,7 +21864,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
2185921864 const air_ref = try sema.resolveInst(extra.modifier);
2186021865 const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src);
2186121866 const modifier_val = try sema.resolveConstValue(block, modifier_src, modifier_ref, "call modifier must be comptime-known");
21862 var modifier = modifier_val.toEnum(std.builtin.CallModifier);
21867 var modifier = mod.toEnum(std.builtin.CallModifier, modifier_val);
2186321868 switch (modifier) {
2186421869 // These can be upgraded to comptime or nosuspend calls.
2186521870 .auto, .never_tail, .no_async => {
......@@ -22111,8 +22116,8 @@ fn analyzeMinMax(
2211122116
2211222117 runtime_known.unset(operand_idx);
2211322118
22114 if (cur_val.isUndef()) continue; // result is also undef
22115 if (operand_val.isUndef()) {
22119 if (cur_val.isUndef(mod)) continue; // result is also undef
22120 if (operand_val.isUndef(mod)) {
2211622121 cur_minmax = try sema.addConstUndef(simd_op.result_ty);
2211722122 continue;
2211822123 }
......@@ -22165,7 +22170,7 @@ fn analyzeMinMax(
2216522170 var cur_max: Value = cur_min;
2216622171 for (1..len) |idx| {
2216722172 const elem_val = try val.elemValue(mod, idx);
22168 if (elem_val.isUndef()) break :blk orig_ty; // can't refine undef
22173 if (elem_val.isUndef(mod)) break :blk orig_ty; // can't refine undef
2216922174 if (Value.order(elem_val, cur_min, mod).compare(.lt)) cur_min = elem_val;
2217022175 if (Value.order(elem_val, cur_max, mod).compare(.gt)) cur_max = elem_val;
2217122176 }
......@@ -22177,7 +22182,7 @@ fn analyzeMinMax(
2217722182 });
2217822183 } else blk: {
2217922184 if (orig_ty.isAnyFloat()) break :blk orig_ty; // can't refine floats
22180 if (val.isUndef()) break :blk orig_ty; // can't refine undef
22185 if (val.isUndef(mod)) break :blk orig_ty; // can't refine undef
2218122186 break :blk try mod.intFittingRange(val, val);
2218222187 };
2218322188
......@@ -22205,7 +22210,7 @@ fn analyzeMinMax(
2220522210 // If the comptime-known part is undef we can avoid emitting actual instructions later
2220622211 const known_undef = if (cur_minmax) |operand| blk: {
2220722212 const val = (try sema.resolveMaybeUndefVal(operand)).?;
22208 break :blk val.isUndef();
22213 break :blk val.isUndef(mod);
2220922214 } else false;
2221022215
2221122216 if (cur_minmax == null) {
......@@ -22749,7 +22754,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2274922754 if (val.isGenericPoison()) {
2275022755 break :blk null;
2275122756 }
22752 break :blk val.toEnum(std.builtin.AddressSpace);
22757 break :blk mod.toEnum(std.builtin.AddressSpace, val);
2275322758 } else if (extra.data.bits.has_addrspace_ref) blk: {
2275422759 const addrspace_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
2275522760 extra_index += 1;
......@@ -22759,7 +22764,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2275922764 },
2276022765 else => |e| return e,
2276122766 };
22762 break :blk addrspace_tv.val.toEnum(std.builtin.AddressSpace);
22767 break :blk mod.toEnum(std.builtin.AddressSpace, addrspace_tv.val);
2276322768 } else target_util.defaultAddressSpace(target, .function);
2276422769
2276522770 const @"linksection": FuncLinkSection = if (extra.data.bits.has_section_body) blk: {
......@@ -22797,7 +22802,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2279722802 if (val.isGenericPoison()) {
2279822803 break :blk null;
2279922804 }
22800 break :blk val.toEnum(std.builtin.CallingConvention);
22805 break :blk mod.toEnum(std.builtin.CallingConvention, val);
2280122806 } else if (extra.data.bits.has_cc_ref) blk: {
2280222807 const cc_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
2280322808 extra_index += 1;
......@@ -22807,7 +22812,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2280722812 },
2280822813 else => |e| return e,
2280922814 };
22810 break :blk cc_tv.val.toEnum(std.builtin.CallingConvention);
22815 break :blk mod.toEnum(std.builtin.CallingConvention, cc_tv.val);
2281122816 } else if (sema.owner_decl.is_exported and has_body)
2281222817 .C
2281322818 else
......@@ -22994,9 +22999,9 @@ fn resolvePrefetchOptions(
2299422999 const cache_val = try sema.resolveConstValue(block, cache_src, cache, "prefetch cache must be comptime-known");
2299523000
2299623001 return std.builtin.PrefetchOptions{
22997 .rw = rw_val.toEnum(std.builtin.PrefetchOptions.Rw),
23002 .rw = mod.toEnum(std.builtin.PrefetchOptions.Rw, rw_val),
2299823003 .locality = @intCast(u2, locality_val.toUnsignedInt(mod)),
22999 .cache = cache_val.toEnum(std.builtin.PrefetchOptions.Cache),
23004 .cache = mod.toEnum(std.builtin.PrefetchOptions.Cache, cache_val),
2300023005 };
2300123006}
2300223007
......@@ -23059,7 +23064,7 @@ fn resolveExternOptions(
2305923064
2306023065 const linkage_ref = try sema.fieldVal(block, src, options, "linkage", linkage_src);
2306123066 const linkage_val = try sema.resolveConstValue(block, linkage_src, linkage_ref, "linkage of the extern symbol must be comptime-known");
23062 const linkage = linkage_val.toEnum(std.builtin.GlobalLinkage);
23067 const linkage = mod.toEnum(std.builtin.GlobalLinkage, linkage_val);
2306323068
2306423069 const is_thread_local = try sema.fieldVal(block, src, options, "is_thread_local", thread_local_src);
2306523070 const is_thread_local_val = try sema.resolveConstValue(block, thread_local_src, is_thread_local, "threadlocality of the extern symbol must be comptime-known");
......@@ -24140,7 +24145,7 @@ fn fieldVal(
2414024145 const field_index = @intCast(u32, field_index_usize);
2414124146 return sema.addConstant(
2414224147 enum_ty,
24143 try Value.Tag.enum_field_index.create(sema.arena, field_index),
24148 try mod.enumValueFieldIndex(enum_ty, field_index),
2414424149 );
2414524150 }
2414624151 }
......@@ -24155,8 +24160,8 @@ fn fieldVal(
2415524160 const field_index_usize = child_type.enumFieldIndex(field_name, mod) orelse
2415624161 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
2415724162 const field_index = @intCast(u32, field_index_usize);
24158 const enum_val = try Value.Tag.enum_field_index.create(arena, field_index);
24159 return sema.addConstant(try child_type.copy(arena), enum_val);
24163 const enum_val = try mod.enumValueFieldIndex(child_type, field_index);
24164 return sema.addConstant(child_type, enum_val);
2416024165 },
2416124166 .Struct, .Opaque => {
2416224167 if (child_type.getNamespaceIndex(mod).unwrap()) |namespace| {
......@@ -24355,8 +24360,8 @@ fn fieldPtr(
2435524360 var anon_decl = try block.startAnonDecl();
2435624361 defer anon_decl.deinit();
2435724362 return sema.analyzeDeclRef(try anon_decl.finish(
24358 try enum_ty.copy(anon_decl.arena()),
24359 try Value.Tag.enum_field_index.create(anon_decl.arena(), field_index_u32),
24363 enum_ty,
24364 try mod.enumValueFieldIndex(enum_ty, field_index_u32),
2436024365 0, // default alignment
2436124366 ));
2436224367 }
......@@ -24376,8 +24381,8 @@ fn fieldPtr(
2437624381 var anon_decl = try block.startAnonDecl();
2437724382 defer anon_decl.deinit();
2437824383 return sema.analyzeDeclRef(try anon_decl.finish(
24379 try child_type.copy(anon_decl.arena()),
24380 try Value.Tag.enum_field_index.create(anon_decl.arena(), field_index_u32),
24384 child_type,
24385 try mod.enumValueFieldIndex(child_type, field_index_u32),
2438124386 0, // default alignment
2438224387 ));
2438324388 },
......@@ -24850,7 +24855,7 @@ fn structFieldVal(
2485024855 }
2485124856
2485224857 if (try sema.resolveMaybeUndefVal(struct_byval)) |struct_val| {
24853 if (struct_val.isUndef()) return sema.addConstUndef(field.ty);
24858 if (struct_val.isUndef(mod)) return sema.addConstUndef(field.ty);
2485424859 if ((try sema.typeHasOnePossibleValue(field.ty))) |opv| {
2485524860 return sema.addConstant(field.ty, opv);
2485624861 }
......@@ -24922,7 +24927,7 @@ fn tupleFieldValByIndex(
2492224927 }
2492324928
2492424929 if (try sema.resolveMaybeUndefVal(tuple_byval)) |tuple_val| {
24925 if (tuple_val.isUndef()) return sema.addConstUndef(field_ty);
24930 if (tuple_val.isUndef(mod)) return sema.addConstUndef(field_ty);
2492624931 if ((try sema.typeHasOnePossibleValue(field_ty))) |opv| {
2492724932 return sema.addConstant(field_ty, opv);
2492824933 }
......@@ -24983,19 +24988,15 @@ fn unionFieldPtr(
2498324988 .Auto => if (!initializing) {
2498424989 const union_val = (try sema.pointerDeref(block, src, union_ptr_val, union_ptr_ty)) orelse
2498524990 break :ct;
24986 if (union_val.isUndef()) {
24991 if (union_val.isUndef(mod)) {
2498724992 return sema.failWithUseOfUndef(block, src);
2498824993 }
2498924994 const tag_and_val = union_val.castTag(.@"union").?.data;
24990 var field_tag_buf: Value.Payload.U32 = .{
24991 .base = .{ .tag = .enum_field_index },
24992 .data = enum_field_index,
24993 };
24994 const field_tag = Value.initPayload(&field_tag_buf.base);
24995 const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);
2499524996 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, mod);
2499624997 if (!tag_matches) {
2499724998 const msg = msg: {
24998 const active_index = tag_and_val.tag.castTag(.enum_field_index).?.data;
24999 const active_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, mod).?;
2499925000 const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod);
2500025001 const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });
2500125002 errdefer msg.destroy(sema.gpa);
......@@ -25021,7 +25022,7 @@ fn unionFieldPtr(
2502125022 if (!initializing and union_obj.layout == .Auto and block.wantSafety() and
2502225023 union_ty.unionTagTypeSafety(mod) != null and union_obj.fields.count() > 1)
2502325024 {
25024 const wanted_tag_val = try Value.Tag.enum_field_index.create(sema.arena, enum_field_index);
25025 const wanted_tag_val = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);
2502525026 const wanted_tag = try sema.addConstant(union_obj.tag_ty, wanted_tag_val);
2502625027 // TODO would it be better if get_union_tag supported pointers to unions?
2502725028 const union_val = try block.addTyOp(.load, union_ty, union_ptr);
......@@ -25054,14 +25055,10 @@ fn unionFieldVal(
2505425055 const enum_field_index = @intCast(u32, union_obj.tag_ty.enumFieldIndex(field_name, mod).?);
2505525056
2505625057 if (try sema.resolveMaybeUndefVal(union_byval)) |union_val| {
25057 if (union_val.isUndef()) return sema.addConstUndef(field.ty);
25058 if (union_val.isUndef(mod)) return sema.addConstUndef(field.ty);
2505825059
2505925060 const tag_and_val = union_val.castTag(.@"union").?.data;
25060 var field_tag_buf: Value.Payload.U32 = .{
25061 .base = .{ .tag = .enum_field_index },
25062 .data = enum_field_index,
25063 };
25064 const field_tag = Value.initPayload(&field_tag_buf.base);
25061 const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);
2506525062 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, mod);
2506625063 switch (union_obj.layout) {
2506725064 .Auto => {
......@@ -25069,7 +25066,7 @@ fn unionFieldVal(
2506925066 return sema.addConstant(field.ty, tag_and_val.val);
2507025067 } else {
2507125068 const msg = msg: {
25072 const active_index = tag_and_val.tag.castTag(.enum_field_index).?.data;
25069 const active_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, mod).?;
2507325070 const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod);
2507425071 const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });
2507525072 errdefer msg.destroy(sema.gpa);
......@@ -25096,7 +25093,7 @@ fn unionFieldVal(
2509625093 if (union_obj.layout == .Auto and block.wantSafety() and
2509725094 union_ty.unionTagTypeSafety(mod) != null and union_obj.fields.count() > 1)
2509825095 {
25099 const wanted_tag_val = try Value.Tag.enum_field_index.create(sema.arena, enum_field_index);
25096 const wanted_tag_val = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);
2510025097 const wanted_tag = try sema.addConstant(union_obj.tag_ty, wanted_tag_val);
2510125098 const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_byval);
2510225099 try sema.panicInactiveUnionField(block, active_tag, wanted_tag);
......@@ -25364,7 +25361,7 @@ fn tupleField(
2536425361 }
2536525362
2536625363 if (try sema.resolveMaybeUndefVal(tuple)) |tuple_val| {
25367 if (tuple_val.isUndef()) return sema.addConstUndef(field_ty);
25364 if (tuple_val.isUndef(mod)) return sema.addConstUndef(field_ty);
2536825365 return sema.addConstant(field_ty, try tuple_val.fieldValue(tuple_ty, mod, field_index));
2536925366 }
2537025367
......@@ -25412,7 +25409,7 @@ fn elemValArray(
2541225409 }
2541325410 }
2541425411 if (maybe_undef_array_val) |array_val| {
25415 if (array_val.isUndef()) {
25412 if (array_val.isUndef(mod)) {
2541625413 return sema.addConstUndef(elem_ty);
2541725414 }
2541825415 if (maybe_index_val) |index_val| {
......@@ -25473,7 +25470,7 @@ fn elemPtrArray(
2547325470 const elem_ptr_ty = try sema.elemPtrType(array_ptr_ty, offset);
2547425471
2547525472 if (maybe_undef_array_ptr_val) |array_ptr_val| {
25476 if (array_ptr_val.isUndef()) {
25473 if (array_ptr_val.isUndef(mod)) {
2547725474 return sema.addConstUndef(elem_ptr_ty);
2547825475 }
2547925476 if (offset) |index| {
......@@ -25580,7 +25577,7 @@ fn elemPtrSlice(
2558025577 const elem_ptr_ty = try sema.elemPtrType(slice_ty, offset);
2558125578
2558225579 if (maybe_undef_slice_val) |slice_val| {
25583 if (slice_val.isUndef()) {
25580 if (slice_val.isUndef(mod)) {
2558425581 return sema.addConstUndef(elem_ptr_ty);
2558525582 }
2558625583 const slice_len = slice_val.sliceLen(mod);
......@@ -25605,7 +25602,7 @@ fn elemPtrSlice(
2560525602 if (oob_safety and block.wantSafety()) {
2560625603 const len_inst = len: {
2560725604 if (maybe_undef_slice_val) |slice_val|
25608 if (!slice_val.isUndef())
25605 if (!slice_val.isUndef(mod))
2560925606 break :len try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(mod));
2561025607 break :len try block.addTyOp(.slice_len, Type.usize, slice);
2561125608 };
......@@ -25681,7 +25678,6 @@ fn coerceExtra(
2568125678 if (dest_ty.eql(inst_ty, mod))
2568225679 return inst;
2568325680
25684 const arena = sema.arena;
2568525681 const maybe_inst_val = try sema.resolveMaybeUndefVal(inst);
2568625682
2568725683 var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src);
......@@ -26175,7 +26171,7 @@ fn coerceExtra(
2617526171 };
2617626172 return sema.addConstant(
2617726173 dest_ty,
26178 try Value.Tag.enum_field_index.create(arena, @intCast(u32, field_index)),
26174 try mod.enumValueFieldIndex(dest_ty, @intCast(u32, field_index)),
2617926175 );
2618026176 },
2618126177 .Union => blk: {
......@@ -27858,8 +27854,9 @@ fn beginComptimePtrMutation(
2785827854 },
2785927855 .Union => {
2786027856 const payload = try arena.create(Value.Payload.Union);
27857 const tag_ty = parent.ty.unionTagTypeHypothetical(mod);
2786127858 payload.* = .{ .data = .{
27862 .tag = try Value.Tag.enum_field_index.create(arena, field_index),
27859 .tag = try mod.enumValueFieldIndex(tag_ty, field_index),
2786327860 .val = Value.undef,
2786427861 } };
2786527862
......@@ -27934,11 +27931,10 @@ fn beginComptimePtrMutation(
2793427931
2793527932 .@"union" => {
2793627933 // We need to set the active field of the union.
27937 const arena = parent.beginArena(sema.mod);
27938 defer parent.finishArena(sema.mod);
27934 const union_tag_ty = field_ptr.container_ty.unionTagTypeHypothetical(mod);
2793927935
2794027936 const payload = &val_ptr.castTag(.@"union").?.data;
27941 payload.tag = try Value.Tag.enum_field_index.create(arena, field_index);
27937 payload.tag = try mod.enumValueFieldIndex(union_tag_ty, field_index);
2794227938
2794327939 return beginComptimePtrMutationInner(
2794427940 sema,
......@@ -28575,7 +28571,7 @@ fn coerceCompatiblePtrs(
2857528571 const mod = sema.mod;
2857628572 const inst_ty = sema.typeOf(inst);
2857728573 if (try sema.resolveMaybeUndefVal(inst)) |val| {
28578 if (!val.isUndef() and val.isNull(mod) and !dest_ty.isAllowzeroPtr(mod)) {
28574 if (!val.isUndef(mod) and val.isNull(mod) and !dest_ty.isAllowzeroPtr(mod)) {
2857928575 return sema.fail(block, inst_src, "null pointer casted to type '{}'", .{dest_ty.fmt(sema.mod)});
2858028576 }
2858128577 // The comptime Value representation is compatible with both types.
......@@ -29426,7 +29422,7 @@ fn analyzeSlicePtr(
2942629422 const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer);
2942729423 const result_ty = slice_ty.slicePtrFieldType(buf, mod);
2942829424 if (try sema.resolveMaybeUndefVal(slice)) |val| {
29429 if (val.isUndef()) return sema.addConstUndef(result_ty);
29425 if (val.isUndef(mod)) return sema.addConstUndef(result_ty);
2943029426 return sema.addConstant(result_ty, val.slicePtr());
2943129427 }
2943229428 try sema.requireRuntimeBlock(block, slice_src, null);
......@@ -29439,8 +29435,9 @@ fn analyzeSliceLen(
2943929435 src: LazySrcLoc,
2944029436 slice_inst: Air.Inst.Ref,
2944129437) CompileError!Air.Inst.Ref {
29438 const mod = sema.mod;
2944229439 if (try sema.resolveMaybeUndefVal(slice_inst)) |slice_val| {
29443 if (slice_val.isUndef()) {
29440 if (slice_val.isUndef(mod)) {
2944429441 return sema.addConstUndef(Type.usize);
2944529442 }
2944629443 return sema.addIntUnsigned(Type.usize, slice_val.sliceLen(sema.mod));
......@@ -29459,7 +29456,7 @@ fn analyzeIsNull(
2945929456 const mod = sema.mod;
2946029457 const result_ty = Type.bool;
2946129458 if (try sema.resolveMaybeUndefVal(operand)) |opt_val| {
29462 if (opt_val.isUndef()) {
29459 if (opt_val.isUndef(mod)) {
2946329460 return sema.addConstUndef(result_ty);
2946429461 }
2946529462 const is_null = opt_val.isNull(mod);
......@@ -29588,7 +29585,7 @@ fn analyzeIsNonErrComptimeOnly(
2958829585 }
2958929586
2959029587 if (maybe_operand_val) |err_union| {
29591 if (err_union.isUndef()) {
29588 if (err_union.isUndef(mod)) {
2959229589 return sema.addConstUndef(Type.bool);
2959329590 }
2959429591 if (err_union.getError() == null) {
......@@ -29768,7 +29765,7 @@ fn analyzeSlice(
2976829765 } else try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
2976929766 if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| {
2977029767 if (try sema.resolveMaybeUndefVal(ptr_or_slice)) |slice_val| {
29771 if (slice_val.isUndef()) {
29768 if (slice_val.isUndef(mod)) {
2977229769 return sema.fail(block, src, "slice of undefined", .{});
2977329770 }
2977429771 const has_sentinel = slice_ty.sentinel(mod) != null;
......@@ -29948,7 +29945,7 @@ fn analyzeSlice(
2994829945 return result;
2994929946 };
2995029947
29951 if (!new_ptr_val.isUndef()) {
29948 if (!new_ptr_val.isUndef(mod)) {
2995229949 return sema.addConstant(return_ty, new_ptr_val);
2995329950 }
2995429951
......@@ -30069,19 +30066,19 @@ fn cmpNumeric(
3006930066 if (try sema.resolveMaybeUndefVal(lhs)) |lhs_val| {
3007030067 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {
3007130068 // Compare ints: const vs. undefined (or vice versa)
30072 if (!lhs_val.isUndef() and (lhs_ty.isInt(mod) or lhs_ty_tag == .ComptimeInt) and rhs_ty.isInt(mod) and rhs_val.isUndef()) {
30069 if (!lhs_val.isUndef(mod) and (lhs_ty.isInt(mod) or lhs_ty_tag == .ComptimeInt) and rhs_ty.isInt(mod) and rhs_val.isUndef(mod)) {
3007330070 try sema.resolveLazyValue(lhs_val);
3007430071 if (try sema.compareIntsOnlyPossibleResult(lhs_val, op, rhs_ty)) |res| {
3007530072 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;
3007630073 }
30077 } else if (!rhs_val.isUndef() and (rhs_ty.isInt(mod) or rhs_ty_tag == .ComptimeInt) and lhs_ty.isInt(mod) and lhs_val.isUndef()) {
30074 } else if (!rhs_val.isUndef(mod) and (rhs_ty.isInt(mod) or rhs_ty_tag == .ComptimeInt) and lhs_ty.isInt(mod) and lhs_val.isUndef(mod)) {
3007830075 try sema.resolveLazyValue(rhs_val);
3007930076 if (try sema.compareIntsOnlyPossibleResult(rhs_val, op.reverse(), lhs_ty)) |res| {
3008030077 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;
3008130078 }
3008230079 }
3008330080
30084 if (lhs_val.isUndef() or rhs_val.isUndef()) {
30081 if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) {
3008530082 return sema.addConstUndef(Type.bool);
3008630083 }
3008730084 if (lhs_val.isNan(mod) or rhs_val.isNan(mod)) {
......@@ -30097,7 +30094,7 @@ fn cmpNumeric(
3009730094 return Air.Inst.Ref.bool_false;
3009830095 }
3009930096 } else {
30100 if (!lhs_val.isUndef() and (lhs_ty.isInt(mod) or lhs_ty_tag == .ComptimeInt) and rhs_ty.isInt(mod)) {
30097 if (!lhs_val.isUndef(mod) and (lhs_ty.isInt(mod) or lhs_ty_tag == .ComptimeInt) and rhs_ty.isInt(mod)) {
3010130098 // Compare ints: const vs. var
3010230099 try sema.resolveLazyValue(lhs_val);
3010330100 if (try sema.compareIntsOnlyPossibleResult(lhs_val, op, rhs_ty)) |res| {
......@@ -30108,7 +30105,7 @@ fn cmpNumeric(
3010830105 }
3010930106 } else {
3011030107 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {
30111 if (!rhs_val.isUndef() and (rhs_ty.isInt(mod) or rhs_ty_tag == .ComptimeInt) and lhs_ty.isInt(mod)) {
30108 if (!rhs_val.isUndef(mod) and (rhs_ty.isInt(mod) or rhs_ty_tag == .ComptimeInt) and lhs_ty.isInt(mod)) {
3011230109 // Compare ints: var vs. const
3011330110 try sema.resolveLazyValue(rhs_val);
3011430111 if (try sema.compareIntsOnlyPossibleResult(rhs_val, op.reverse(), lhs_ty)) |res| {
......@@ -30177,7 +30174,7 @@ fn cmpNumeric(
3017730174 var lhs_bits: usize = undefined;
3017830175 if (try sema.resolveMaybeUndefVal(lhs)) |lhs_val| {
3017930176 try sema.resolveLazyValue(lhs_val);
30180 if (lhs_val.isUndef())
30177 if (lhs_val.isUndef(mod))
3018130178 return sema.addConstUndef(Type.bool);
3018230179 if (lhs_val.isNan(mod)) switch (op) {
3018330180 .neq => return Air.Inst.Ref.bool_true,
......@@ -30236,7 +30233,7 @@ fn cmpNumeric(
3023630233 var rhs_bits: usize = undefined;
3023730234 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {
3023830235 try sema.resolveLazyValue(rhs_val);
30239 if (rhs_val.isUndef())
30236 if (rhs_val.isUndef(mod))
3024030237 return sema.addConstUndef(Type.bool);
3024130238 if (rhs_val.isNan(mod)) switch (op) {
3024230239 .neq => return Air.Inst.Ref.bool_true,
......@@ -30441,7 +30438,7 @@ fn cmpVector(
3044130438 const runtime_src: LazySrcLoc = src: {
3044230439 if (try sema.resolveMaybeUndefVal(casted_lhs)) |lhs_val| {
3044330440 if (try sema.resolveMaybeUndefVal(casted_rhs)) |rhs_val| {
30444 if (lhs_val.isUndef() or rhs_val.isUndef()) {
30441 if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) {
3044530442 return sema.addConstUndef(result_ty);
3044630443 }
3044730444 const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_ty);
......@@ -30558,11 +30555,12 @@ fn unionToTag(
3055830555 un: Air.Inst.Ref,
3055930556 un_src: LazySrcLoc,
3056030557) !Air.Inst.Ref {
30558 const mod = sema.mod;
3056130559 if ((try sema.typeHasOnePossibleValue(enum_ty))) |opv| {
3056230560 return sema.addConstant(enum_ty, opv);
3056330561 }
3056430562 if (try sema.resolveMaybeUndefVal(un)) |un_val| {
30565 return sema.addConstant(enum_ty, un_val.unionTag());
30563 return sema.addConstant(enum_ty, un_val.unionTag(mod));
3056630564 }
3056730565 try sema.requireRuntimeBlock(block, un_src, null);
3056830566 return block.addTyOp(.get_union_tag, enum_ty, un);
......@@ -31718,6 +31716,7 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3171831716 .enum_type => |enum_type| try sema.resolveTypeRequiresComptime(enum_type.tag_ty.toType()),
3171931717
3172031718 // values, not types
31719 .undef => unreachable,
3172131720 .un => unreachable,
3172231721 .simple_value => unreachable,
3172331722 .extern_func => unreachable,
......@@ -31845,6 +31844,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
3184531844 .none => return ty,
3184631845
3184731846 .u1_type,
31847 .u5_type,
3184831848 .u8_type,
3184931849 .i8_type,
3185031850 .u16_type,
......@@ -31904,6 +31904,8 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
3190431904 .zero_u8 => unreachable,
3190531905 .one => unreachable,
3190631906 .one_usize => unreachable,
31907 .one_u5 => unreachable,
31908 .four_u5 => unreachable,
3190731909 .negative_one => unreachable,
3190831910 .calling_convention_c => unreachable,
3190931911 .calling_convention_inline => unreachable,
......@@ -32720,7 +32722,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3272032722 }
3272132723
3272232724 if (explicit_enum_info) |tag_info| {
32723 const enum_index = tag_info.nameIndex(mod.intern_pool, field_name_ip) orelse {
32725 const enum_index = tag_info.nameIndex(&mod.intern_pool, field_name_ip) orelse {
3272432726 const msg = msg: {
3272532727 const ty_src = mod.fieldSrcLoc(union_obj.owner_decl, .{
3272632728 .index = field_i,
......@@ -33186,19 +33188,30 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3318633188 .opaque_type => null,
3318733189 .enum_type => |enum_type| switch (enum_type.tag_mode) {
3318833190 .nonexhaustive => {
33189 if (enum_type.tag_ty != .comptime_int_type and
33190 !(try sema.typeHasRuntimeBits(enum_type.tag_ty.toType())))
33191 {
33192 return Value.enum_field_0;
33193 } else {
33194 return null;
33191 if (enum_type.tag_ty == .comptime_int_type) return null;
33192
33193 if (try sema.typeHasOnePossibleValue(enum_type.tag_ty.toType())) |int_opv| {
33194 const only = try mod.intern(.{ .enum_tag = .{
33195 .ty = ty.ip_index,
33196 .int = int_opv.ip_index,
33197 } });
33198 return only.toValue();
3319533199 }
33200
33201 return null;
3319633202 },
3319733203 .auto, .explicit => switch (enum_type.names.len) {
3319833204 0 => return Value.@"unreachable",
3319933205 1 => {
3320033206 if (enum_type.values.len == 0) {
33201 return Value.enum_field_0; // auto-numbered
33207 const only = try mod.intern(.{ .enum_tag = .{
33208 .ty = ty.ip_index,
33209 .int = try mod.intern(.{ .int = .{
33210 .ty = enum_type.tag_ty,
33211 .storage = .{ .u64 = 0 },
33212 } }),
33213 } });
33214 return only.toValue();
3320233215 } else {
3320333216 return enum_type.values[0].toValue();
3320433217 }
......@@ -33208,6 +33221,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3320833221 },
3320933222
3321033223 // values, not types
33224 .undef => unreachable,
3321133225 .un => unreachable,
3321233226 .simple_value => unreachable,
3321333227 .extern_func => unreachable,
......@@ -33397,8 +33411,9 @@ pub fn analyzeAddressSpace(
3339733411 zir_ref: Zir.Inst.Ref,
3339833412 ctx: AddressSpaceContext,
3339933413) !std.builtin.AddressSpace {
33414 const mod = sema.mod;
3340033415 const addrspace_tv = try sema.resolveInstConst(block, src, zir_ref, "addresspace must be comptime-known");
33401 const address_space = addrspace_tv.val.toEnum(std.builtin.AddressSpace);
33416 const address_space = mod.toEnum(std.builtin.AddressSpace, addrspace_tv.val);
3340233417 const target = sema.mod.getTarget();
3340333418 const arch = target.cpu.arch;
3340433419
......@@ -33766,6 +33781,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3376633781 .enum_type => |enum_type| try sema.typeRequiresComptime(enum_type.tag_ty.toType()),
3376733782
3376833783 // values, not types
33784 .undef => unreachable,
3376933785 .un => unreachable,
3377033786 .simple_value => unreachable,
3377133787 .extern_func => unreachable,
......@@ -33921,9 +33937,9 @@ fn numberAddWrapScalar(
3392133937 rhs: Value,
3392233938 ty: Type,
3392333939) !Value {
33924 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;
33925
3392633940 const mod = sema.mod;
33941 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.undef;
33942
3392733943 if (ty.zigTypeTag(mod) == .ComptimeInt) {
3392833944 return sema.intAdd(lhs, rhs, ty);
3392933945 }
......@@ -33975,9 +33991,9 @@ fn numberSubWrapScalar(
3397533991 rhs: Value,
3397633992 ty: Type,
3397733993) !Value {
33978 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;
33979
3398033994 const mod = sema.mod;
33995 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.undef;
33996
3398133997 if (ty.zigTypeTag(mod) == .ComptimeInt) {
3398233998 return sema.intSub(lhs, rhs, ty);
3398333999 }
......@@ -34222,17 +34238,12 @@ fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool {
3422234238 const mod = sema.mod;
3422334239 const enum_type = mod.intern_pool.indexToKey(ty.ip_index).enum_type;
3422434240 assert(enum_type.tag_mode != .nonexhaustive);
34225 if (enum_type.values.len == 0) {
34226 // auto-numbered
34227 return sema.intInRange(enum_type.tag_ty.toType(), int, enum_type.names.len);
34228 }
34229
3423034241 // The `tagValueIndex` function call below relies on the type being the integer tag type.
3423134242 // `getCoerced` assumes the value will fit the new type.
3423234243 if (!(try sema.intFitsInType(int, enum_type.tag_ty.toType(), null))) return false;
3423334244 const int_coerced = try mod.intern_pool.getCoerced(sema.gpa, int.ip_index, enum_type.tag_ty);
3423434245
34235 return enum_type.tagValueIndex(mod.intern_pool, int_coerced) != null;
34246 return enum_type.tagValueIndex(&mod.intern_pool, int_coerced) != null;
3423634247}
3423734248
3423834249fn intAddWithOverflow(
src/TypedValue.zig+16-5
......@@ -197,9 +197,6 @@ pub fn print(
197197 },
198198 .empty_array => return writer.writeAll(".{}"),
199199 .enum_literal => return writer.print(".{}", .{std.zig.fmtId(val.castTag(.enum_literal).?.data)}),
200 .enum_field_index => {
201 return writer.print(".{s}", .{ty.enumFieldName(val.castTag(.enum_field_index).?.data, mod)});
202 },
203200 .bytes => return writer.print("\"{}\"", .{std.zig.fmtEscapes(val.castTag(.bytes).?.data)}),
204201 .str_lit => {
205202 const str_lit = val.castTag(.str_lit).?.data;
......@@ -255,7 +252,7 @@ pub fn print(
255252 const elem_val = payload.ptr.elemValue(mod, i) catch |err| switch (err) {
256253 error.OutOfMemory => @panic("OOM"), // TODO: eliminate this panic
257254 };
258 if (elem_val.isUndef()) break :str;
255 if (elem_val.isUndef(mod)) break :str;
259256 buf[i] = std.math.cast(u8, elem_val.toUnsignedInt(mod)) orelse break :str;
260257 }
261258
......@@ -358,6 +355,20 @@ pub fn print(
358355 .int => |int| switch (int.storage) {
359356 inline .u64, .i64, .big_int => |x| return writer.print("{}", .{x}),
360357 },
358 .enum_tag => |enum_tag| {
359 try writer.writeAll("@intToEnum(");
360 try print(.{
361 .ty = Type.type,
362 .val = enum_tag.ty.toValue(),
363 }, writer, level - 1, mod);
364 try writer.writeAll(", ");
365 try print(.{
366 .ty = mod.intern_pool.typeOf(enum_tag.int).toType(),
367 .val = enum_tag.int.toValue(),
368 }, writer, level - 1, mod);
369 try writer.writeAll(")");
370 return;
371 },
361372 .float => |float| switch (float.storage) {
362373 inline else => |x| return writer.print("{}", .{x}),
363374 },
......@@ -414,7 +425,7 @@ fn printAggregate(
414425 var i: u32 = 0;
415426 while (i < max_len) : (i += 1) {
416427 const elem = try val.fieldValue(ty, mod, i);
417 if (elem.isUndef()) break :str;
428 if (elem.isUndef(mod)) break :str;
418429 buf[i] = std.math.cast(u8, elem.toUnsignedInt(mod)) orelse break :str;
419430 }
420431
src/Zir.zig+3
......@@ -2052,6 +2052,7 @@ pub const Inst = struct {
20522052 /// and `[]Ref`.
20532053 pub const Ref = enum(u32) {
20542054 u1_type = @enumToInt(InternPool.Index.u1_type),
2055 u5_type = @enumToInt(InternPool.Index.u5_type),
20552056 u8_type = @enumToInt(InternPool.Index.u8_type),
20562057 i8_type = @enumToInt(InternPool.Index.i8_type),
20572058 u16_type = @enumToInt(InternPool.Index.u16_type),
......@@ -2120,6 +2121,8 @@ pub const Inst = struct {
21202121 zero_u8 = @enumToInt(InternPool.Index.zero_u8),
21212122 one = @enumToInt(InternPool.Index.one),
21222123 one_usize = @enumToInt(InternPool.Index.one_usize),
2124 one_u5 = @enumToInt(InternPool.Index.one_u5),
2125 four_u5 = @enumToInt(InternPool.Index.four_u5),
21232126 negative_one = @enumToInt(InternPool.Index.negative_one),
21242127 calling_convention_c = @enumToInt(InternPool.Index.calling_convention_c),
21252128 calling_convention_inline = @enumToInt(InternPool.Index.calling_convention_inline),
src/arch/wasm/CodeGen.zig+39-48
......@@ -11,6 +11,7 @@ const log = std.log.scoped(.codegen);
1111
1212const codegen = @import("../../codegen.zig");
1313const Module = @import("../../Module.zig");
14const InternPool = @import("../../InternPool.zig");
1415const Decl = Module.Decl;
1516const Type = @import("../../type.zig").Type;
1617const Value = @import("../../value.zig").Value;
......@@ -3044,11 +3045,12 @@ fn toTwosComplement(value: anytype, bits: u7) std.meta.Int(.unsigned, @typeInfo(
30443045}
30453046
30463047fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3048 const mod = func.bin_file.base.options.module.?;
30473049 var val = arg_val;
30483050 if (val.castTag(.runtime_value)) |rt| {
30493051 val = rt.data;
30503052 }
3051 if (val.isUndefDeep()) return func.emitUndefined(ty);
3053 if (val.isUndefDeep(mod)) return func.emitUndefined(ty);
30523054 if (val.castTag(.decl_ref)) |decl_ref| {
30533055 const decl_index = decl_ref.data;
30543056 return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl_index, 0);
......@@ -3057,7 +3059,6 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
30573059 const decl_index = decl_ref_mut.data.decl_index;
30583060 return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl_index, 0);
30593061 }
3060 const mod = func.bin_file.base.options.module.?;
30613062 switch (ty.zigTypeTag(mod)) {
30623063 .Void => return WValue{ .none = {} },
30633064 .Int => {
......@@ -3100,18 +3101,9 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
31003101 },
31013102 },
31023103 .Enum => {
3103 if (val.castTag(.enum_field_index)) |field_index| {
3104 const enum_type = mod.intern_pool.indexToKey(ty.ip_index).enum_type;
3105 if (enum_type.values.len != 0) {
3106 const tag_val = enum_type.values[field_index.data];
3107 return func.lowerConstant(tag_val.toValue(), enum_type.tag_ty.toType());
3108 } else {
3109 return WValue{ .imm32 = field_index.data };
3110 }
3111 } else {
3112 const int_tag_ty = try ty.intTagType(mod);
3113 return func.lowerConstant(val, int_tag_ty);
3114 }
3104 const enum_tag = mod.intern_pool.indexToKey(val.ip_index).enum_tag;
3105 const int_tag_ty = mod.intern_pool.typeOf(enum_tag.int);
3106 return func.lowerConstant(enum_tag.int.toValue(), int_tag_ty.toType());
31153107 },
31163108 .ErrorSet => switch (val.tag()) {
31173109 .@"error" => {
......@@ -3223,37 +3215,42 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
32233215/// Returns a `Value` as a signed 32 bit value.
32243216/// It's illegal to provide a value with a type that cannot be represented
32253217/// as an integer value.
3226fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) !i32 {
3218fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {
32273219 const mod = func.bin_file.base.options.module.?;
3228 switch (ty.zigTypeTag(mod)) {
3229 .Enum => {
3230 if (val.castTag(.enum_field_index)) |field_index| {
3231 const enum_type = mod.intern_pool.indexToKey(ty.ip_index).enum_type;
3232 if (enum_type.values.len != 0) {
3233 const tag_val = enum_type.values[field_index.data];
3234 return func.valueAsI32(tag_val.toValue(), enum_type.tag_ty.toType());
3235 } else {
3236 return @bitCast(i32, field_index.data);
3237 }
3238 } else {
3239 const int_tag_ty = try ty.intTagType(mod);
3240 return func.valueAsI32(val, int_tag_ty);
3241 }
3242 },
3243 .Int => switch (ty.intInfo(mod).signedness) {
3244 .signed => return @truncate(i32, val.toSignedInt(mod)),
3245 .unsigned => return @bitCast(i32, @truncate(u32, val.toUnsignedInt(mod))),
3220
3221 switch (val.ip_index) {
3222 .none => {},
3223 .bool_true => return 1,
3224 .bool_false => return 0,
3225 else => return switch (mod.intern_pool.indexToKey(val.ip_index)) {
3226 .enum_tag => |enum_tag| intIndexAsI32(&mod.intern_pool, enum_tag.int),
3227 .int => |int| intStorageAsI32(int.storage),
3228 .ptr => |ptr| intIndexAsI32(&mod.intern_pool, ptr.addr.int),
3229 else => unreachable,
32463230 },
3231 }
3232
3233 switch (ty.zigTypeTag(mod)) {
32473234 .ErrorSet => {
32483235 const kv = func.bin_file.base.options.module.?.getErrorValue(val.getError().?) catch unreachable; // passed invalid `Value` to function
32493236 return @bitCast(i32, kv.value);
32503237 },
3251 .Bool => return @intCast(i32, val.toSignedInt(mod)),
3252 .Pointer => return @intCast(i32, val.toSignedInt(mod)),
32533238 else => unreachable, // Programmer called this function for an illegal type
32543239 }
32553240}
32563241
3242fn intIndexAsI32(ip: *const InternPool, int: InternPool.Index) i32 {
3243 return intStorageAsI32(ip.indexToKey(int).int.storage);
3244}
3245
3246fn intStorageAsI32(storage: InternPool.Key.Int.Storage) i32 {
3247 return switch (storage) {
3248 .i64 => |x| @intCast(i32, x),
3249 .u64 => |x| @bitCast(i32, @intCast(u32, x)),
3250 .big_int => unreachable,
3251 };
3252}
3253
32573254fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
32583255 const mod = func.bin_file.base.options.module.?;
32593256 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
......@@ -3772,7 +3769,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37723769
37733770 for (items, 0..) |ref, i| {
37743771 const item_val = (try func.air.value(ref, mod)).?;
3775 const int_val = try func.valueAsI32(item_val, target_ty);
3772 const int_val = func.valueAsI32(item_val, target_ty);
37763773 if (lowest_maybe == null or int_val < lowest_maybe.?) {
37773774 lowest_maybe = int_val;
37783775 }
......@@ -5071,12 +5068,8 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
50715068
50725069 const tag_int = blk: {
50735070 const tag_ty = union_ty.unionTagTypeHypothetical(mod);
5074 const enum_field_index = tag_ty.enumFieldIndex(field_name).?;
5075 var tag_val_payload: Value.Payload.U32 = .{
5076 .base = .{ .tag = .enum_field_index },
5077 .data = @intCast(u32, enum_field_index),
5078 };
5079 const tag_val = Value.initPayload(&tag_val_payload.base);
5071 const enum_field_index = tag_ty.enumFieldIndex(field_name, mod).?;
5072 const tag_val = try mod.enumValueFieldIndex(tag_ty, enum_field_index);
50805073 break :blk try func.lowerConstant(tag_val, tag_ty);
50815074 };
50825075 if (layout.payload_size == 0) {
......@@ -6815,7 +6808,8 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
68156808
68166809 // TODO: Make switch implementation generic so we can use a jump table for this when the tags are not sparse.
68176810 // generate an if-else chain for each tag value as well as constant.
6818 for (enum_ty.enumFields(mod), 0..) |tag_name_ip, field_index| {
6811 for (enum_ty.enumFields(mod), 0..) |tag_name_ip, field_index_usize| {
6812 const field_index = @intCast(u32, field_index_usize);
68196813 const tag_name = mod.intern_pool.stringToSlice(tag_name_ip);
68206814 // for each tag name, create an unnamed const,
68216815 // and then get a pointer to its value.
......@@ -6857,11 +6851,8 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
68576851 try writer.writeByte(std.wasm.opcode(.local_get));
68586852 try leb.writeULEB128(writer, @as(u32, 1));
68596853
6860 var tag_val_payload: Value.Payload.U32 = .{
6861 .base = .{ .tag = .enum_field_index },
6862 .data = @intCast(u32, field_index),
6863 };
6864 const tag_value = try func.lowerConstant(Value.initPayload(&tag_val_payload.base), enum_ty);
6854 const tag_val = try mod.enumValueFieldIndex(enum_ty, field_index);
6855 const tag_value = try func.lowerConstant(tag_val, enum_ty);
68656856
68666857 switch (tag_value) {
68676858 .imm32 => |value| {
src/arch/x86_64/CodeGen.zig+4-8
......@@ -2029,13 +2029,10 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
20292029 exitlude_jump_relocs,
20302030 enum_ty.enumFields(mod),
20312031 0..,
2032 ) |*exitlude_jump_reloc, tag_name_ip, index| {
2032 ) |*exitlude_jump_reloc, tag_name_ip, index_usize| {
2033 const index = @intCast(u32, index_usize);
20332034 const tag_name = mod.intern_pool.stringToSlice(tag_name_ip);
2034 var tag_pl = Value.Payload.U32{
2035 .base = .{ .tag = .enum_field_index },
2036 .data = @intCast(u32, index),
2037 };
2038 const tag_val = Value.initPayload(&tag_pl.base);
2035 const tag_val = try mod.enumValueFieldIndex(enum_ty, index);
20392036 const tag_mcv = try self.genTypedValue(.{ .ty = enum_ty, .val = tag_val });
20402037 try self.genBinOpMir(.{ ._, .cmp }, enum_ty, enum_mcv, tag_mcv);
20412038 const skip_reloc = try self.asmJccReloc(undefined, .ne);
......@@ -11415,8 +11412,7 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
1141511412 const field_name = union_obj.fields.keys()[extra.field_index];
1141611413 const tag_ty = union_obj.tag_ty;
1141711414 const field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name, mod).?);
11418 var tag_pl = Value.Payload.U32{ .base = .{ .tag = .enum_field_index }, .data = field_index };
11419 const tag_val = Value.initPayload(&tag_pl.base);
11415 const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index);
1142011416 const tag_int_val = try tag_val.enumToInt(tag_ty, mod);
1142111417 const tag_int = tag_int_val.toUnsignedInt(mod);
1142211418 const tag_off = if (layout.tag_align < layout.payload_align)
src/codegen.zig+8-20
......@@ -196,7 +196,7 @@ pub fn generateSymbol(
196196 typed_value.val.fmtValue(typed_value.ty, mod),
197197 });
198198
199 if (typed_value.val.isUndefDeep()) {
199 if (typed_value.val.isUndefDeep(mod)) {
200200 const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow;
201201 try code.appendNTimes(0xaa, abi_size);
202202 return Result.ok;
......@@ -1168,7 +1168,7 @@ pub fn genTypedValue(
11681168 typed_value.val.fmtValue(typed_value.ty, mod),
11691169 });
11701170
1171 if (typed_value.val.isUndef())
1171 if (typed_value.val.isUndef(mod))
11721172 return GenResult.mcv(.undef);
11731173
11741174 const target = bin_file.options.target;
......@@ -1229,24 +1229,12 @@ pub fn genTypedValue(
12291229 }
12301230 },
12311231 .Enum => {
1232 if (typed_value.val.castTag(.enum_field_index)) |field_index| {
1233 const enum_type = mod.intern_pool.indexToKey(typed_value.ty.ip_index).enum_type;
1234 if (enum_type.values.len != 0) {
1235 const tag_val = enum_type.values[field_index.data];
1236 return genTypedValue(bin_file, src_loc, .{
1237 .ty = enum_type.tag_ty.toType(),
1238 .val = tag_val.toValue(),
1239 }, owner_decl_index);
1240 } else {
1241 return GenResult.mcv(.{ .immediate = field_index.data });
1242 }
1243 } else {
1244 const int_tag_ty = try typed_value.ty.intTagType(mod);
1245 return genTypedValue(bin_file, src_loc, .{
1246 .ty = int_tag_ty,
1247 .val = typed_value.val,
1248 }, owner_decl_index);
1249 }
1232 const enum_tag = mod.intern_pool.indexToKey(typed_value.val.ip_index).enum_tag;
1233 const int_tag_ty = mod.intern_pool.typeOf(enum_tag.int);
1234 return genTypedValue(bin_file, src_loc, .{
1235 .ty = int_tag_ty.toType(),
1236 .val = enum_tag.int.toValue(),
1237 }, owner_decl_index);
12501238 },
12511239 .ErrorSet => {
12521240 switch (typed_value.val.tag()) {
src/codegen/c.zig+21-35
......@@ -748,7 +748,7 @@ pub const DeclGen = struct {
748748 .ReleaseFast, .ReleaseSmall => false,
749749 };
750750
751 if (val.isUndefDeep()) {
751 if (val.isUndefDeep(mod)) {
752752 switch (ty.zigTypeTag(mod)) {
753753 .Bool => {
754754 if (safety_on) {
......@@ -1183,7 +1183,7 @@ pub const DeclGen = struct {
11831183 var index: usize = 0;
11841184 while (index < ai.len) : (index += 1) {
11851185 const elem_val = try val.elemValue(mod, index);
1186 const elem_val_u8 = if (elem_val.isUndef()) undefPattern(u8) else @intCast(u8, elem_val.toUnsignedInt(mod));
1186 const elem_val_u8 = if (elem_val.isUndef(mod)) undefPattern(u8) else @intCast(u8, elem_val.toUnsignedInt(mod));
11871187 try literal.writeChar(elem_val_u8);
11881188 }
11891189 if (ai.sentinel) |s| {
......@@ -1197,7 +1197,7 @@ pub const DeclGen = struct {
11971197 while (index < ai.len) : (index += 1) {
11981198 if (index != 0) try writer.writeByte(',');
11991199 const elem_val = try val.elemValue(mod, index);
1200 const elem_val_u8 = if (elem_val.isUndef()) undefPattern(u8) else @intCast(u8, elem_val.toUnsignedInt(mod));
1200 const elem_val_u8 = if (elem_val.isUndef(mod)) undefPattern(u8) else @intCast(u8, elem_val.toUnsignedInt(mod));
12011201 try writer.print("'\\x{x}'", .{elem_val_u8});
12021202 }
12031203 if (ai.sentinel) |s| {
......@@ -1284,23 +1284,16 @@ pub const DeclGen = struct {
12841284 try dg.renderValue(writer, error_ty, error_val, initializer_type);
12851285 try writer.writeAll(" }");
12861286 },
1287 .Enum => {
1288 switch (val.tag()) {
1289 .enum_field_index => {
1290 const field_index = val.castTag(.enum_field_index).?.data;
1291 const enum_type = mod.intern_pool.indexToKey(ty.ip_index).enum_type;
1292 if (enum_type.values.len != 0) {
1293 const tag_val = enum_type.values[field_index];
1294 return dg.renderValue(writer, enum_type.tag_ty.toType(), tag_val.toValue(), location);
1295 } else {
1296 return writer.print("{d}", .{field_index});
1297 }
1298 },
1299 else => {
1300 const int_tag_ty = try ty.intTagType(mod);
1301 return dg.renderValue(writer, int_tag_ty, val, location);
1302 },
1303 }
1287 .Enum => switch (val.ip_index) {
1288 .none => {
1289 const int_tag_ty = try ty.intTagType(mod);
1290 return dg.renderValue(writer, int_tag_ty, val, location);
1291 },
1292 else => {
1293 const enum_tag = mod.intern_pool.indexToKey(val.ip_index).enum_tag;
1294 const int_tag_ty = mod.intern_pool.typeOf(enum_tag.int);
1295 return dg.renderValue(writer, int_tag_ty.toType(), enum_tag.int.toValue(), location);
1296 },
13041297 },
13051298 .Fn => switch (val.tag()) {
13061299 .function => {
......@@ -2524,13 +2517,10 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
25242517 try w.writeByte('(');
25252518 try o.dg.renderTypeAndName(w, enum_ty, .{ .identifier = "tag" }, Const, 0, .complete);
25262519 try w.writeAll(") {\n switch (tag) {\n");
2527 for (enum_ty.enumFields(mod), 0..) |name_ip, index| {
2520 for (enum_ty.enumFields(mod), 0..) |name_ip, index_usize| {
2521 const index = @intCast(u32, index_usize);
25282522 const name = mod.intern_pool.stringToSlice(name_ip);
2529 var tag_pl: Value.Payload.U32 = .{
2530 .base = .{ .tag = .enum_field_index },
2531 .data = @intCast(u32, index),
2532 };
2533 const tag_val = Value.initPayload(&tag_pl.base);
2523 const tag_val = try mod.enumValueFieldIndex(enum_ty, index);
25342524
25352525 const int_val = try tag_val.enumToInt(enum_ty, mod);
25362526
......@@ -3609,7 +3599,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
36093599 const ptr_val = try f.resolveInst(bin_op.lhs);
36103600 const src_ty = f.typeOf(bin_op.rhs);
36113601
3612 const val_is_undef = if (try f.air.value(bin_op.rhs, mod)) |v| v.isUndefDeep() else false;
3602 const val_is_undef = if (try f.air.value(bin_op.rhs, mod)) |v| v.isUndefDeep(mod) else false;
36133603
36143604 if (val_is_undef) {
36153605 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
......@@ -4267,7 +4257,7 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
42674257 const mod = f.object.dg.module;
42684258 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
42694259 const name = f.air.nullTerminatedString(pl_op.payload);
4270 const operand_is_undef = if (try f.air.value(pl_op.operand, mod)) |v| v.isUndefDeep() else false;
4260 const operand_is_undef = if (try f.air.value(pl_op.operand, mod)) |v| v.isUndefDeep(mod) else false;
42714261 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);
42724262
42734263 try reap(f, inst, &.{pl_op.operand});
......@@ -6290,7 +6280,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
62906280 const value = try f.resolveInst(bin_op.rhs);
62916281 const elem_ty = f.typeOf(bin_op.rhs);
62926282 const elem_abi_size = elem_ty.abiSize(mod);
6293 const val_is_undef = if (try f.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false;
6283 const val_is_undef = if (try f.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep(mod) else false;
62946284 const writer = f.object.writer();
62956285
62966286 if (val_is_undef) {
......@@ -6907,11 +6897,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
69076897 if (layout.tag_size != 0) {
69086898 const field_index = tag_ty.enumFieldIndex(field_name, mod).?;
69096899
6910 var tag_pl: Value.Payload.U32 = .{
6911 .base = .{ .tag = .enum_field_index },
6912 .data = @intCast(u32, field_index),
6913 };
6914 const tag_val = Value.initPayload(&tag_pl.base);
6900 const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index);
69156901
69166902 const int_val = try tag_val.enumToInt(tag_ty, mod);
69176903
......@@ -7438,7 +7424,7 @@ fn formatIntLiteral(
74387424 defer allocator.free(undef_limbs);
74397425
74407426 var int_buf: Value.BigIntSpace = undefined;
7441 const int = if (data.val.isUndefDeep()) blk: {
7427 const int = if (data.val.isUndefDeep(mod)) blk: {
74427428 undef_limbs = try allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(data.int_info.bits));
74437429 @memset(undef_limbs, undefPattern(BigIntLimb));
74447430
src/codegen/llvm.zig+16-28
......@@ -3233,16 +3233,16 @@ pub const DeclGen = struct {
32333233 }
32343234
32353235 fn lowerValue(dg: *DeclGen, arg_tv: TypedValue) Error!*llvm.Value {
3236 const mod = dg.module;
3237 const target = mod.getTarget();
32363238 var tv = arg_tv;
32373239 if (tv.val.castTag(.runtime_value)) |rt| {
32383240 tv.val = rt.data;
32393241 }
3240 if (tv.val.isUndef()) {
3242 if (tv.val.isUndef(mod)) {
32413243 const llvm_type = try dg.lowerType(tv.ty);
32423244 return llvm_type.getUndef();
32433245 }
3244 const mod = dg.module;
3245 const target = mod.getTarget();
32463246 switch (tv.ty.zigTypeTag(mod)) {
32473247 .Bool => {
32483248 const llvm_type = try dg.lowerType(tv.ty);
......@@ -8204,7 +8204,7 @@ pub const FuncGen = struct {
82048204 const ptr_ty = self.typeOf(bin_op.lhs);
82058205 const operand_ty = ptr_ty.childType(mod);
82068206
8207 const val_is_undef = if (try self.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false;
8207 const val_is_undef = if (try self.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep(mod) else false;
82088208 if (val_is_undef) {
82098209 // Even if safety is disabled, we still emit a memset to undefined since it conveys
82108210 // extra information to LLVM. However, safety makes the difference between using
......@@ -8496,7 +8496,7 @@ pub const FuncGen = struct {
84968496 const is_volatile = ptr_ty.isVolatilePtr(mod);
84978497
84988498 if (try self.air.value(bin_op.rhs, mod)) |elem_val| {
8499 if (elem_val.isUndefDeep()) {
8499 if (elem_val.isUndefDeep(mod)) {
85008500 // Even if safety is disabled, we still emit a memset to undefined since it conveys
85018501 // extra information to LLVM. However, safety makes the difference between using
85028502 // 0xaa or actual undefined for the fill byte.
......@@ -8890,15 +8890,12 @@ pub const FuncGen = struct {
88908890 const tag_int_value = fn_val.getParam(0);
88918891 const switch_instr = self.builder.buildSwitch(tag_int_value, unnamed_block, @intCast(c_uint, enum_type.names.len));
88928892
8893 for (enum_type.names, 0..) |_, field_index| {
8893 for (enum_type.names, 0..) |_, field_index_usize| {
8894 const field_index = @intCast(u32, field_index_usize);
88948895 const this_tag_int_value = int: {
8895 var tag_val_payload: Value.Payload.U32 = .{
8896 .base = .{ .tag = .enum_field_index },
8897 .data = @intCast(u32, field_index),
8898 };
88998896 break :int try self.dg.lowerValue(.{
89008897 .ty = enum_ty,
8901 .val = Value.initPayload(&tag_val_payload.base),
8898 .val = try mod.enumValueFieldIndex(enum_ty, field_index),
89028899 });
89038900 };
89048901 switch_instr.addCase(this_tag_int_value, named_block);
......@@ -8973,7 +8970,8 @@ pub const FuncGen = struct {
89738970 usize_llvm_ty.constNull(), usize_llvm_ty.constNull(),
89748971 };
89758972
8976 for (enum_type.names, 0..) |name_ip, field_index| {
8973 for (enum_type.names, 0..) |name_ip, field_index_usize| {
8974 const field_index = @intCast(u32, field_index_usize);
89778975 const name = mod.intern_pool.stringToSlice(name_ip);
89788976 const str_init = self.context.constString(name.ptr, @intCast(c_uint, name.len), .False);
89798977 const str_init_llvm_ty = str_init.typeOf();
......@@ -8997,16 +8995,10 @@ pub const FuncGen = struct {
89978995 slice_global.setAlignment(slice_alignment);
89988996
89998997 const return_block = self.context.appendBasicBlock(fn_val, "Name");
9000 const this_tag_int_value = int: {
9001 var tag_val_payload: Value.Payload.U32 = .{
9002 .base = .{ .tag = .enum_field_index },
9003 .data = @intCast(u32, field_index),
9004 };
9005 break :int try self.dg.lowerValue(.{
9006 .ty = enum_ty,
9007 .val = Value.initPayload(&tag_val_payload.base),
9008 });
9009 };
8998 const this_tag_int_value = try self.dg.lowerValue(.{
8999 .ty = enum_ty,
9000 .val = try mod.enumValueFieldIndex(enum_ty, field_index),
9001 });
90109002 switch_instr.addCase(this_tag_int_value, return_block);
90119003
90129004 self.builder.positionBuilderAtEnd(return_block);
......@@ -9094,7 +9086,7 @@ pub const FuncGen = struct {
90949086
90959087 for (values, 0..) |*val, i| {
90969088 const elem = try mask.elemValue(mod, i);
9097 if (elem.isUndef()) {
9089 if (elem.isUndef(mod)) {
90989090 val.* = llvm_i32.getUndef();
90999091 } else {
91009092 const int = elem.toSignedInt(mod);
......@@ -9419,11 +9411,7 @@ pub const FuncGen = struct {
94199411 const tag_ty = union_ty.unionTagTypeHypothetical(mod);
94209412 const union_field_name = union_obj.fields.keys()[extra.field_index];
94219413 const enum_field_index = tag_ty.enumFieldIndex(union_field_name, mod).?;
9422 var tag_val_payload: Value.Payload.U32 = .{
9423 .base = .{ .tag = .enum_field_index },
9424 .data = @intCast(u32, enum_field_index),
9425 };
9426 const tag_val = Value.initPayload(&tag_val_payload.base);
9414 const tag_val = try mod.enumValueFieldIndex(tag_ty, enum_field_index);
94279415 const tag_int_val = try tag_val.enumToInt(tag_ty, mod);
94289416 break :blk tag_int_val.toUnsignedInt(mod);
94299417 };
src/codegen/spirv.zig+4-4
......@@ -614,7 +614,7 @@ pub const DeclGen = struct {
614614 const dg = self.dg;
615615 const mod = dg.module;
616616
617 if (val.isUndef()) {
617 if (val.isUndef(mod)) {
618618 const size = ty.abiSize(mod);
619619 return try self.addUndef(size);
620620 }
......@@ -882,7 +882,7 @@ pub const DeclGen = struct {
882882 // const target = self.getTarget();
883883
884884 // TODO: Fix the resulting global linking for these paths.
885 // if (val.isUndef()) {
885 // if (val.isUndef(mod)) {
886886 // // Special case: the entire value is undefined. In this case, we can just
887887 // // generate an OpVariable with no initializer.
888888 // return try section.emit(self.spv.gpa, .OpVariable, .{
......@@ -978,7 +978,7 @@ pub const DeclGen = struct {
978978
979979 log.debug("constant: ty = {}, val = {}", .{ ty.fmt(self.module), val.fmtValue(ty, self.module) });
980980
981 if (val.isUndef()) {
981 if (val.isUndef(mod)) {
982982 return self.spv.constUndef(result_ty_ref);
983983 }
984984
......@@ -2091,7 +2091,7 @@ pub const DeclGen = struct {
20912091 var i: usize = 0;
20922092 while (i < mask_len) : (i += 1) {
20932093 const elem = try mask.elemValue(self.module, i);
2094 if (elem.isUndef()) {
2094 if (elem.isUndef(mod)) {
20952095 self.func.body.writeOperand(spec.LiteralInteger, 0xFFFF_FFFF);
20962096 } else {
20972097 const int = elem.toSignedInt(mod);
src/link/Coff.zig+1-1
......@@ -1304,7 +1304,7 @@ fn getDeclOutputSection(self: *Coff, decl_index: Module.Decl.Index) u16 {
13041304 const zig_ty = ty.zigTypeTag(mod);
13051305 const val = decl.val;
13061306 const index: u16 = blk: {
1307 if (val.isUndefDeep()) {
1307 if (val.isUndefDeep(mod)) {
13081308 // TODO in release-fast and release-small, we should put undef in .bss
13091309 break :blk self.data_section_index.?;
13101310 }
src/link/Elf.zig+1-1
......@@ -2456,7 +2456,7 @@ fn getDeclShdrIndex(self: *Elf, decl_index: Module.Decl.Index) u16 {
24562456 const zig_ty = ty.zigTypeTag(mod);
24572457 const val = decl.val;
24582458 const shdr_index: u16 = blk: {
2459 if (val.isUndefDeep()) {
2459 if (val.isUndefDeep(mod)) {
24602460 // TODO in release-fast and release-small, we should put undef in .bss
24612461 break :blk self.data_section_index.?;
24622462 }
src/link/MachO.zig+1-1
......@@ -2270,7 +2270,7 @@ fn getDeclOutputSection(self: *MachO, decl_index: Module.Decl.Index) u8 {
22702270 const single_threaded = self.base.options.single_threaded;
22712271 const sect_id: u8 = blk: {
22722272 // TODO finish and audit this function
2273 if (val.isUndefDeep()) {
2273 if (val.isUndefDeep(mod)) {
22742274 if (mode == .ReleaseFast or mode == .ReleaseSmall) {
22752275 @panic("TODO __DATA,__bss");
22762276 } else {
src/link/Wasm.zig+1-1
......@@ -3374,7 +3374,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
33743374 } else if (decl.getVariable()) |variable| {
33753375 if (!variable.is_mutable) {
33763376 try wasm.parseAtom(atom_index, .{ .data = .read_only });
3377 } else if (variable.init.isUndefDeep()) {
3377 } else if (variable.init.isUndefDeep(mod)) {
33783378 // for safe build modes, we store the atom in the data segment,
33793379 // whereas for unsafe build modes we store it in bss.
33803380 const is_initialized = wasm.base.options.optimize_mode == .Debug or
src/type.zig+33-26
......@@ -126,6 +126,7 @@ pub const Type = struct {
126126 },
127127
128128 // values, not types
129 .undef => unreachable,
129130 .un => unreachable,
130131 .extern_func => unreachable,
131132 .int => unreachable,
......@@ -1350,6 +1351,7 @@ pub const Type = struct {
13501351 },
13511352
13521353 // values, not types
1354 .undef => unreachable,
13531355 .un => unreachable,
13541356 .simple_value => unreachable,
13551357 .extern_func => unreachable,
......@@ -1600,6 +1602,7 @@ pub const Type = struct {
16001602 .enum_type => |enum_type| enum_type.tag_ty.toType().hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat),
16011603
16021604 // values, not types
1605 .undef => unreachable,
16031606 .un => unreachable,
16041607 .simple_value => unreachable,
16051608 .extern_func => unreachable,
......@@ -1713,6 +1716,7 @@ pub const Type = struct {
17131716 },
17141717
17151718 // values, not types
1719 .undef => unreachable,
17161720 .un => unreachable,
17171721 .simple_value => unreachable,
17181722 .extern_func => unreachable,
......@@ -2104,6 +2108,7 @@ pub const Type = struct {
21042108 .enum_type => |enum_type| return AbiAlignmentAdvanced{ .scalar = enum_type.tag_ty.toType().abiAlignment(mod) },
21052109
21062110 // values, not types
2111 .undef => unreachable,
21072112 .un => unreachable,
21082113 .simple_value => unreachable,
21092114 .extern_func => unreachable,
......@@ -2499,6 +2504,7 @@ pub const Type = struct {
24992504 .enum_type => |enum_type| return AbiSizeAdvanced{ .scalar = enum_type.tag_ty.toType().abiSize(mod) },
25002505
25012506 // values, not types
2507 .undef => unreachable,
25022508 .un => unreachable,
25032509 .simple_value => unreachable,
25042510 .extern_func => unreachable,
......@@ -2736,6 +2742,7 @@ pub const Type = struct {
27362742 .enum_type => |enum_type| return bitSizeAdvanced(enum_type.tag_ty.toType(), mod, opt_sema),
27372743
27382744 // values, not types
2745 .undef => unreachable,
27392746 .un => unreachable,
27402747 .simple_value => unreachable,
27412748 .extern_func => unreachable,
......@@ -3492,6 +3499,7 @@ pub const Type = struct {
34923499 .opaque_type => unreachable,
34933500
34943501 // values, not types
3502 .undef => unreachable,
34953503 .un => unreachable,
34963504 .simple_value => unreachable,
34973505 .extern_func => unreachable,
......@@ -3826,19 +3834,30 @@ pub const Type = struct {
38263834 .opaque_type => return null,
38273835 .enum_type => |enum_type| switch (enum_type.tag_mode) {
38283836 .nonexhaustive => {
3829 if (enum_type.tag_ty != .comptime_int_type and
3830 !enum_type.tag_ty.toType().hasRuntimeBits(mod))
3831 {
3832 return Value.enum_field_0;
3833 } else {
3834 return null;
3837 if (enum_type.tag_ty == .comptime_int_type) return null;
3838
3839 if (try enum_type.tag_ty.toType().onePossibleValue(mod)) |int_opv| {
3840 const only = try mod.intern(.{ .enum_tag = .{
3841 .ty = ty.ip_index,
3842 .int = int_opv.ip_index,
3843 } });
3844 return only.toValue();
38353845 }
3846
3847 return null;
38363848 },
38373849 .auto, .explicit => switch (enum_type.names.len) {
38383850 0 => return Value.@"unreachable",
38393851 1 => {
38403852 if (enum_type.values.len == 0) {
3841 return Value.enum_field_0; // auto-numbered
3853 const only = try mod.intern(.{ .enum_tag = .{
3854 .ty = ty.ip_index,
3855 .int = try mod.intern(.{ .int = .{
3856 .ty = enum_type.tag_ty,
3857 .storage = .{ .u64 = 0 },
3858 } }),
3859 } });
3860 return only.toValue();
38423861 } else {
38433862 return enum_type.values[0].toValue();
38443863 }
......@@ -3848,6 +3867,7 @@ pub const Type = struct {
38483867 },
38493868
38503869 // values, not types
3870 .undef => unreachable,
38513871 .un => unreachable,
38523872 .simple_value => unreachable,
38533873 .extern_func => unreachable,
......@@ -4006,6 +4026,7 @@ pub const Type = struct {
40064026 .enum_type => |enum_type| enum_type.tag_ty.toType().comptimeOnly(mod),
40074027
40084028 // values, not types
4029 .undef => unreachable,
40094030 .un => unreachable,
40104031 .simple_value => unreachable,
40114032 .extern_func => unreachable,
......@@ -4224,36 +4245,22 @@ pub const Type = struct {
42244245 return ip.stringToSlice(field_name);
42254246 }
42264247
4227 pub fn enumFieldIndex(ty: Type, field_name: []const u8, mod: *Module) ?usize {
4248 pub fn enumFieldIndex(ty: Type, field_name: []const u8, mod: *Module) ?u32 {
42284249 const ip = &mod.intern_pool;
42294250 const enum_type = ip.indexToKey(ty.ip_index).enum_type;
42304251 // If the string is not interned, then the field certainly is not present.
42314252 const field_name_interned = ip.getString(field_name).unwrap() orelse return null;
4232 return enum_type.nameIndex(ip.*, field_name_interned);
4253 return enum_type.nameIndex(ip, field_name_interned);
42334254 }
42344255
42354256 /// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or
42364257 /// an integer which represents the enum value. Returns the field index in
42374258 /// declaration order, or `null` if `enum_tag` does not match any field.
4238 pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?usize {
4239 if (enum_tag.castTag(.enum_field_index)) |payload| {
4240 return @as(usize, payload.data);
4241 }
4259 pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?u32 {
42424260 const ip = &mod.intern_pool;
42434261 const enum_type = ip.indexToKey(ty.ip_index).enum_type;
4244 const tag_ty = enum_type.tag_ty.toType();
4245 if (enum_type.values.len == 0) {
4246 if (enum_tag.compareAllWithZero(.lt, mod)) return null;
4247 const end_val = mod.intValue(tag_ty, enum_type.names.len) catch |err| switch (err) {
4248 // TODO: eliminate this failure condition
4249 error.OutOfMemory => @panic("OOM"),
4250 };
4251 if (enum_tag.compareScalar(.gte, end_val, tag_ty, mod)) return null;
4252 return @intCast(usize, enum_tag.toUnsignedInt(mod));
4253 } else {
4254 assert(ip.typeOf(enum_tag.ip_index) == enum_type.tag_ty);
4255 return enum_type.tagValueIndex(ip.*, enum_tag.ip_index);
4256 }
4262 assert(ip.typeOf(enum_tag.ip_index) == enum_type.tag_ty);
4263 return enum_type.tagValueIndex(ip, enum_tag.ip_index);
42574264 }
42584265
42594266 pub fn structFields(ty: Type, mod: *Module) Module.Struct.Fields {
src/value.zig+99-155
......@@ -73,8 +73,6 @@ pub const Value = struct {
7373 /// Pointer and length as sub `Value` objects.
7474 slice,
7575 enum_literal,
76 /// A specific enum tag, indicated by the field index (declaration order).
77 enum_field_index,
7876 @"error",
7977 /// When the type is error union:
8078 /// * If the tag is `.@"error"`, the error union is an error.
......@@ -143,8 +141,6 @@ pub const Value = struct {
143141 .str_lit => Payload.StrLit,
144142 .slice => Payload.Slice,
145143
146 .enum_field_index => Payload.U32,
147
148144 .ty,
149145 .lazy_align,
150146 .lazy_size,
......@@ -397,7 +393,6 @@ pub const Value = struct {
397393 .legacy = .{ .ptr_otherwise = &new_payload.base },
398394 };
399395 },
400 .enum_field_index => return self.copyPayloadShallow(arena, Payload.U32),
401396 .@"error" => return self.copyPayloadShallow(arena, Payload.Error),
402397
403398 .aggregate => {
......@@ -515,7 +510,6 @@ pub const Value = struct {
515510 },
516511 .empty_array => return out_stream.writeAll(".{}"),
517512 .enum_literal => return out_stream.print(".{}", .{std.zig.fmtId(val.castTag(.enum_literal).?.data)}),
518 .enum_field_index => return out_stream.print("(enum field {d})", .{val.castTag(.enum_field_index).?.data}),
519513 .bytes => return out_stream.print("\"{}\"", .{std.zig.fmtEscapes(val.castTag(.bytes).?.data)}),
520514 .str_lit => {
521515 const str_lit = val.castTag(.str_lit).?.data;
......@@ -618,87 +612,58 @@ pub const Value = struct {
618612 };
619613 }
620614
621 /// Asserts the type is an enum type.
622 pub fn toEnum(val: Value, comptime E: type) E {
615 pub fn enumToInt(val: Value, ty: Type, mod: *Module) Allocator.Error!Value {
616 const ip = &mod.intern_pool;
623617 switch (val.ip_index) {
624 .calling_convention_c => {
625 if (E == std.builtin.CallingConvention) {
626 return .C;
618 .none => {
619 const field_index = switch (val.tag()) {
620 .the_only_possible_value => blk: {
621 assert(ty.enumFieldCount(mod) == 1);
622 break :blk 0;
623 },
624 .enum_literal => i: {
625 const name = val.castTag(.enum_literal).?.data;
626 break :i ty.enumFieldIndex(name, mod).?;
627 },
628 else => unreachable,
629 };
630 const enum_type = ip.indexToKey(ty.ip_index).enum_type;
631 if (enum_type.values.len != 0) {
632 return enum_type.values[field_index].toValue();
627633 } else {
628 unreachable;
634 // Field index and integer values are the same.
635 return mod.intValue(enum_type.tag_ty.toType(), field_index);
629636 }
630637 },
631 .calling_convention_inline => {
632 if (E == std.builtin.CallingConvention) {
633 return .Inline;
634 } else {
635 unreachable;
636 }
638 else => {
639 const enum_type = ip.indexToKey(ip.typeOf(val.ip_index)).enum_type;
640 const int = try ip.getCoerced(mod.gpa, val.ip_index, enum_type.tag_ty);
641 return int.toValue();
637642 },
638 .none => switch (val.tag()) {
639 .enum_field_index => {
640 const field_index = val.castTag(.enum_field_index).?.data;
641 return @intToEnum(E, field_index);
642 },
643 .the_only_possible_value => {
644 const fields = std.meta.fields(E);
645 assert(fields.len == 1);
646 return @intToEnum(E, fields[0].value);
647 },
648 else => unreachable,
649 },
650 else => unreachable,
651643 }
652644 }
653645
654 pub fn enumToInt(val: Value, ty: Type, mod: *Module) Allocator.Error!Value {
655 const field_index = switch (val.tag()) {
656 .enum_field_index => val.castTag(.enum_field_index).?.data,
657 .the_only_possible_value => blk: {
658 assert(ty.enumFieldCount(mod) == 1);
659 break :blk 0;
660 },
661 .enum_literal => i: {
662 const name = val.castTag(.enum_literal).?.data;
663 break :i ty.enumFieldIndex(name, mod).?;
664 },
665 // Assume it is already an integer and return it directly.
666 else => return val,
667 };
646 pub fn tagName(val: Value, ty: Type, mod: *Module) []const u8 {
647 _ = ty; // TODO: remove this parameter now that we use InternPool
668648
669 const enum_type = mod.intern_pool.indexToKey(ty.ip_index).enum_type;
670 if (enum_type.values.len != 0) {
671 return enum_type.values[field_index].toValue();
672 } else {
673 // Field index and integer values are the same.
674 return mod.intValue(enum_type.tag_ty.toType(), field_index);
649 if (val.castTag(.enum_literal)) |payload| {
650 return payload.data;
675651 }
676 }
677
678 pub fn tagName(val: Value, ty: Type, mod: *Module) []const u8 {
679 if (ty.zigTypeTag(mod) == .Union) return val.unionTag().tagName(ty.unionTagTypeHypothetical(mod), mod);
680652
681 const enum_type = mod.intern_pool.indexToKey(ty.ip_index).enum_type;
653 const ip = &mod.intern_pool;
682654
683 const field_index = switch (val.tag()) {
684 .enum_field_index => val.castTag(.enum_field_index).?.data,
685 .the_only_possible_value => blk: {
686 assert(ty.enumFieldCount(mod) == 1);
687 break :blk 0;
688 },
689 .enum_literal => return val.castTag(.enum_literal).?.data,
690 else => field_index: {
691 if (enum_type.values.len == 0) {
692 // auto-numbered enum
693 break :field_index @intCast(u32, val.toUnsignedInt(mod));
694 }
695 const field_index = enum_type.tagValueIndex(mod.intern_pool, val.ip_index).?;
696 break :field_index @intCast(u32, field_index);
697 },
655 const enum_tag = switch (ip.indexToKey(val.ip_index)) {
656 .un => |un| ip.indexToKey(un.tag).enum_tag,
657 .enum_tag => |x| x,
658 else => unreachable,
659 };
660 const enum_type = ip.indexToKey(enum_tag.ty).enum_type;
661 const field_index = field_index: {
662 const field_index = enum_type.tagValueIndex(ip, val.ip_index).?;
663 break :field_index @intCast(u32, field_index);
698664 };
699
700665 const field_name = enum_type.names[field_index];
701 return mod.intern_pool.stringToSlice(field_name);
666 return ip.stringToSlice(field_name);
702667 }
703668
704669 /// Asserts the value is an integer.
......@@ -722,10 +687,6 @@ pub const Value = struct {
722687 .the_only_possible_value, // i0, u0
723688 => BigIntMutable.init(&space.limbs, 0).toConst(),
724689
725 .enum_field_index => {
726 const index = val.castTag(.enum_field_index).?.data;
727 return BigIntMutable.init(&space.limbs, index).toConst();
728 },
729690 .runtime_value => {
730691 const sub_val = val.castTag(.runtime_value).?.data;
731692 return sub_val.toBigIntAdvanced(space, mod, opt_sema);
......@@ -759,6 +720,7 @@ pub const Value = struct {
759720 },
760721 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
761722 .int => |int| int.storage.toBigInt(space),
723 .enum_tag => |enum_tag| mod.intern_pool.indexToKey(enum_tag.int).int.storage.toBigInt(space),
762724 else => unreachable,
763725 },
764726 };
......@@ -886,7 +848,7 @@ pub const Value = struct {
886848 }!void {
887849 const target = mod.getTarget();
888850 const endian = target.cpu.arch.endian();
889 if (val.isUndef()) {
851 if (val.isUndef(mod)) {
890852 const size = @intCast(usize, ty.abiSize(mod));
891853 @memset(buffer[0..size], 0xaa);
892854 return;
......@@ -1007,7 +969,7 @@ pub const Value = struct {
1007969 ) error{ ReinterpretDeclRef, OutOfMemory }!void {
1008970 const target = mod.getTarget();
1009971 const endian = target.cpu.arch.endian();
1010 if (val.isUndef()) {
972 if (val.isUndef(mod)) {
1011973 const bit_size = @intCast(usize, ty.bitSize(mod));
1012974 std.mem.writeVarPackedInt(buffer, bit_offset, bit_size, @as(u1, 0), endian);
1013975 return;
......@@ -1087,7 +1049,7 @@ pub const Value = struct {
10871049 .Auto => unreachable, // Sema is supposed to have emitted a compile error already
10881050 .Extern => unreachable, // Handled in non-packed writeToMemory
10891051 .Packed => {
1090 const field_index = ty.unionTagFieldIndex(val.unionTag(), mod);
1052 const field_index = ty.unionTagFieldIndex(val.unionTag(mod), mod);
10911053 const field_type = ty.unionFields(mod).values()[field_index.?].ty;
10921054 const field_val = try val.fieldValue(field_type, mod, field_index.?);
10931055
......@@ -1432,7 +1394,7 @@ pub const Value = struct {
14321394 }
14331395
14341396 pub fn popCount(val: Value, ty: Type, mod: *Module) u64 {
1435 assert(!val.isUndef());
1397 assert(!val.isUndef(mod));
14361398 switch (val.ip_index) {
14371399 .bool_false => return 0,
14381400 .bool_true => return 1,
......@@ -1450,7 +1412,7 @@ pub const Value = struct {
14501412 }
14511413
14521414 pub fn bitReverse(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {
1453 assert(!val.isUndef());
1415 assert(!val.isUndef(mod));
14541416
14551417 const info = ty.intInfo(mod);
14561418
......@@ -1468,7 +1430,7 @@ pub const Value = struct {
14681430 }
14691431
14701432 pub fn byteSwap(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {
1471 assert(!val.isUndef());
1433 assert(!val.isUndef(mod));
14721434
14731435 const info = ty.intInfo(mod);
14741436
......@@ -1578,7 +1540,6 @@ pub const Value = struct {
15781540 .variable,
15791541 => .gt,
15801542
1581 .enum_field_index => return std.math.order(lhs.castTag(.enum_field_index).?.data, 0),
15821543 .runtime_value => {
15831544 // This is needed to correctly handle hashing the value.
15841545 // Checks in Sema should prevent direct comparisons from reaching here.
......@@ -1633,6 +1594,10 @@ pub const Value = struct {
16331594 .big_int => |big_int| big_int.orderAgainstScalar(0),
16341595 inline .u64, .i64 => |x| std.math.order(x, 0),
16351596 },
1597 .enum_tag => |enum_tag| switch (mod.intern_pool.indexToKey(enum_tag.int).int.storage) {
1598 .big_int => |big_int| big_int.orderAgainstScalar(0),
1599 inline .u64, .i64 => |x| std.math.order(x, 0),
1600 },
16361601 .float => |float| switch (float.storage) {
16371602 inline else => |x| std.math.order(x, 0),
16381603 },
......@@ -1861,11 +1826,6 @@ pub const Value = struct {
18611826 const b_name = b.castTag(.enum_literal).?.data;
18621827 return std.mem.eql(u8, a_name, b_name);
18631828 },
1864 .enum_field_index => {
1865 const a_field_index = a.castTag(.enum_field_index).?.data;
1866 const b_field_index = b.castTag(.enum_field_index).?.data;
1867 return a_field_index == b_field_index;
1868 },
18691829 .opt_payload => {
18701830 const a_payload = a.castTag(.opt_payload).?.data;
18711831 const b_payload = b.castTag(.opt_payload).?.data;
......@@ -2064,13 +2024,9 @@ pub const Value = struct {
20642024 }
20652025 const field_name = tuple.names[0];
20662026 const union_obj = mod.typeToUnion(ty).?;
2067 const field_index = union_obj.fields.getIndex(field_name) orelse return false;
2027 const field_index = @intCast(u32, union_obj.fields.getIndex(field_name) orelse return false);
20682028 const tag_and_val = b.castTag(.@"union").?.data;
2069 var field_tag_buf: Value.Payload.U32 = .{
2070 .base = .{ .tag = .enum_field_index },
2071 .data = @intCast(u32, field_index),
2072 };
2073 const field_tag = Value.initPayload(&field_tag_buf.base);
2029 const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, field_index);
20742030 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, mod);
20752031 if (!tag_matches) return false;
20762032 return eqlAdvanced(tag_and_val.val, union_obj.tag_ty, tuple.values[0], tuple.types[0], mod, opt_sema);
......@@ -2132,7 +2088,7 @@ pub const Value = struct {
21322088 }
21332089 const zig_ty_tag = ty.zigTypeTag(mod);
21342090 std.hash.autoHash(hasher, zig_ty_tag);
2135 if (val.isUndef()) return;
2091 if (val.isUndef(mod)) return;
21362092 // The value is runtime-known and shouldn't affect the hash.
21372093 if (val.isRuntimeValue()) return;
21382094
......@@ -2277,7 +2233,7 @@ pub const Value = struct {
22772233 /// This function is used by hash maps and so treats floating-point NaNs as equal
22782234 /// to each other, and not equal to other floating-point values.
22792235 pub fn hashUncoerced(val: Value, ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void {
2280 if (val.isUndef()) return;
2236 if (val.isUndef(mod)) return;
22812237 // The value is runtime-known and shouldn't affect the hash.
22822238 if (val.isRuntimeValue()) return;
22832239
......@@ -2726,16 +2682,12 @@ pub const Value = struct {
27262682 }
27272683 }
27282684
2729 pub fn unionTag(val: Value) Value {
2730 switch (val.ip_index) {
2731 .undef => return val,
2732 .none => switch (val.tag()) {
2733 .enum_field_index => return val,
2734 .@"union" => return val.castTag(.@"union").?.data.tag,
2735 else => unreachable,
2736 },
2685 pub fn unionTag(val: Value, mod: *Module) Value {
2686 return switch (mod.intern_pool.indexToKey(val.ip_index)) {
2687 .undef, .enum_tag => val,
2688 .un => |un| un.tag.toValue(),
27372689 else => unreachable,
2738 }
2690 };
27392691 }
27402692
27412693 /// Returns a pointer to the element value at the index.
......@@ -2769,27 +2721,30 @@ pub const Value = struct {
27692721 });
27702722 }
27712723
2772 pub fn isUndef(val: Value) bool {
2773 return val.ip_index == .undef;
2724 pub fn isUndef(val: Value, mod: *Module) bool {
2725 if (val.ip_index == .none) return false;
2726 return switch (mod.intern_pool.indexToKey(val.ip_index)) {
2727 .undef => true,
2728 .simple_value => |v| v == .undefined,
2729 else => false,
2730 };
27742731 }
27752732
27762733 /// TODO: check for cases such as array that is not marked undef but all the element
27772734 /// values are marked undef, or struct that is not marked undef but all fields are marked
27782735 /// undef, etc.
2779 pub fn isUndefDeep(val: Value) bool {
2780 return val.isUndef();
2736 pub fn isUndefDeep(val: Value, mod: *Module) bool {
2737 return val.isUndef(mod);
27812738 }
27822739
27832740 /// Returns true if any value contained in `self` is undefined.
2784 /// TODO: check for cases such as array that is not marked undef but all the element
2785 /// values are marked undef, or struct that is not marked undef but all fields are marked
2786 /// undef, etc.
2787 pub fn anyUndef(self: Value, mod: *Module) !bool {
2788 switch (self.ip_index) {
2741 pub fn anyUndef(val: Value, mod: *Module) !bool {
2742 if (val.ip_index == .none) return false;
2743 switch (val.ip_index) {
27892744 .undef => return true,
2790 .none => switch (self.tag()) {
2745 .none => switch (val.tag()) {
27912746 .slice => {
2792 const payload = self.castTag(.slice).?;
2747 const payload = val.castTag(.slice).?;
27932748 const len = payload.data.len.toUnsignedInt(mod);
27942749
27952750 for (0..len) |i| {
......@@ -2799,14 +2754,21 @@ pub const Value = struct {
27992754 },
28002755
28012756 .aggregate => {
2802 const payload = self.castTag(.aggregate).?;
2803 for (payload.data) |val| {
2804 if (try val.anyUndef(mod)) return true;
2757 const payload = val.castTag(.aggregate).?;
2758 for (payload.data) |field| {
2759 if (try field.anyUndef(mod)) return true;
28052760 }
28062761 },
28072762 else => {},
28082763 },
2809 else => {},
2764 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
2765 .undef => return true,
2766 .simple_value => |v| if (v == .undefined) return true,
2767 .aggregate => |aggregate| for (aggregate.fields) |field| {
2768 if (try anyUndef(field.toValue(), mod)) return true;
2769 },
2770 else => {},
2771 },
28102772 }
28112773
28122774 return false;
......@@ -2819,11 +2781,7 @@ pub const Value = struct {
28192781 .undef => unreachable,
28202782 .unreachable_value => unreachable,
28212783
2822 .null_value,
2823 .zero,
2824 .zero_usize,
2825 .zero_u8,
2826 => true,
2784 .null_value => true,
28272785
28282786 .none => switch (val.tag()) {
28292787 .opt_payload => false,
......@@ -2843,6 +2801,7 @@ pub const Value = struct {
28432801 .big_int => |big_int| big_int.eqZero(),
28442802 inline .u64, .i64 => |x| x == 0,
28452803 },
2804 .opt => |opt| opt.val == .none,
28462805 else => unreachable,
28472806 },
28482807 };
......@@ -3024,8 +2983,8 @@ pub const Value = struct {
30242983 arena: Allocator,
30252984 mod: *Module,
30262985 ) !Value {
3027 assert(!lhs.isUndef());
3028 assert(!rhs.isUndef());
2986 assert(!lhs.isUndef(mod));
2987 assert(!rhs.isUndef(mod));
30292988
30302989 const info = ty.intInfo(mod);
30312990
......@@ -3071,8 +3030,8 @@ pub const Value = struct {
30713030 arena: Allocator,
30723031 mod: *Module,
30733032 ) !Value {
3074 assert(!lhs.isUndef());
3075 assert(!rhs.isUndef());
3033 assert(!lhs.isUndef(mod));
3034 assert(!rhs.isUndef(mod));
30763035
30773036 const info = ty.intInfo(mod);
30783037
......@@ -3178,7 +3137,7 @@ pub const Value = struct {
31783137 arena: Allocator,
31793138 mod: *Module,
31803139 ) !Value {
3181 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;
3140 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.undef;
31823141
31833142 if (ty.zigTypeTag(mod) == .ComptimeInt) {
31843143 return intMul(lhs, rhs, ty, arena, mod);
......@@ -3220,8 +3179,8 @@ pub const Value = struct {
32203179 arena: Allocator,
32213180 mod: *Module,
32223181 ) !Value {
3223 assert(!lhs.isUndef());
3224 assert(!rhs.isUndef());
3182 assert(!lhs.isUndef(mod));
3183 assert(!rhs.isUndef(mod));
32253184
32263185 const info = ty.intInfo(mod);
32273186
......@@ -3249,7 +3208,7 @@ pub const Value = struct {
32493208
32503209 /// Supports both floats and ints; handles undefined.
32513210 pub fn numberMax(lhs: Value, rhs: Value, mod: *Module) Value {
3252 if (lhs.isUndef() or rhs.isUndef()) return undef;
3211 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return undef;
32533212 if (lhs.isNan(mod)) return rhs;
32543213 if (rhs.isNan(mod)) return lhs;
32553214
......@@ -3261,7 +3220,7 @@ pub const Value = struct {
32613220
32623221 /// Supports both floats and ints; handles undefined.
32633222 pub fn numberMin(lhs: Value, rhs: Value, mod: *Module) Value {
3264 if (lhs.isUndef() or rhs.isUndef()) return undef;
3223 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return undef;
32653224 if (lhs.isNan(mod)) return rhs;
32663225 if (rhs.isNan(mod)) return lhs;
32673226
......@@ -3286,7 +3245,7 @@ pub const Value = struct {
32863245
32873246 /// operands must be integers; handles undefined.
32883247 pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value {
3289 if (val.isUndef()) return Value.undef;
3248 if (val.isUndef(mod)) return Value.undef;
32903249
32913250 const info = ty.intInfo(mod);
32923251
......@@ -3324,7 +3283,7 @@ pub const Value = struct {
33243283
33253284 /// operands must be integers; handles undefined.
33263285 pub fn bitwiseAndScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {
3327 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;
3286 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.undef;
33283287
33293288 // TODO is this a performance issue? maybe we should try the operation without
33303289 // resorting to BigInt first.
......@@ -3358,7 +3317,7 @@ pub const Value = struct {
33583317
33593318 /// operands must be integers; handles undefined.
33603319 pub fn bitwiseNandScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {
3361 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;
3320 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.undef;
33623321
33633322 const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod);
33643323 const all_ones = if (ty.isSignedInt(mod)) try mod.intValue(ty, -1) else try ty.maxIntScalar(mod, ty);
......@@ -3381,7 +3340,7 @@ pub const Value = struct {
33813340
33823341 /// operands must be integers; handles undefined.
33833342 pub fn bitwiseOrScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {
3384 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;
3343 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.undef;
33853344
33863345 // TODO is this a performance issue? maybe we should try the operation without
33873346 // resorting to BigInt first.
......@@ -3415,7 +3374,7 @@ pub const Value = struct {
34153374
34163375 /// operands must be integers; handles undefined.
34173376 pub fn bitwiseXorScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {
3418 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;
3377 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.undef;
34193378
34203379 // TODO is this a performance issue? maybe we should try the operation without
34213380 // resorting to BigInt first.
......@@ -4697,11 +4656,6 @@ pub const Value = struct {
46974656 pub const Payload = struct {
46984657 tag: Tag,
46994658
4700 pub const U32 = struct {
4701 base: Payload,
4702 data: u32,
4703 };
4704
47054659 pub const Function = struct {
47064660 base: Payload,
47074661 data: *Module.Fn,
......@@ -4885,16 +4839,6 @@ pub const Value = struct {
48854839 pub const generic_poison_type: Value = .{ .ip_index = .generic_poison_type, .legacy = undefined };
48864840 pub const empty_struct: Value = .{ .ip_index = .empty_struct, .legacy = undefined };
48874841
4888 pub const enum_field_0: Value = .{
4889 .ip_index = .none,
4890 .legacy = .{ .ptr_otherwise = &enum_field_0_payload.base },
4891 };
4892
4893 var enum_field_0_payload: Payload.U32 = .{
4894 .base = .{ .tag = .enum_field_index },
4895 .data = 0,
4896 };
4897
48984842 pub fn makeBool(x: bool) Value {
48994843 return if (x) Value.true else Value.false;
49004844 }