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 {...@@ -223,6 +223,13 @@ pub const SourceLocation = struct {
223pub const TypeId = std.meta.Tag(Type);223pub const TypeId = std.meta.Tag(Type);
224pub const TypeInfo = @compileError("deprecated; use Type");224pub 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
226/// This data structure is used by the Zig language code generation and233/// This data structure is used by the Zig language code generation and
227/// therefore must be kept in sync with the compiler implementation.234/// therefore must be kept in sync with the compiler implementation.
228pub const Type = union(enum) {235pub const Type = union(enum) {
src/Air.zig+3
...@@ -845,6 +845,7 @@ pub const Inst = struct {...@@ -845,6 +845,7 @@ pub const Inst = struct {
845845
846 pub const Ref = enum(u32) {846 pub const Ref = enum(u32) {
847 u1_type = @enumToInt(InternPool.Index.u1_type),847 u1_type = @enumToInt(InternPool.Index.u1_type),
848 u5_type = @enumToInt(InternPool.Index.u5_type),
848 u8_type = @enumToInt(InternPool.Index.u8_type),849 u8_type = @enumToInt(InternPool.Index.u8_type),
849 i8_type = @enumToInt(InternPool.Index.i8_type),850 i8_type = @enumToInt(InternPool.Index.i8_type),
850 u16_type = @enumToInt(InternPool.Index.u16_type),851 u16_type = @enumToInt(InternPool.Index.u16_type),
...@@ -913,6 +914,8 @@ pub const Inst = struct {...@@ -913,6 +914,8 @@ pub const Inst = struct {
913 zero_u8 = @enumToInt(InternPool.Index.zero_u8),914 zero_u8 = @enumToInt(InternPool.Index.zero_u8),
914 one = @enumToInt(InternPool.Index.one),915 one = @enumToInt(InternPool.Index.one),
915 one_usize = @enumToInt(InternPool.Index.one_usize),916 one_usize = @enumToInt(InternPool.Index.one_usize),
917 one_u5 = @enumToInt(InternPool.Index.one_u5),
918 four_u5 = @enumToInt(InternPool.Index.four_u5),
916 negative_one = @enumToInt(InternPool.Index.negative_one),919 negative_one = @enumToInt(InternPool.Index.negative_one),
917 calling_convention_c = @enumToInt(InternPool.Index.calling_convention_c),920 calling_convention_c = @enumToInt(InternPool.Index.calling_convention_c),
918 calling_convention_inline = @enumToInt(InternPool.Index.calling_convention_inline),921 calling_convention_inline = @enumToInt(InternPool.Index.calling_convention_inline),
src/InternPool.zig+218-97
...@@ -144,6 +144,9 @@ pub const Key = union(enum) {...@@ -144,6 +144,9 @@ pub const Key = union(enum) {
144 opaque_type: OpaqueType,144 opaque_type: OpaqueType,
145 enum_type: EnumType,145 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,
147 simple_value: SimpleValue,150 simple_value: SimpleValue,
148 extern_func: struct {151 extern_func: struct {
149 ty: Index,152 ty: Index,
...@@ -155,13 +158,12 @@ pub const Key = union(enum) {...@@ -155,13 +158,12 @@ pub const Key = union(enum) {
155 lib_name: u32,158 lib_name: u32,
156 },159 },
157 int: Key.Int,160 int: Key.Int,
161 /// A specific enum tag, indicated by the integer tag value.
162 enum_tag: Key.EnumTag,
158 float: Key.Float,163 float: Key.Float,
159 ptr: Ptr,164 ptr: Ptr,
160 opt: Opt,165 opt: Opt,
161 enum_tag: struct {166
162 ty: Index,
163 tag: BigIntConst,
164 },
165 /// An instance of a struct, array, or vector.167 /// An instance of a struct, array, or vector.
166 /// Each element/field stored as an `Index`.168 /// Each element/field stored as an `Index`.
167 /// In the case of sentinel-terminated arrays, the sentinel value *is* stored,169 /// In the case of sentinel-terminated arrays, the sentinel value *is* stored,
...@@ -284,21 +286,33 @@ pub const Key = union(enum) {...@@ -284,21 +286,33 @@ pub const Key = union(enum) {
284 };286 };
285287
286 /// Look up field index based on field name.288 /// 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 {
288 const map = &ip.maps.items[@enumToInt(self.names_map.unwrap().?)];290 const map = &ip.maps.items[@enumToInt(self.names_map.unwrap().?)];
289 const adapter: NullTerminatedString.Adapter = .{ .strings = self.names };291 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);
291 }294 }
292295
293 /// Look up field index based on tag value.296 /// Look up field index based on tag value.
294 /// Asserts that `values_map` is not `none`.297 /// Asserts that `values_map` is not `none`.
295 /// This function returns `null` when `tag_val` does not have the298 /// This function returns `null` when `tag_val` does not have the
296 /// integer tag type of the enum.299 /// 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 {
298 assert(tag_val != .none);301 assert(tag_val != .none);
299 const map = &ip.maps.items[@enumToInt(self.values_map.unwrap().?)];302 if (self.values_map.unwrap()) |values_map| {
300 const adapter: Index.Adapter = .{ .indexes = self.values };303 const map = &ip.maps.items[@enumToInt(values_map)];
301 return map.getIndexAdapted(tag_val, adapter);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 }
302 }316 }
303 };317 };
304318
...@@ -362,6 +376,13 @@ pub const Key = union(enum) {...@@ -362,6 +376,13 @@ pub const Key = union(enum) {
362 };376 };
363 };377 };
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
365 pub const Float = struct {386 pub const Float = struct {
366 ty: Index,387 ty: Index,
367 /// The storage used must match the size of the float type being represented.388 /// The storage used must match the size of the float type being represented.
...@@ -436,6 +457,8 @@ pub const Key = union(enum) {...@@ -436,6 +457,8 @@ pub const Key = union(enum) {
436 .struct_type,457 .struct_type,
437 .union_type,458 .union_type,
438 .un,459 .un,
460 .undef,
461 .enum_tag,
439 => |info| std.hash.autoHash(hasher, info),462 => |info| std.hash.autoHash(hasher, info),
440463
441 .opaque_type => |opaque_type| std.hash.autoHash(hasher, opaque_type.decl),464 .opaque_type => |opaque_type| std.hash.autoHash(hasher, opaque_type.decl),
...@@ -471,12 +494,6 @@ pub const Key = union(enum) {...@@ -471,12 +494,6 @@ pub const Key = union(enum) {
471 }494 }
472 },495 },
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
480 .aggregate => |aggregate| {497 .aggregate => |aggregate| {
481 std.hash.autoHash(hasher, aggregate.ty);498 std.hash.autoHash(hasher, aggregate.ty);
482 for (aggregate.fields) |field| std.hash.autoHash(hasher, field);499 for (aggregate.fields) |field| std.hash.autoHash(hasher, field);
...@@ -522,6 +539,10 @@ pub const Key = union(enum) {...@@ -522,6 +539,10 @@ pub const Key = union(enum) {
522 const b_info = b.simple_value;539 const b_info = b.simple_value;
523 return a_info == b_info;540 return a_info == b_info;
524 },541 },
542 .undef => |a_info| {
543 const b_info = b.undef;
544 return a_info == b_info;
545 },
525 .extern_func => |a_info| {546 .extern_func => |a_info| {
526 const b_info = b.extern_func;547 const b_info = b.extern_func;
527 return std.meta.eql(a_info, b_info);548 return std.meta.eql(a_info, b_info);
...@@ -542,6 +563,10 @@ pub const Key = union(enum) {...@@ -542,6 +563,10 @@ pub const Key = union(enum) {
542 const b_info = b.un;563 const b_info = b.un;
543 return std.meta.eql(a_info, b_info);564 return std.meta.eql(a_info, b_info);
544 },565 },
566 .enum_tag => |a_info| {
567 const b_info = b.enum_tag;
568 return std.meta.eql(a_info, b_info);
569 },
545570
546 .ptr => |a_info| {571 .ptr => |a_info| {
547 const b_info = b.ptr;572 const b_info = b.ptr;
...@@ -612,13 +637,6 @@ pub const Key = union(enum) {...@@ -612,13 +637,6 @@ pub const Key = union(enum) {
612 };637 };
613 },638 },
614639
615 .enum_tag => |a_info| {
616 const b_info = b.enum_tag;
617 _ = a_info;
618 _ = b_info;
619 @panic("TODO");
620 },
621
622 .opaque_type => |a_info| {640 .opaque_type => |a_info| {
623 const b_info = b.opaque_type;641 const b_info = b.opaque_type;
624 return a_info.decl == b_info.decl;642 return a_info.decl == b_info.decl;
...@@ -636,7 +654,7 @@ pub const Key = union(enum) {...@@ -636,7 +654,7 @@ pub const Key = union(enum) {
636 }654 }
637655
638 pub fn typeOf(key: Key) Index {656 pub fn typeOf(key: Key) Index {
639 switch (key) {657 return switch (key) {
640 .int_type,658 .int_type,
641 .ptr_type,659 .ptr_type,
642 .array_type,660 .array_type,
...@@ -648,7 +666,7 @@ pub const Key = union(enum) {...@@ -648,7 +666,7 @@ pub const Key = union(enum) {
648 .union_type,666 .union_type,
649 .opaque_type,667 .opaque_type,
650 .enum_type,668 .enum_type,
651 => return .type_type,669 => .type_type,
652670
653 inline .ptr,671 inline .ptr,
654 .int,672 .int,
...@@ -658,18 +676,20 @@ pub const Key = union(enum) {...@@ -658,18 +676,20 @@ pub const Key = union(enum) {
658 .enum_tag,676 .enum_tag,
659 .aggregate,677 .aggregate,
660 .un,678 .un,
661 => |x| return x.ty,679 => |x| x.ty,
680
681 .undef => |x| x,
662682
663 .simple_value => |s| switch (s) {683 .simple_value => |s| switch (s) {
664 .undefined => return .undefined_type,684 .undefined => .undefined_type,
665 .void => return .void_type,685 .void => .void_type,
666 .null => return .null_type,686 .null => .null_type,
667 .false, .true => return .bool_type,687 .false, .true => .bool_type,
668 .empty_struct => return .empty_struct_type,688 .empty_struct => .empty_struct_type,
669 .@"unreachable" => return .noreturn_type,689 .@"unreachable" => .noreturn_type,
670 .generic_poison => unreachable,690 .generic_poison => unreachable,
671 },691 },
672 }692 };
673 }693 }
674};694};
675695
...@@ -693,6 +713,7 @@ pub const Index = enum(u32) {...@@ -693,6 +713,7 @@ pub const Index = enum(u32) {
693 pub const last_value: Index = .empty_struct;713 pub const last_value: Index = .empty_struct;
694714
695 u1_type,715 u1_type,
716 u5_type,
696 u8_type,717 u8_type,
697 i8_type,718 i8_type,
698 u16_type,719 u16_type,
...@@ -769,6 +790,10 @@ pub const Index = enum(u32) {...@@ -769,6 +790,10 @@ pub const Index = enum(u32) {
769 one,790 one,
770 /// `1` (usize)791 /// `1` (usize)
771 one_usize,792 one_usize,
793 /// `1` (u5)
794 one_u5,
795 /// `4` (u5)
796 four_u5,
772 /// `-1` (comptime_int)797 /// `-1` (comptime_int)
773 negative_one,798 negative_one,
774 /// `std.builtin.CallingConvention.C`799 /// `std.builtin.CallingConvention.C`
...@@ -834,6 +859,12 @@ pub const static_keys = [_]Key{...@@ -834,6 +859,12 @@ pub const static_keys = [_]Key{
834 .bits = 1,859 .bits = 1,
835 } },860 } },
836861
862 // u5_type
863 .{ .int_type = .{
864 .signedness = .unsigned,
865 .bits = 5,
866 } },
867
837 .{ .int_type = .{868 .{ .int_type = .{
838 .signedness = .unsigned,869 .signedness = .unsigned,
839 .bits = 8,870 .bits = 8,
...@@ -1021,25 +1052,30 @@ pub const static_keys = [_]Key{...@@ -1021,25 +1052,30 @@ pub const static_keys = [_]Key{
1021 .storage = .{ .u64 = 1 },1052 .storage = .{ .u64 = 1 },
1022 } },1053 } },
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
1024 .{ .int = .{1066 .{ .int = .{
1025 .ty = .comptime_int_type,1067 .ty = .comptime_int_type,
1026 .storage = .{ .i64 = -1 },1068 .storage = .{ .i64 = -1 },
1027 } },1069 } },
10281070 // calling_convention_c
1029 .{ .enum_tag = .{1071 .{ .enum_tag = .{
1030 .ty = .calling_convention_type,1072 .ty = .calling_convention_type,
1031 .tag = .{1073 .int = .one_u5,
1032 .limbs = &.{@enumToInt(std.builtin.CallingConvention.C)},
1033 .positive = true,
1034 },
1035 } },1074 } },
10361075 // calling_convention_inline
1037 .{ .enum_tag = .{1076 .{ .enum_tag = .{
1038 .ty = .calling_convention_type,1077 .ty = .calling_convention_type,
1039 .tag = .{1078 .int = .four_u5,
1040 .limbs = &.{@enumToInt(std.builtin.CallingConvention.Inline)},
1041 .positive = true,
1042 },
1043 } },1079 } },
10441080
1045 .{ .simple_value = .void },1081 .{ .simple_value = .void },
...@@ -1118,6 +1154,10 @@ pub const Tag = enum(u8) {...@@ -1118,6 +1154,10 @@ pub const Tag = enum(u8) {
1118 /// `data` is `Module.Union.Index`.1154 /// `data` is `Module.Union.Index`.
1119 type_union_safety,1155 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,
1121 /// A value that can be represented with only an enum tag.1161 /// A value that can be represented with only an enum tag.
1122 /// data is SimpleValue enum value.1162 /// data is SimpleValue enum value.
1123 simple_value,1163 simple_value,
...@@ -1132,7 +1172,7 @@ pub const Tag = enum(u8) {...@@ -1132,7 +1172,7 @@ pub const Tag = enum(u8) {
1132 /// already contains the optional type corresponding to this payload.1172 /// already contains the optional type corresponding to this payload.
1133 opt_payload,1173 opt_payload,
1134 /// An optional value that is null.1174 /// An optional value that is null.
1135 /// data is Index of the payload type.1175 /// data is Index of the optional type.
1136 opt_null,1176 opt_null,
1137 /// Type: u81177 /// Type: u8
1138 /// data is integer value1178 /// data is integer value
...@@ -1155,18 +1195,18 @@ pub const Tag = enum(u8) {...@@ -1155,18 +1195,18 @@ pub const Tag = enum(u8) {
1155 /// A comptime_int that fits in an i32.1195 /// A comptime_int that fits in an i32.
1156 /// data is integer value bitcasted to u32.1196 /// data is integer value bitcasted to u32.
1157 int_comptime_int_i32,1197 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,
1158 /// A positive integer value.1201 /// A positive integer value.
1159 /// data is a limbs index to Int.1202 /// data is a limbs index to `Int`.
1160 int_positive,1203 int_positive,
1161 /// A negative integer value.1204 /// A negative integer value.
1162 /// data is a limbs index to Int.1205 /// data is a limbs index to `Int`.
1163 int_negative,1206 int_negative,
1164 /// An enum tag identified by a positive integer value.1207 /// An enum tag value.
1165 /// data is a limbs index to Int.1208 /// data is extra index of `Key.EnumTag`.
1166 enum_tag_positive,1209 enum_tag,
1167 /// An enum tag identified by a negative integer value.
1168 /// data is a limbs index to Int.
1169 enum_tag_negative,
1170 /// An f16 value.1210 /// An f16 value.
1171 /// data is float value bitcasted to u16 and zero-extended.1211 /// data is float value bitcasted to u16 and zero-extended.
1172 float_f16,1212 float_f16,
...@@ -1404,6 +1444,11 @@ pub const Int = struct {...@@ -1404,6 +1444,11 @@ pub const Int = struct {
1404 limbs_len: u32,1444 limbs_len: u32,
1405};1445};
14061446
1447pub const IntSmall = struct {
1448 ty: Index,
1449 value: u32,
1450};
1451
1407/// A f64 value, broken up into 2 u32 parts.1452/// A f64 value, broken up into 2 u32 parts.
1408pub const Float64 = struct {1453pub const Float64 = struct {
1409 piece0: u32,1454 piece0: u32,
...@@ -1479,15 +1524,28 @@ pub fn init(ip: *InternPool, gpa: Allocator) !void {...@@ -1479,15 +1524,28 @@ pub fn init(ip: *InternPool, gpa: Allocator) !void {
1479 try ip.items.ensureUnusedCapacity(gpa, static_keys.len);1524 try ip.items.ensureUnusedCapacity(gpa, static_keys.len);
1480 try ip.map.ensureUnusedCapacity(gpa, static_keys.len);1525 try ip.map.ensureUnusedCapacity(gpa, static_keys.len);
1481 try ip.extra.ensureUnusedCapacity(gpa, static_keys.len);1526 try ip.extra.ensureUnusedCapacity(gpa, static_keys.len);
1482 try ip.limbs.ensureUnusedCapacity(gpa, 2);
14831527
1484 // This inserts all the statically-known values into the intern pool in the1528 // This inserts all the statically-known values into the intern pool in the
1485 // order expected.1529 // order expected.
1486 for (static_keys) |key| _ = ip.get(gpa, key) catch unreachable;1530 for (static_keys) |key| _ = ip.get(gpa, key) catch unreachable;
14871531
1488 // Sanity check.1532 if (std.debug.runtime_safety) {
1489 assert(ip.indexToKey(.bool_true).simple_value == .true);1533 // Sanity check.
1490 assert(ip.indexToKey(.bool_false).simple_value == .false);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
1492 assert(ip.items.len == static_keys.len);1550 assert(ip.items.len == static_keys.len);
1493}1551}
...@@ -1634,6 +1692,7 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {...@@ -1634,6 +1692,7 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
1634 .type_enum_explicit => indexToKeyEnum(ip, data, .explicit),1692 .type_enum_explicit => indexToKeyEnum(ip, data, .explicit),
1635 .type_enum_nonexhaustive => indexToKeyEnum(ip, data, .nonexhaustive),1693 .type_enum_nonexhaustive => indexToKeyEnum(ip, data, .nonexhaustive),
16361694
1695 .undef => .{ .undef = @intToEnum(Index, data) },
1637 .opt_null => .{ .opt = .{1696 .opt_null => .{ .opt = .{
1638 .ty = @intToEnum(Index, data),1697 .ty = @intToEnum(Index, data),
1639 .val = .none,1698 .val = .none,
...@@ -1687,8 +1746,13 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {...@@ -1687,8 +1746,13 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
1687 } },1746 } },
1688 .int_positive => indexToKeyBigInt(ip, data, true),1747 .int_positive => indexToKeyBigInt(ip, data, true),
1689 .int_negative => indexToKeyBigInt(ip, data, false),1748 .int_negative => indexToKeyBigInt(ip, data, false),
1690 .enum_tag_positive => @panic("TODO"),1749 .int_small => {
1691 .enum_tag_negative => @panic("TODO"),1750 const info = ip.extraData(IntSmall, data);
1751 return .{ .int = .{
1752 .ty = info.ty,
1753 .storage = .{ .u64 = info.value },
1754 } };
1755 },
1692 .float_f16 => .{ .float = .{1756 .float_f16 => .{ .float = .{
1693 .ty = .f16_type,1757 .ty = .f16_type,
1694 .storage = .{ .f16 = @bitCast(f16, @intCast(u16, data)) },1758 .storage = .{ .f16 = @bitCast(f16, @intCast(u16, data)) },
...@@ -1734,6 +1798,7 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {...@@ -1734,6 +1798,7 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
1734 };1798 };
1735 },1799 },
1736 .union_value => .{ .un = ip.extraData(Key.Union, data) },1800 .union_value => .{ .un = ip.extraData(Key.Union, data) },
1801 .enum_tag => .{ .enum_tag = ip.extraData(Key.EnumTag, data) },
1737 };1802 };
1738}1803}
17391804
...@@ -1896,6 +1961,13 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -1896,6 +1961,13 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
1896 .data = @enumToInt(simple_value),1961 .data = @enumToInt(simple_value),
1897 });1962 });
1898 },1963 },
1964 .undef => |ty| {
1965 assert(ty != .none);
1966 ip.items.appendAssumeCapacity(.{
1967 .tag = .undef,
1968 .data = @enumToInt(ty),
1969 });
1970 },
18991971
1900 .struct_type => |struct_type| {1972 .struct_type => |struct_type| {
1901 ip.items.appendAssumeCapacity(if (struct_type.index.unwrap()) |i| .{1973 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 {...@@ -2112,10 +2184,32 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
2112 }2184 }
2113 switch (int.storage) {2185 switch (int.storage) {
2114 .big_int => |big_int| {2186 .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
2115 const tag: Tag = if (big_int.positive) .int_positive else .int_negative;2198 const tag: Tag = if (big_int.positive) .int_positive else .int_negative;
2116 try addInt(ip, gpa, int.ty, tag, big_int.limbs);2199 try addInt(ip, gpa, int.ty, tag, big_int.limbs);
2117 },2200 },
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
2119 var buf: [2]Limb = undefined;2213 var buf: [2]Limb = undefined;
2120 const big_int = BigIntMutable.init(&buf, x).toConst();2214 const big_int = BigIntMutable.init(&buf, x).toConst();
2121 const tag: Tag = if (big_int.positive) .int_positive else .int_negative;2215 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 {...@@ -2124,6 +2218,16 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
2124 }2218 }
2125 },2219 },
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
2127 .float => |float| {2231 .float => |float| {
2128 switch (float.ty) {2232 switch (float.ty) {
2129 .f16_type => ip.items.appendAssumeCapacity(.{2233 .f16_type => ip.items.appendAssumeCapacity(.{
...@@ -2164,11 +2268,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -2164,11 +2268,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
2164 }2268 }
2165 },2269 },
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
2172 .aggregate => |aggregate| {2271 .aggregate => |aggregate| {
2173 if (aggregate.fields.len == 0) {2272 if (aggregate.fields.len == 0) {
2174 ip.items.appendAssumeCapacity(.{2273 ip.items.appendAssumeCapacity(.{
...@@ -2671,44 +2770,59 @@ pub fn slicePtrType(ip: InternPool, i: Index) Index {...@@ -2671,44 +2770,59 @@ pub fn slicePtrType(ip: InternPool, i: Index) Index {
26712770
2672/// Given an existing value, returns the same value but with the supplied type.2771/// Given an existing value, returns the same value but with the supplied type.
2673/// Only some combinations are allowed:2772/// Only some combinations are allowed:
2674/// * int to int2773/// * int <=> int
2774/// * int <=> enum
2675pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index {2775pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index {
2676 switch (ip.indexToKey(val)) {2776 switch (ip.indexToKey(val)) {
2677 .int => |int| {2777 .int => |int| switch (ip.indexToKey(new_ty)) {
2678 // The key cannot be passed directly to `get`, otherwise in the case of2778 .enum_type => return ip.get(gpa, .{ .enum_tag = .{
2679 // big_int storage, the limbs would be invalidated before they are read.2779 .ty = new_ty,
2680 // Here we pre-reserve the limbs to ensure that the logic in `addInt` will2780 .int = val,
2681 // not use an invalidated limbs pointer.2781 } }),
2682 switch (int.storage) {2782 else => return getCoercedInts(ip, gpa, int, new_ty),
2683 .u64 => |x| return ip.get(gpa, .{ .int = .{2783 },
2684 .ty = new_ty,2784 .enum_tag => |enum_tag| {
2685 .storage = .{ .u64 = x },2785 // Assume new_ty is an integer type.
2686 } }),2786 return getCoercedInts(ip, gpa, ip.indexToKey(enum_tag.int).int, new_ty);
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 }
2707 },2787 },
2708 else => unreachable,2788 else => unreachable,
2709 }2789 }
2710}2790}
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
2712pub fn indexToStruct(ip: *InternPool, val: Index) Module.Struct.OptionalIndex {2826pub fn indexToStruct(ip: *InternPool, val: Index) Module.Struct.OptionalIndex {
2713 const tags = ip.items.items(.tag);2827 const tags = ip.items.items(.tag);
2714 if (val == .none) return .none;2828 if (val == .none) return .none;
...@@ -2805,6 +2919,7 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void {...@@ -2805,6 +2919,7 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void {
2805 .type_union_safety,2919 .type_union_safety,
2806 => @sizeOf(Module.Union) + @sizeOf(Module.Namespace) + @sizeOf(Module.Decl),2920 => @sizeOf(Module.Union) + @sizeOf(Module.Namespace) + @sizeOf(Module.Decl),
28072921
2922 .undef => 0,
2808 .simple_type => 0,2923 .simple_type => 0,
2809 .simple_value => 0,2924 .simple_value => 0,
2810 .ptr_int => @sizeOf(PtrInt),2925 .ptr_int => @sizeOf(PtrInt),
...@@ -2817,15 +2932,15 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void {...@@ -2817,15 +2932,15 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void {
2817 .int_usize => 0,2932 .int_usize => 0,
2818 .int_comptime_int_u32 => 0,2933 .int_comptime_int_u32 => 0,
2819 .int_comptime_int_i32 => 0,2934 .int_comptime_int_i32 => 0,
2935 .int_small => @sizeOf(IntSmall),
28202936
2821 .int_positive,2937 .int_positive,
2822 .int_negative,2938 .int_negative,
2823 .enum_tag_positive,
2824 .enum_tag_negative,
2825 => b: {2939 => b: {
2826 const int = ip.limbData(Int, data);2940 const int = ip.limbData(Int, data);
2827 break :b @sizeOf(Int) + int.limbs_len * 8;2941 break :b @sizeOf(Int) + int.limbs_len * 8;
2828 },2942 },
2943 .enum_tag => @sizeOf(Key.EnumTag),
28292944
2830 .float_f16 => 0,2945 .float_f16 => 0,
2831 .float_f32 => 0,2946 .float_f32 => 0,
...@@ -2958,3 +3073,9 @@ pub fn stringToSlice(ip: InternPool, s: NullTerminatedString) [:0]const u8 {...@@ -2958,3 +3073,9 @@ pub fn stringToSlice(ip: InternPool, s: NullTerminatedString) [:0]const u8 {
2958pub fn typeOf(ip: InternPool, index: Index) Index {3073pub fn typeOf(ip: InternPool, index: Index) Index {
2959 return ip.indexToKey(index).typeOf();3074 return ip.indexToKey(index).typeOf();
2960}3075}
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...@@ -6896,6 +6896,43 @@ pub fn ptrIntValue_ptronly(mod: *Module, ty: Type, x: u64) Allocator.Error!Value
6896 return i.toValue();6896 return i.toValue();
6897}6897}
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
6899pub fn intValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value {6936pub fn intValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value {
6900 if (std.debug.runtime_safety) {6937 if (std.debug.runtime_safety) {
6901 const tag = ty.zigTypeTag(mod);6938 const tag = ty.zigTypeTag(mod);
...@@ -6967,8 +7004,8 @@ pub fn smallestUnsignedInt(mod: *Module, max: u64) Allocator.Error!Type {...@@ -6967,8 +7004,8 @@ pub fn smallestUnsignedInt(mod: *Module, max: u64) Allocator.Error!Type {
6967/// `max`. Asserts that neither value is undef.7004/// `max`. Asserts that neither value is undef.
6968/// TODO: if #3806 is implemented, this becomes trivial7005/// TODO: if #3806 is implemented, this becomes trivial
6969pub fn intFittingRange(mod: *Module, min: Value, max: Value) !Type {7006pub fn intFittingRange(mod: *Module, min: Value, max: Value) !Type {
6970 assert(!min.isUndef());7007 assert(!min.isUndef(mod));
6971 assert(!max.isUndef());7008 assert(!max.isUndef(mod));
69727009
6973 if (std.debug.runtime_safety) {7010 if (std.debug.runtime_safety) {
6974 assert(Value.order(min, max, mod).compare(.lte));7011 assert(Value.order(min, max, mod).compare(.lte));
...@@ -6990,7 +7027,7 @@ pub fn intFittingRange(mod: *Module, min: Value, max: Value) !Type {...@@ -6990,7 +7027,7 @@ pub fn intFittingRange(mod: *Module, min: Value, max: Value) !Type {
6990/// twos-complement integer; otherwise in an unsigned integer.7027/// twos-complement integer; otherwise in an unsigned integer.
6991/// Asserts that `val` is not undef. If `val` is negative, asserts that `sign` is true.7028/// Asserts that `val` is not undef. If `val` is negative, asserts that `sign` is true.
6992pub fn intBitsForValue(mod: *Module, val: Value, sign: bool) u16 {7029pub fn intBitsForValue(mod: *Module, val: Value, sign: bool) u16 {
6993 assert(!val.isUndef());7030 assert(!val.isUndef(mod));
69947031
6995 const key = mod.intern_pool.indexToKey(val.ip_index);7032 const key = mod.intern_pool.indexToKey(val.ip_index);
6996 switch (key.int.storage) {7033 switch (key.int.storage) {
...@@ -7193,3 +7230,7 @@ pub fn fieldSrcLoc(mod: *Module, owner_decl_index: Decl.Index, query: FieldSrcQu...@@ -7193,3 +7230,7 @@ pub fn fieldSrcLoc(mod: *Module, owner_decl_index: Decl.Index, query: FieldSrcQu
7193 return owner_decl.srcLoc(mod);7230 return owner_decl.srcLoc(mod);
7194 }7231 }
7195}7232}
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(...@@ -1904,8 +1904,9 @@ fn resolveDefinedValue(
1904 src: LazySrcLoc,1904 src: LazySrcLoc,
1905 air_ref: Air.Inst.Ref,1905 air_ref: Air.Inst.Ref,
1906) CompileError!?Value {1906) CompileError!?Value {
1907 const mod = sema.mod;
1907 if (try sema.resolveMaybeUndefVal(air_ref)) |val| {1908 if (try sema.resolveMaybeUndefVal(air_ref)) |val| {
1908 if (val.isUndef()) {1909 if (val.isUndef(mod)) {
1909 if (block.is_typeof) return null;1910 if (block.is_typeof) return null;
1910 return sema.failWithUseOfUndef(block, src);1911 return sema.failWithUseOfUndef(block, src);
1911 }1912 }
...@@ -4333,7 +4334,7 @@ fn validateUnionInit(...@@ -4333,7 +4334,7 @@ fn validateUnionInit(
43334334
4334 const tag_ty = union_ty.unionTagTypeHypothetical(mod);4335 const tag_ty = union_ty.unionTagTypeHypothetical(mod);
4335 const enum_field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name, mod).?);4336 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
4338 if (init_val) |val| {4339 if (init_val) |val| {
4339 // Our task is to delete all the `field_ptr` and `store` instructions, and insert4340 // 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...@@ -4832,7 +4833,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
48324833
4833 const elem_ty = operand_ty.elemType2(mod);4834 const elem_ty = operand_ty.elemType2(mod);
4834 if (try sema.resolveMaybeUndefVal(operand)) |val| {4835 if (try sema.resolveMaybeUndefVal(operand)) |val| {
4835 if (val.isUndef()) {4836 if (val.isUndef(mod)) {
4836 return sema.fail(block, src, "cannot dereference undefined value", .{});4837 return sema.fail(block, src, "cannot dereference undefined value", .{});
4837 }4838 }
4838 } else if (!(try sema.validateRunTimeType(elem_ty, false))) {4839 } else if (!(try sema.validateRunTimeType(elem_ty, false))) {
...@@ -6194,15 +6195,16 @@ fn lookupInNamespace(...@@ -6194,15 +6195,16 @@ fn lookupInNamespace(
6194}6195}
61956196
6196fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {6197fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {
6198 const mod = sema.mod;
6197 const func_val = (try sema.resolveMaybeUndefVal(func_inst)) orelse return null;6199 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;
6199 const owner_decl_index = switch (func_val.tag()) {6201 const owner_decl_index = switch (func_val.tag()) {
6200 .extern_fn => func_val.castTag(.extern_fn).?.data.owner_decl,6202 .extern_fn => func_val.castTag(.extern_fn).?.data.owner_decl,
6201 .function => func_val.castTag(.function).?.data.owner_decl,6203 .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,
6203 else => return null,6205 else => return null,
6204 };6206 };
6205 return sema.mod.declPtr(owner_decl_index);6207 return mod.declPtr(owner_decl_index);
6206}6208}
62076209
6208pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {6210pub 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...@@ -8106,7 +8108,7 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
8106 const operand = try sema.coerce(block, Type.anyerror, uncasted_operand, operand_src);8108 const operand = try sema.coerce(block, Type.anyerror, uncasted_operand, operand_src);
81078109
8108 if (try sema.resolveMaybeUndefVal(operand)) |val| {8110 if (try sema.resolveMaybeUndefVal(operand)) |val| {
8109 if (val.isUndef()) {8111 if (val.isUndef(mod)) {
8110 return sema.addConstUndef(Type.err_int);8112 return sema.addConstUndef(Type.err_int);
8111 }8113 }
8112 switch (val.tag()) {8114 switch (val.tag()) {
...@@ -8326,7 +8328,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -8326,7 +8328,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
8326 };8328 };
8327 return sema.failWithOwnedErrorMsg(msg);8329 return sema.failWithOwnedErrorMsg(msg);
8328 }8330 }
8329 if (int_val.isUndef()) {8331 if (int_val.isUndef(mod)) {
8330 return sema.failWithUseOfUndef(block, operand_src);8332 return sema.failWithUseOfUndef(block, operand_src);
8331 }8333 }
8332 if (!(try sema.enumHasInt(dest_ty, int_val))) {8334 if (!(try sema.enumHasInt(dest_ty, int_val))) {
...@@ -11472,7 +11474,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11472,7 +11474,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11472 if (f != null) continue;11474 if (f != null) continue;
11473 cases_len += 1;11475 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));
11476 const item_ref = try sema.addConstant(operand_ty, item_val);11478 const item_ref = try sema.addConstant(operand_ty, item_val);
11477 case_block.inline_case_capture = item_ref;11479 case_block.inline_case_capture = item_ref;
1147811480
...@@ -12208,7 +12210,7 @@ fn zirShl(...@@ -12208,7 +12210,7 @@ fn zirShl(
12208 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(rhs);12210 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(rhs);
1220912211
12210 if (maybe_rhs_val) |rhs_val| {12212 if (maybe_rhs_val) |rhs_val| {
12211 if (rhs_val.isUndef()) {12213 if (rhs_val.isUndef(mod)) {
12212 return sema.addConstUndef(sema.typeOf(lhs));12214 return sema.addConstUndef(sema.typeOf(lhs));
12213 }12215 }
12214 // If rhs is 0, return lhs without doing any calculations.12216 // If rhs is 0, return lhs without doing any calculations.
...@@ -12255,7 +12257,7 @@ fn zirShl(...@@ -12255,7 +12257,7 @@ fn zirShl(
12255 }12257 }
1225612258
12257 const runtime_src = if (maybe_lhs_val) |lhs_val| rs: {12259 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);
12259 const rhs_val = maybe_rhs_val orelse {12261 const rhs_val = maybe_rhs_val orelse {
12260 if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) {12262 if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) {
12261 return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be comptime-known", .{});12263 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(...@@ -12389,7 +12391,7 @@ fn zirShr(
12389 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(rhs);12391 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(rhs);
1239012392
12391 const runtime_src = if (maybe_rhs_val) |rhs_val| rs: {12393 const runtime_src = if (maybe_rhs_val) |rhs_val| rs: {
12392 if (rhs_val.isUndef()) {12394 if (rhs_val.isUndef(mod)) {
12393 return sema.addConstUndef(lhs_ty);12395 return sema.addConstUndef(lhs_ty);
12394 }12396 }
12395 // If rhs is 0, return lhs without doing any calculations.12397 // If rhs is 0, return lhs without doing any calculations.
...@@ -12434,7 +12436,7 @@ fn zirShr(...@@ -12434,7 +12436,7 @@ fn zirShr(
12434 });12436 });
12435 }12437 }
12436 if (maybe_lhs_val) |lhs_val| {12438 if (maybe_lhs_val) |lhs_val| {
12437 if (lhs_val.isUndef()) {12439 if (lhs_val.isUndef(mod)) {
12438 return sema.addConstUndef(lhs_ty);12440 return sema.addConstUndef(lhs_ty);
12439 }12441 }
12440 if (air_tag == .shr_exact) {12442 if (air_tag == .shr_exact) {
...@@ -12578,7 +12580,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -12578,7 +12580,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
12578 }12580 }
1257912581
12580 if (try sema.resolveMaybeUndefVal(operand)) |val| {12582 if (try sema.resolveMaybeUndefVal(operand)) |val| {
12581 if (val.isUndef()) {12583 if (val.isUndef(mod)) {
12582 return sema.addConstUndef(operand_type);12584 return sema.addConstUndef(operand_type);
12583 } else if (operand_type.zigTypeTag(mod) == .Vector) {12585 } else if (operand_type.zigTypeTag(mod) == .Vector) {
12584 const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen(mod));12586 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....@@ -13154,7 +13156,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13154 if (rhs_scalar_ty.isAnyFloat()) {13156 if (rhs_scalar_ty.isAnyFloat()) {
13155 // We handle float negation here to ensure negative zero is represented in the bits.13157 // We handle float negation here to ensure negative zero is represented in the bits.
13156 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {13158 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);
13158 return sema.addConstant(rhs_ty, try rhs_val.floatNeg(rhs_ty, sema.arena, sema.mod));13160 return sema.addConstant(rhs_ty, try rhs_val.floatNeg(rhs_ty, sema.arena, sema.mod));
13159 }13161 }
13160 try sema.requireRuntimeBlock(block, src, null);13162 try sema.requireRuntimeBlock(block, src, null);
...@@ -13297,7 +13299,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -13297,7 +13299,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
13297 switch (scalar_tag) {13299 switch (scalar_tag) {
13298 .Int, .ComptimeInt, .ComptimeFloat => {13300 .Int, .ComptimeInt, .ComptimeFloat => {
13299 if (maybe_lhs_val) |lhs_val| {13301 if (maybe_lhs_val) |lhs_val| {
13300 if (!lhs_val.isUndef()) {13302 if (!lhs_val.isUndef(mod)) {
13301 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13303 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
13302 const scalar_zero = switch (scalar_tag) {13304 const scalar_zero = switch (scalar_tag) {
13303 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),13305 .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...@@ -13312,7 +13314,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
13312 }13314 }
13313 }13315 }
13314 if (maybe_rhs_val) |rhs_val| {13316 if (maybe_rhs_val) |rhs_val| {
13315 if (rhs_val.isUndef()) {13317 if (rhs_val.isUndef(mod)) {
13316 return sema.failWithUseOfUndef(block, rhs_src);13318 return sema.failWithUseOfUndef(block, rhs_src);
13317 }13319 }
13318 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {13320 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
...@@ -13326,7 +13328,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -13326,7 +13328,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1332613328
13327 const runtime_src = rs: {13329 const runtime_src = rs: {
13328 if (maybe_lhs_val) |lhs_val| {13330 if (maybe_lhs_val) |lhs_val| {
13329 if (lhs_val.isUndef()) {13331 if (lhs_val.isUndef(mod)) {
13330 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {13332 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {
13331 if (maybe_rhs_val) |rhs_val| {13333 if (maybe_rhs_val) |rhs_val| {
13332 if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) {13334 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...@@ -13434,7 +13436,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13434 // If the lhs is undefined, compile error because there is a possible13436 // If the lhs is undefined, compile error because there is a possible
13435 // value for which the division would result in a remainder.13437 // value for which the division would result in a remainder.
13436 if (maybe_lhs_val) |lhs_val| {13438 if (maybe_lhs_val) |lhs_val| {
13437 if (lhs_val.isUndef()) {13439 if (lhs_val.isUndef(mod)) {
13438 return sema.failWithUseOfUndef(block, rhs_src);13440 return sema.failWithUseOfUndef(block, rhs_src);
13439 } else {13441 } else {
13440 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13442 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
...@@ -13451,7 +13453,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13451,7 +13453,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13451 }13453 }
13452 }13454 }
13453 if (maybe_rhs_val) |rhs_val| {13455 if (maybe_rhs_val) |rhs_val| {
13454 if (rhs_val.isUndef()) {13456 if (rhs_val.isUndef(mod)) {
13455 return sema.failWithUseOfUndef(block, rhs_src);13457 return sema.failWithUseOfUndef(block, rhs_src);
13456 }13458 }
13457 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {13459 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
...@@ -13611,7 +13613,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13611,7 +13613,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13611 // value (zero) for which the division would be illegal behavior.13613 // value (zero) for which the division would be illegal behavior.
13612 // If the lhs is undefined, result is undefined.13614 // If the lhs is undefined, result is undefined.
13613 if (maybe_lhs_val) |lhs_val| {13615 if (maybe_lhs_val) |lhs_val| {
13614 if (!lhs_val.isUndef()) {13616 if (!lhs_val.isUndef(mod)) {
13615 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13617 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
13616 const scalar_zero = switch (scalar_tag) {13618 const scalar_zero = switch (scalar_tag) {
13617 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),13619 .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...@@ -13626,7 +13628,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13626 }13628 }
13627 }13629 }
13628 if (maybe_rhs_val) |rhs_val| {13630 if (maybe_rhs_val) |rhs_val| {
13629 if (rhs_val.isUndef()) {13631 if (rhs_val.isUndef(mod)) {
13630 return sema.failWithUseOfUndef(block, rhs_src);13632 return sema.failWithUseOfUndef(block, rhs_src);
13631 }13633 }
13632 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {13634 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
...@@ -13635,7 +13637,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13635,7 +13637,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13635 // TODO: if the RHS is one, return the LHS directly13637 // TODO: if the RHS is one, return the LHS directly
13636 }13638 }
13637 if (maybe_lhs_val) |lhs_val| {13639 if (maybe_lhs_val) |lhs_val| {
13638 if (lhs_val.isUndef()) {13640 if (lhs_val.isUndef(mod)) {
13639 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {13641 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {
13640 if (maybe_rhs_val) |rhs_val| {13642 if (maybe_rhs_val) |rhs_val| {
13641 if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) {13643 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...@@ -13732,7 +13734,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13732 // value (zero) for which the division would be illegal behavior.13734 // value (zero) for which the division would be illegal behavior.
13733 // If the lhs is undefined, result is undefined.13735 // If the lhs is undefined, result is undefined.
13734 if (maybe_lhs_val) |lhs_val| {13736 if (maybe_lhs_val) |lhs_val| {
13735 if (!lhs_val.isUndef()) {13737 if (!lhs_val.isUndef(mod)) {
13736 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13738 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
13737 const scalar_zero = switch (scalar_tag) {13739 const scalar_zero = switch (scalar_tag) {
13738 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),13740 .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...@@ -13747,7 +13749,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13747 }13749 }
13748 }13750 }
13749 if (maybe_rhs_val) |rhs_val| {13751 if (maybe_rhs_val) |rhs_val| {
13750 if (rhs_val.isUndef()) {13752 if (rhs_val.isUndef(mod)) {
13751 return sema.failWithUseOfUndef(block, rhs_src);13753 return sema.failWithUseOfUndef(block, rhs_src);
13752 }13754 }
13753 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {13755 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
...@@ -13755,7 +13757,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13755,7 +13757,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13755 }13757 }
13756 }13758 }
13757 if (maybe_lhs_val) |lhs_val| {13759 if (maybe_lhs_val) |lhs_val| {
13758 if (lhs_val.isUndef()) {13760 if (lhs_val.isUndef(mod)) {
13759 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {13761 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {
13760 if (maybe_rhs_val) |rhs_val| {13762 if (maybe_rhs_val) |rhs_val| {
13761 if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) {13763 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....@@ -13977,7 +13979,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13977 // then emit a compile error saying you have to pick one.13979 // then emit a compile error saying you have to pick one.
13978 if (is_int) {13980 if (is_int) {
13979 if (maybe_lhs_val) |lhs_val| {13981 if (maybe_lhs_val) |lhs_val| {
13980 if (lhs_val.isUndef()) {13982 if (lhs_val.isUndef(mod)) {
13981 return sema.failWithUseOfUndef(block, lhs_src);13983 return sema.failWithUseOfUndef(block, lhs_src);
13982 }13984 }
13983 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13985 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
...@@ -13995,7 +13997,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13995,7 +13997,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13995 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);13997 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
13996 }13998 }
13997 if (maybe_rhs_val) |rhs_val| {13999 if (maybe_rhs_val) |rhs_val| {
13998 if (rhs_val.isUndef()) {14000 if (rhs_val.isUndef(mod)) {
13999 return sema.failWithUseOfUndef(block, rhs_src);14001 return sema.failWithUseOfUndef(block, rhs_src);
14000 }14002 }
14001 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {14003 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
...@@ -14024,7 +14026,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14024,7 +14026,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
14024 }14026 }
14025 // float operands14027 // float operands
14026 if (maybe_rhs_val) |rhs_val| {14028 if (maybe_rhs_val) |rhs_val| {
14027 if (rhs_val.isUndef()) {14029 if (rhs_val.isUndef(mod)) {
14028 return sema.failWithUseOfUndef(block, rhs_src);14030 return sema.failWithUseOfUndef(block, rhs_src);
14029 }14031 }
14030 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {14032 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
...@@ -14034,7 +14036,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14034,7 +14036,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
14034 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);14036 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);
14035 }14037 }
14036 if (maybe_lhs_val) |lhs_val| {14038 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))) {
14038 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);14040 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
14039 }14041 }
14040 return sema.addConstant(14042 return sema.addConstant(
...@@ -14155,12 +14157,12 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -14155,12 +14157,12 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
14155 // If the lhs is undefined, result is undefined.14157 // If the lhs is undefined, result is undefined.
14156 if (is_int) {14158 if (is_int) {
14157 if (maybe_lhs_val) |lhs_val| {14159 if (maybe_lhs_val) |lhs_val| {
14158 if (lhs_val.isUndef()) {14160 if (lhs_val.isUndef(mod)) {
14159 return sema.failWithUseOfUndef(block, lhs_src);14161 return sema.failWithUseOfUndef(block, lhs_src);
14160 }14162 }
14161 }14163 }
14162 if (maybe_rhs_val) |rhs_val| {14164 if (maybe_rhs_val) |rhs_val| {
14163 if (rhs_val.isUndef()) {14165 if (rhs_val.isUndef(mod)) {
14164 return sema.failWithUseOfUndef(block, rhs_src);14166 return sema.failWithUseOfUndef(block, rhs_src);
14165 }14167 }
14166 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {14168 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
...@@ -14179,7 +14181,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -14179,7 +14181,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
14179 }14181 }
14180 // float operands14182 // float operands
14181 if (maybe_rhs_val) |rhs_val| {14183 if (maybe_rhs_val) |rhs_val| {
14182 if (rhs_val.isUndef()) {14184 if (rhs_val.isUndef(mod)) {
14183 return sema.failWithUseOfUndef(block, rhs_src);14185 return sema.failWithUseOfUndef(block, rhs_src);
14184 }14186 }
14185 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {14187 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
...@@ -14187,7 +14189,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -14187,7 +14189,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
14187 }14189 }
14188 }14190 }
14189 if (maybe_lhs_val) |lhs_val| {14191 if (maybe_lhs_val) |lhs_val| {
14190 if (lhs_val.isUndef()) {14192 if (lhs_val.isUndef(mod)) {
14191 return sema.addConstUndef(resolved_type);14193 return sema.addConstUndef(resolved_type);
14192 }14194 }
14193 if (maybe_rhs_val) |rhs_val| {14195 if (maybe_rhs_val) |rhs_val| {
...@@ -14257,12 +14259,12 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -14257,12 +14259,12 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
14257 // If the lhs is undefined, result is undefined.14259 // If the lhs is undefined, result is undefined.
14258 if (is_int) {14260 if (is_int) {
14259 if (maybe_lhs_val) |lhs_val| {14261 if (maybe_lhs_val) |lhs_val| {
14260 if (lhs_val.isUndef()) {14262 if (lhs_val.isUndef(mod)) {
14261 return sema.failWithUseOfUndef(block, lhs_src);14263 return sema.failWithUseOfUndef(block, lhs_src);
14262 }14264 }
14263 }14265 }
14264 if (maybe_rhs_val) |rhs_val| {14266 if (maybe_rhs_val) |rhs_val| {
14265 if (rhs_val.isUndef()) {14267 if (rhs_val.isUndef(mod)) {
14266 return sema.failWithUseOfUndef(block, rhs_src);14268 return sema.failWithUseOfUndef(block, rhs_src);
14267 }14269 }
14268 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {14270 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
...@@ -14281,7 +14283,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -14281,7 +14283,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
14281 }14283 }
14282 // float operands14284 // float operands
14283 if (maybe_rhs_val) |rhs_val| {14285 if (maybe_rhs_val) |rhs_val| {
14284 if (rhs_val.isUndef()) {14286 if (rhs_val.isUndef(mod)) {
14285 return sema.failWithUseOfUndef(block, rhs_src);14287 return sema.failWithUseOfUndef(block, rhs_src);
14286 }14288 }
14287 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {14289 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
...@@ -14289,7 +14291,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -14289,7 +14291,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
14289 }14291 }
14290 }14292 }
14291 if (maybe_lhs_val) |lhs_val| {14293 if (maybe_lhs_val) |lhs_val| {
14292 if (lhs_val.isUndef()) {14294 if (lhs_val.isUndef(mod)) {
14293 return sema.addConstUndef(resolved_type);14295 return sema.addConstUndef(resolved_type);
14294 }14296 }
14295 if (maybe_rhs_val) |rhs_val| {14297 if (maybe_rhs_val) |rhs_val| {
...@@ -14372,18 +14374,18 @@ fn zirOverflowArithmetic(...@@ -14372,18 +14374,18 @@ fn zirOverflowArithmetic(
14372 // to the result, even if it is undefined..14374 // to the result, even if it is undefined..
14373 // Otherwise, if either of the argument is undefined, undefined is returned.14375 // Otherwise, if either of the argument is undefined, undefined is returned.
14374 if (maybe_lhs_val) |lhs_val| {14376 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))) {
14376 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = rhs };14378 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = rhs };
14377 }14379 }
14378 }14380 }
14379 if (maybe_rhs_val) |rhs_val| {14381 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))) {
14381 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };14383 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };
14382 }14384 }
14383 }14385 }
14384 if (maybe_lhs_val) |lhs_val| {14386 if (maybe_lhs_val) |lhs_val| {
14385 if (maybe_rhs_val) |rhs_val| {14387 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)) {
14387 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };14389 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
14388 }14390 }
1438914391
...@@ -14396,12 +14398,12 @@ fn zirOverflowArithmetic(...@@ -14396,12 +14398,12 @@ fn zirOverflowArithmetic(
14396 // If the rhs is zero, then the result is lhs and no overflow occured.14398 // If the rhs is zero, then the result is lhs and no overflow occured.
14397 // Otherwise, if either result is undefined, both results are undefined.14399 // Otherwise, if either result is undefined, both results are undefined.
14398 if (maybe_rhs_val) |rhs_val| {14400 if (maybe_rhs_val) |rhs_val| {
14399 if (rhs_val.isUndef()) {14401 if (rhs_val.isUndef(mod)) {
14400 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };14402 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
14401 } else if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14403 } else if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
14402 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };14404 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };
14403 } else if (maybe_lhs_val) |lhs_val| {14405 } else if (maybe_lhs_val) |lhs_val| {
14404 if (lhs_val.isUndef()) {14406 if (lhs_val.isUndef(mod)) {
14405 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };14407 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
14406 }14408 }
1440714409
...@@ -14416,7 +14418,7 @@ fn zirOverflowArithmetic(...@@ -14416,7 +14418,7 @@ fn zirOverflowArithmetic(
14416 // Otherwise, if either of the arguments is undefined, both results are undefined.14418 // Otherwise, if either of the arguments is undefined, both results are undefined.
14417 const scalar_one = try mod.intValue(dest_ty.scalarType(mod), 1);14419 const scalar_one = try mod.intValue(dest_ty.scalarType(mod), 1);
14418 if (maybe_lhs_val) |lhs_val| {14420 if (maybe_lhs_val) |lhs_val| {
14419 if (!lhs_val.isUndef()) {14421 if (!lhs_val.isUndef(mod)) {
14420 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14422 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
14421 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };14423 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };
14422 } else if (try sema.compareAll(lhs_val, .eq, try maybeRepeated(sema, dest_ty, scalar_one), dest_ty)) {14424 } else if (try sema.compareAll(lhs_val, .eq, try maybeRepeated(sema, dest_ty, scalar_one), dest_ty)) {
...@@ -14426,7 +14428,7 @@ fn zirOverflowArithmetic(...@@ -14426,7 +14428,7 @@ fn zirOverflowArithmetic(
14426 }14428 }
1442714429
14428 if (maybe_rhs_val) |rhs_val| {14430 if (maybe_rhs_val) |rhs_val| {
14429 if (!rhs_val.isUndef()) {14431 if (!rhs_val.isUndef(mod)) {
14430 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14432 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
14431 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = rhs };14433 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = rhs };
14432 } else if (try sema.compareAll(rhs_val, .eq, try maybeRepeated(sema, dest_ty, scalar_one), dest_ty)) {14434 } else if (try sema.compareAll(rhs_val, .eq, try maybeRepeated(sema, dest_ty, scalar_one), dest_ty)) {
...@@ -14437,7 +14439,7 @@ fn zirOverflowArithmetic(...@@ -14437,7 +14439,7 @@ fn zirOverflowArithmetic(
1443714439
14438 if (maybe_lhs_val) |lhs_val| {14440 if (maybe_lhs_val) |lhs_val| {
14439 if (maybe_rhs_val) |rhs_val| {14441 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)) {
14441 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };14443 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
14442 }14444 }
1444314445
...@@ -14451,18 +14453,18 @@ fn zirOverflowArithmetic(...@@ -14451,18 +14453,18 @@ fn zirOverflowArithmetic(
14451 // If rhs is zero, the result is lhs (even if undefined) and no overflow occurred.14453 // If rhs is zero, the result is lhs (even if undefined) and no overflow occurred.
14452 // Oterhwise if either of the arguments is undefined, both results are undefined.14454 // Oterhwise if either of the arguments is undefined, both results are undefined.
14453 if (maybe_lhs_val) |lhs_val| {14455 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))) {
14455 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };14457 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };
14456 }14458 }
14457 }14459 }
14458 if (maybe_rhs_val) |rhs_val| {14460 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))) {
14460 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };14462 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };
14461 }14463 }
14462 }14464 }
14463 if (maybe_lhs_val) |lhs_val| {14465 if (maybe_lhs_val) |lhs_val| {
14464 if (maybe_rhs_val) |rhs_val| {14466 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)) {
14466 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };14468 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
14467 }14469 }
1446814470
...@@ -14606,12 +14608,12 @@ fn analyzeArithmetic(...@@ -14606,12 +14608,12 @@ fn analyzeArithmetic(
14606 // overflow (max_int), causing illegal behavior.14608 // overflow (max_int), causing illegal behavior.
14607 // For floats: either operand being undef makes the result undef.14609 // For floats: either operand being undef makes the result undef.
14608 if (maybe_lhs_val) |lhs_val| {14610 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))) {
14610 return casted_rhs;14612 return casted_rhs;
14611 }14613 }
14612 }14614 }
14613 if (maybe_rhs_val) |rhs_val| {14615 if (maybe_rhs_val) |rhs_val| {
14614 if (rhs_val.isUndef()) {14616 if (rhs_val.isUndef(mod)) {
14615 if (is_int) {14617 if (is_int) {
14616 return sema.failWithUseOfUndef(block, rhs_src);14618 return sema.failWithUseOfUndef(block, rhs_src);
14617 } else {14619 } else {
...@@ -14624,7 +14626,7 @@ fn analyzeArithmetic(...@@ -14624,7 +14626,7 @@ fn analyzeArithmetic(
14624 }14626 }
14625 const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .add_optimized else .add;14627 const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .add_optimized else .add;
14626 if (maybe_lhs_val) |lhs_val| {14628 if (maybe_lhs_val) |lhs_val| {
14627 if (lhs_val.isUndef()) {14629 if (lhs_val.isUndef(mod)) {
14628 if (is_int) {14630 if (is_int) {
14629 return sema.failWithUseOfUndef(block, lhs_src);14631 return sema.failWithUseOfUndef(block, lhs_src);
14630 } else {14632 } else {
...@@ -14653,13 +14655,13 @@ fn analyzeArithmetic(...@@ -14653,13 +14655,13 @@ fn analyzeArithmetic(
14653 // If either of the operands are zero, the other operand is returned.14655 // If either of the operands are zero, the other operand is returned.
14654 // If either of the operands are undefined, the result is undefined.14656 // If either of the operands are undefined, the result is undefined.
14655 if (maybe_lhs_val) |lhs_val| {14657 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))) {
14657 return casted_rhs;14659 return casted_rhs;
14658 }14660 }
14659 }14661 }
14660 const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .addwrap_optimized else .addwrap;14662 const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .addwrap_optimized else .addwrap;
14661 if (maybe_rhs_val) |rhs_val| {14663 if (maybe_rhs_val) |rhs_val| {
14662 if (rhs_val.isUndef()) {14664 if (rhs_val.isUndef(mod)) {
14663 return sema.addConstUndef(resolved_type);14665 return sema.addConstUndef(resolved_type);
14664 }14666 }
14665 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14667 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
...@@ -14678,12 +14680,12 @@ fn analyzeArithmetic(...@@ -14678,12 +14680,12 @@ fn analyzeArithmetic(
14678 // If either of the operands are zero, then the other operand is returned.14680 // If either of the operands are zero, then the other operand is returned.
14679 // If either of the operands are undefined, the result is undefined.14681 // If either of the operands are undefined, the result is undefined.
14680 if (maybe_lhs_val) |lhs_val| {14682 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))) {
14682 return casted_rhs;14684 return casted_rhs;
14683 }14685 }
14684 }14686 }
14685 if (maybe_rhs_val) |rhs_val| {14687 if (maybe_rhs_val) |rhs_val| {
14686 if (rhs_val.isUndef()) {14688 if (rhs_val.isUndef(mod)) {
14687 return sema.addConstUndef(resolved_type);14689 return sema.addConstUndef(resolved_type);
14688 }14690 }
14689 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14691 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
...@@ -14708,7 +14710,7 @@ fn analyzeArithmetic(...@@ -14708,7 +14710,7 @@ fn analyzeArithmetic(
14708 // overflow, causing illegal behavior.14710 // overflow, causing illegal behavior.
14709 // For floats: either operand being undef makes the result undef.14711 // For floats: either operand being undef makes the result undef.
14710 if (maybe_rhs_val) |rhs_val| {14712 if (maybe_rhs_val) |rhs_val| {
14711 if (rhs_val.isUndef()) {14713 if (rhs_val.isUndef(mod)) {
14712 if (is_int) {14714 if (is_int) {
14713 return sema.failWithUseOfUndef(block, rhs_src);14715 return sema.failWithUseOfUndef(block, rhs_src);
14714 } else {14716 } else {
...@@ -14721,7 +14723,7 @@ fn analyzeArithmetic(...@@ -14721,7 +14723,7 @@ fn analyzeArithmetic(
14721 }14723 }
14722 const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .sub_optimized else .sub;14724 const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .sub_optimized else .sub;
14723 if (maybe_lhs_val) |lhs_val| {14725 if (maybe_lhs_val) |lhs_val| {
14724 if (lhs_val.isUndef()) {14726 if (lhs_val.isUndef(mod)) {
14725 if (is_int) {14727 if (is_int) {
14726 return sema.failWithUseOfUndef(block, lhs_src);14728 return sema.failWithUseOfUndef(block, lhs_src);
14727 } else {14729 } else {
...@@ -14750,7 +14752,7 @@ fn analyzeArithmetic(...@@ -14750,7 +14752,7 @@ fn analyzeArithmetic(
14750 // If the RHS is zero, then the other operand is returned, even if it is undefined.14752 // If the RHS is zero, then the other operand is returned, even if it is undefined.
14751 // If either of the operands are undefined, the result is undefined.14753 // If either of the operands are undefined, the result is undefined.
14752 if (maybe_rhs_val) |rhs_val| {14754 if (maybe_rhs_val) |rhs_val| {
14753 if (rhs_val.isUndef()) {14755 if (rhs_val.isUndef(mod)) {
14754 return sema.addConstUndef(resolved_type);14756 return sema.addConstUndef(resolved_type);
14755 }14757 }
14756 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14758 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
...@@ -14759,7 +14761,7 @@ fn analyzeArithmetic(...@@ -14759,7 +14761,7 @@ fn analyzeArithmetic(
14759 }14761 }
14760 const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .subwrap_optimized else .subwrap;14762 const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .subwrap_optimized else .subwrap;
14761 if (maybe_lhs_val) |lhs_val| {14763 if (maybe_lhs_val) |lhs_val| {
14762 if (lhs_val.isUndef()) {14764 if (lhs_val.isUndef(mod)) {
14763 return sema.addConstUndef(resolved_type);14765 return sema.addConstUndef(resolved_type);
14764 }14766 }
14765 if (maybe_rhs_val) |rhs_val| {14767 if (maybe_rhs_val) |rhs_val| {
...@@ -14775,7 +14777,7 @@ fn analyzeArithmetic(...@@ -14775,7 +14777,7 @@ fn analyzeArithmetic(
14775 // If the RHS is zero, result is LHS.14777 // If the RHS is zero, result is LHS.
14776 // If either of the operands are undefined, result is undefined.14778 // If either of the operands are undefined, result is undefined.
14777 if (maybe_rhs_val) |rhs_val| {14779 if (maybe_rhs_val) |rhs_val| {
14778 if (rhs_val.isUndef()) {14780 if (rhs_val.isUndef(mod)) {
14779 return sema.addConstUndef(resolved_type);14781 return sema.addConstUndef(resolved_type);
14780 }14782 }
14781 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14783 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
...@@ -14783,7 +14785,7 @@ fn analyzeArithmetic(...@@ -14783,7 +14785,7 @@ fn analyzeArithmetic(
14783 }14785 }
14784 }14786 }
14785 if (maybe_lhs_val) |lhs_val| {14787 if (maybe_lhs_val) |lhs_val| {
14786 if (lhs_val.isUndef()) {14788 if (lhs_val.isUndef(mod)) {
14787 return sema.addConstUndef(resolved_type);14789 return sema.addConstUndef(resolved_type);
14788 }14790 }
14789 if (maybe_rhs_val) |rhs_val| {14791 if (maybe_rhs_val) |rhs_val| {
...@@ -14814,7 +14816,7 @@ fn analyzeArithmetic(...@@ -14814,7 +14816,7 @@ fn analyzeArithmetic(
14814 else => unreachable,14816 else => unreachable,
14815 };14817 };
14816 if (maybe_lhs_val) |lhs_val| {14818 if (maybe_lhs_val) |lhs_val| {
14817 if (!lhs_val.isUndef()) {14819 if (!lhs_val.isUndef(mod)) {
14818 if (lhs_val.isNan(mod)) {14820 if (lhs_val.isNan(mod)) {
14819 return sema.addConstant(resolved_type, lhs_val);14821 return sema.addConstant(resolved_type, lhs_val);
14820 }14822 }
...@@ -14844,7 +14846,7 @@ fn analyzeArithmetic(...@@ -14844,7 +14846,7 @@ fn analyzeArithmetic(
14844 }14846 }
14845 const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .mul_optimized else .mul;14847 const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .mul_optimized else .mul;
14846 if (maybe_rhs_val) |rhs_val| {14848 if (maybe_rhs_val) |rhs_val| {
14847 if (rhs_val.isUndef()) {14849 if (rhs_val.isUndef(mod)) {
14848 if (is_int) {14850 if (is_int) {
14849 return sema.failWithUseOfUndef(block, rhs_src);14851 return sema.failWithUseOfUndef(block, rhs_src);
14850 } else {14852 } else {
...@@ -14874,7 +14876,7 @@ fn analyzeArithmetic(...@@ -14874,7 +14876,7 @@ fn analyzeArithmetic(
14874 return casted_lhs;14876 return casted_lhs;
14875 }14877 }
14876 if (maybe_lhs_val) |lhs_val| {14878 if (maybe_lhs_val) |lhs_val| {
14877 if (lhs_val.isUndef()) {14879 if (lhs_val.isUndef(mod)) {
14878 if (is_int) {14880 if (is_int) {
14879 return sema.failWithUseOfUndef(block, lhs_src);14881 return sema.failWithUseOfUndef(block, lhs_src);
14880 } else {14882 } else {
...@@ -14908,7 +14910,7 @@ fn analyzeArithmetic(...@@ -14908,7 +14910,7 @@ fn analyzeArithmetic(
14908 else => unreachable,14910 else => unreachable,
14909 };14911 };
14910 if (maybe_lhs_val) |lhs_val| {14912 if (maybe_lhs_val) |lhs_val| {
14911 if (!lhs_val.isUndef()) {14913 if (!lhs_val.isUndef(mod)) {
14912 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14914 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
14913 const zero_val = if (is_vector) b: {14915 const zero_val = if (is_vector) b: {
14914 break :b try Value.Tag.repeated.create(sema.arena, scalar_zero);14916 break :b try Value.Tag.repeated.create(sema.arena, scalar_zero);
...@@ -14922,7 +14924,7 @@ fn analyzeArithmetic(...@@ -14922,7 +14924,7 @@ fn analyzeArithmetic(
14922 }14924 }
14923 const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .mulwrap_optimized else .mulwrap;14925 const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .mulwrap_optimized else .mulwrap;
14924 if (maybe_rhs_val) |rhs_val| {14926 if (maybe_rhs_val) |rhs_val| {
14925 if (rhs_val.isUndef()) {14927 if (rhs_val.isUndef(mod)) {
14926 return sema.addConstUndef(resolved_type);14928 return sema.addConstUndef(resolved_type);
14927 }14929 }
14928 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14930 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
...@@ -14935,7 +14937,7 @@ fn analyzeArithmetic(...@@ -14935,7 +14937,7 @@ fn analyzeArithmetic(
14935 return casted_lhs;14937 return casted_lhs;
14936 }14938 }
14937 if (maybe_lhs_val) |lhs_val| {14939 if (maybe_lhs_val) |lhs_val| {
14938 if (lhs_val.isUndef()) {14940 if (lhs_val.isUndef(mod)) {
14939 return sema.addConstUndef(resolved_type);14941 return sema.addConstUndef(resolved_type);
14940 }14942 }
14941 return sema.addConstant(14943 return sema.addConstant(
...@@ -14956,7 +14958,7 @@ fn analyzeArithmetic(...@@ -14956,7 +14958,7 @@ fn analyzeArithmetic(
14956 else => unreachable,14958 else => unreachable,
14957 };14959 };
14958 if (maybe_lhs_val) |lhs_val| {14960 if (maybe_lhs_val) |lhs_val| {
14959 if (!lhs_val.isUndef()) {14961 if (!lhs_val.isUndef(mod)) {
14960 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14962 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
14961 const zero_val = if (is_vector) b: {14963 const zero_val = if (is_vector) b: {
14962 break :b try Value.Tag.repeated.create(sema.arena, scalar_zero);14964 break :b try Value.Tag.repeated.create(sema.arena, scalar_zero);
...@@ -14969,7 +14971,7 @@ fn analyzeArithmetic(...@@ -14969,7 +14971,7 @@ fn analyzeArithmetic(
14969 }14971 }
14970 }14972 }
14971 if (maybe_rhs_val) |rhs_val| {14973 if (maybe_rhs_val) |rhs_val| {
14972 if (rhs_val.isUndef()) {14974 if (rhs_val.isUndef(mod)) {
14973 return sema.addConstUndef(resolved_type);14975 return sema.addConstUndef(resolved_type);
14974 }14976 }
14975 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14977 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
...@@ -14982,7 +14984,7 @@ fn analyzeArithmetic(...@@ -14982,7 +14984,7 @@ fn analyzeArithmetic(
14982 return casted_lhs;14984 return casted_lhs;
14983 }14985 }
14984 if (maybe_lhs_val) |lhs_val| {14986 if (maybe_lhs_val) |lhs_val| {
14985 if (lhs_val.isUndef()) {14987 if (lhs_val.isUndef(mod)) {
14986 return sema.addConstUndef(resolved_type);14988 return sema.addConstUndef(resolved_type);
14987 }14989 }
1498814990
...@@ -15100,7 +15102,7 @@ fn analyzePtrArithmetic(...@@ -15100,7 +15102,7 @@ fn analyzePtrArithmetic(
15100 const runtime_src = rs: {15102 const runtime_src = rs: {
15101 if (opt_ptr_val) |ptr_val| {15103 if (opt_ptr_val) |ptr_val| {
15102 if (opt_off_val) |offset_val| {15104 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
15105 const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt(mod));15107 const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt(mod));
15106 if (offset_int == 0) return ptr;15108 if (offset_int == 0) return ptr;
...@@ -15363,7 +15365,7 @@ fn zirCmpEq(...@@ -15363,7 +15365,7 @@ fn zirCmpEq(
15363 const runtime_src: LazySrcLoc = src: {15365 const runtime_src: LazySrcLoc = src: {
15364 if (try sema.resolveMaybeUndefVal(lhs)) |lval| {15366 if (try sema.resolveMaybeUndefVal(lhs)) |lval| {
15365 if (try sema.resolveMaybeUndefVal(rhs)) |rval| {15367 if (try sema.resolveMaybeUndefVal(rhs)) |rval| {
15366 if (lval.isUndef() or rval.isUndef()) {15368 if (lval.isUndef(mod) or rval.isUndef(mod)) {
15367 return sema.addConstUndef(Type.bool);15369 return sema.addConstUndef(Type.bool);
15368 }15370 }
15369 // TODO optimisation opportunity: evaluate if mem.eql is faster with the names,15371 // TODO optimisation opportunity: evaluate if mem.eql is faster with the names,
...@@ -15425,7 +15427,7 @@ fn analyzeCmpUnionTag(...@@ -15425,7 +15427,7 @@ fn analyzeCmpUnionTag(
15425 const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src);15427 const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src);
1542615428
15427 if (try sema.resolveMaybeUndefVal(coerced_tag)) |enum_val| {15429 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);
15429 const field_ty = union_ty.unionFieldType(enum_val, sema.mod);15431 const field_ty = union_ty.unionFieldType(enum_val, sema.mod);
15430 if (field_ty.zigTypeTag(mod) == .NoReturn) {15432 if (field_ty.zigTypeTag(mod) == .NoReturn) {
15431 return Air.Inst.Ref.bool_false;15433 return Air.Inst.Ref.bool_false;
...@@ -15527,9 +15529,9 @@ fn cmpSelf(...@@ -15527,9 +15529,9 @@ fn cmpSelf(
15527 const resolved_type = sema.typeOf(casted_lhs);15529 const resolved_type = sema.typeOf(casted_lhs);
15528 const runtime_src: LazySrcLoc = src: {15530 const runtime_src: LazySrcLoc = src: {
15529 if (try sema.resolveMaybeUndefVal(casted_lhs)) |lhs_val| {15531 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);
15531 if (try sema.resolveMaybeUndefVal(casted_rhs)) |rhs_val| {15533 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
15534 if (resolved_type.zigTypeTag(mod) == .Vector) {15536 if (resolved_type.zigTypeTag(mod) == .Vector) {
15535 const result_ty = try mod.vectorType(.{15537 const result_ty = try mod.vectorType(.{
...@@ -15557,7 +15559,7 @@ fn cmpSelf(...@@ -15557,7 +15559,7 @@ fn cmpSelf(
15557 // bool eq/neq more efficiently.15559 // bool eq/neq more efficiently.
15558 if (resolved_type.zigTypeTag(mod) == .Bool) {15560 if (resolved_type.zigTypeTag(mod) == .Bool) {
15559 if (try sema.resolveMaybeUndefVal(casted_rhs)) |rhs_val| {15561 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);
15561 return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(mod), lhs_src);15563 return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(mod), lhs_src);
15562 }15564 }
15563 }15565 }
...@@ -15892,68 +15894,69 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15892,68 +15894,69 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15892 const src = inst_data.src();15894 const src = inst_data.src();
15893 const ty = try sema.resolveType(block, src, inst_data.operand);15895 const ty = try sema.resolveType(block, src, inst_data.operand);
15894 const type_info_ty = try sema.getBuiltinType("Type");15896 const type_info_ty = try sema.getBuiltinType("Type");
15897 const type_info_tag_ty = type_info_ty.unionTagType(mod).?;
1589515898
15896 switch (ty.zigTypeTag(mod)) {15899 switch (ty.zigTypeTag(mod)) {
15897 .Type => return sema.addConstant(15900 .Type => return sema.addConstant(
15898 type_info_ty,15901 type_info_ty,
15899 try Value.Tag.@"union".create(sema.arena, .{15902 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)),
15901 .val = Value.void,15904 .val = Value.void,
15902 }),15905 }),
15903 ),15906 ),
15904 .Void => return sema.addConstant(15907 .Void => return sema.addConstant(
15905 type_info_ty,15908 type_info_ty,
15906 try Value.Tag.@"union".create(sema.arena, .{15909 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)),
15908 .val = Value.void,15911 .val = Value.void,
15909 }),15912 }),
15910 ),15913 ),
15911 .Bool => return sema.addConstant(15914 .Bool => return sema.addConstant(
15912 type_info_ty,15915 type_info_ty,
15913 try Value.Tag.@"union".create(sema.arena, .{15916 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)),
15915 .val = Value.void,15918 .val = Value.void,
15916 }),15919 }),
15917 ),15920 ),
15918 .NoReturn => return sema.addConstant(15921 .NoReturn => return sema.addConstant(
15919 type_info_ty,15922 type_info_ty,
15920 try Value.Tag.@"union".create(sema.arena, .{15923 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)),
15922 .val = Value.void,15925 .val = Value.void,
15923 }),15926 }),
15924 ),15927 ),
15925 .ComptimeFloat => return sema.addConstant(15928 .ComptimeFloat => return sema.addConstant(
15926 type_info_ty,15929 type_info_ty,
15927 try Value.Tag.@"union".create(sema.arena, .{15930 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)),
15929 .val = Value.void,15932 .val = Value.void,
15930 }),15933 }),
15931 ),15934 ),
15932 .ComptimeInt => return sema.addConstant(15935 .ComptimeInt => return sema.addConstant(
15933 type_info_ty,15936 type_info_ty,
15934 try Value.Tag.@"union".create(sema.arena, .{15937 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)),
15936 .val = Value.void,15939 .val = Value.void,
15937 }),15940 }),
15938 ),15941 ),
15939 .Undefined => return sema.addConstant(15942 .Undefined => return sema.addConstant(
15940 type_info_ty,15943 type_info_ty,
15941 try Value.Tag.@"union".create(sema.arena, .{15944 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)),
15943 .val = Value.void,15946 .val = Value.void,
15944 }),15947 }),
15945 ),15948 ),
15946 .Null => return sema.addConstant(15949 .Null => return sema.addConstant(
15947 type_info_ty,15950 type_info_ty,
15948 try Value.Tag.@"union".create(sema.arena, .{15951 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)),
15950 .val = Value.void,15953 .val = Value.void,
15951 }),15954 }),
15952 ),15955 ),
15953 .EnumLiteral => return sema.addConstant(15956 .EnumLiteral => return sema.addConstant(
15954 type_info_ty,15957 type_info_ty,
15955 try Value.Tag.@"union".create(sema.arena, .{15958 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)),
15957 .val = Value.void,15960 .val = Value.void,
15958 }),15961 }),
15959 ),15962 ),
...@@ -16040,10 +16043,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16040,10 +16043,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16040 else16043 else
16041 Value.null;16044 Value.null;
1604216045
16046 const callconv_ty = try sema.getBuiltinType("CallingConvention");
16047
16043 const field_values = try sema.arena.create([6]Value);16048 const field_values = try sema.arena.create([6]Value);
16044 field_values.* = .{16049 field_values.* = .{
16045 // calling_convention: CallingConvention,16050 // 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)),
16047 // alignment: comptime_int,16052 // alignment: comptime_int,
16048 try mod.intValue(Type.comptime_int, ty.abiAlignment(mod)),16053 try mod.intValue(Type.comptime_int, ty.abiAlignment(mod)),
16049 // is_generic: bool,16054 // is_generic: bool,
...@@ -16059,26 +16064,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16059,26 +16064,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16059 return sema.addConstant(16064 return sema.addConstant(
16060 type_info_ty,16065 type_info_ty,
16061 try Value.Tag.@"union".create(sema.arena, .{16066 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)),
16063 .val = try Value.Tag.aggregate.create(sema.arena, field_values),16068 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
16064 }),16069 }),
16065 );16070 );
16066 },16071 },
16067 .Int => {16072 .Int => {
16073 const signedness_ty = try sema.getBuiltinType("Signedness");
16068 const info = ty.intInfo(mod);16074 const info = ty.intInfo(mod);
16069 const field_values = try sema.arena.alloc(Value, 2);16075 const field_values = try sema.arena.alloc(Value, 2);
16070 // signedness: Signedness,16076 // signedness: Signedness,
16071 field_values[0] = try Value.Tag.enum_field_index.create(16077 field_values[0] = try mod.enumValueFieldIndex(signedness_ty, @enumToInt(info.signedness));
16072 sema.arena,
16073 @enumToInt(info.signedness),
16074 );
16075 // bits: u16,16078 // bits: u16,
16076 field_values[1] = try mod.intValue(Type.u16, info.bits);16079 field_values[1] = try mod.intValue(Type.u16, info.bits);
1607716080
16078 return sema.addConstant(16081 return sema.addConstant(
16079 type_info_ty,16082 type_info_ty,
16080 try Value.Tag.@"union".create(sema.arena, .{16083 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)),
16082 .val = try Value.Tag.aggregate.create(sema.arena, field_values),16085 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
16083 }),16086 }),
16084 );16087 );
...@@ -16091,7 +16094,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16091,7 +16094,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16091 return sema.addConstant(16094 return sema.addConstant(
16092 type_info_ty,16095 type_info_ty,
16093 try Value.Tag.@"union".create(sema.arena, .{16096 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)),
16095 .val = try Value.Tag.aggregate.create(sema.arena, field_values),16098 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
16096 }),16099 }),
16097 );16100 );
...@@ -16103,10 +16106,13 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16103,10 +16106,13 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16103 else16106 else
16104 try info.pointee_type.lazyAbiAlignment(mod, sema.arena);16107 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
16106 const field_values = try sema.arena.create([8]Value);16112 const field_values = try sema.arena.create([8]Value);
16107 field_values.* = .{16113 field_values.* = .{
16108 // size: Size,16114 // 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)),
16110 // is_const: bool,16116 // is_const: bool,
16111 Value.makeBool(!info.mutable),16117 Value.makeBool(!info.mutable),
16112 // is_volatile: bool,16118 // is_volatile: bool,
...@@ -16114,7 +16120,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16114,7 +16120,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16114 // alignment: comptime_int,16120 // alignment: comptime_int,
16115 alignment,16121 alignment,
16116 // address_space: AddressSpace16122 // 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")),
16118 // child: type,16124 // child: type,
16119 try Value.Tag.ty.create(sema.arena, info.pointee_type),16125 try Value.Tag.ty.create(sema.arena, info.pointee_type),
16120 // is_allowzero: bool,16126 // is_allowzero: bool,
...@@ -16126,7 +16132,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16126,7 +16132,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16126 return sema.addConstant(16132 return sema.addConstant(
16127 type_info_ty,16133 type_info_ty,
16128 try Value.Tag.@"union".create(sema.arena, .{16134 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)),
16130 .val = try Value.Tag.aggregate.create(sema.arena, field_values),16136 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
16131 }),16137 }),
16132 );16138 );
...@@ -16144,7 +16150,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16144,7 +16150,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16144 return sema.addConstant(16150 return sema.addConstant(
16145 type_info_ty,16151 type_info_ty,
16146 try Value.Tag.@"union".create(sema.arena, .{16152 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)),
16148 .val = try Value.Tag.aggregate.create(sema.arena, field_values),16154 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
16149 }),16155 }),
16150 );16156 );
...@@ -16160,7 +16166,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16160,7 +16166,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16160 return sema.addConstant(16166 return sema.addConstant(
16161 type_info_ty,16167 type_info_ty,
16162 try Value.Tag.@"union".create(sema.arena, .{16168 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)),
16164 .val = try Value.Tag.aggregate.create(sema.arena, field_values),16170 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
16165 }),16171 }),
16166 );16172 );
...@@ -16173,7 +16179,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16173,7 +16179,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16173 return sema.addConstant(16179 return sema.addConstant(
16174 type_info_ty,16180 type_info_ty,
16175 try Value.Tag.@"union".create(sema.arena, .{16181 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)),
16177 .val = try Value.Tag.aggregate.create(sema.arena, field_values),16183 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
16178 }),16184 }),
16179 );16185 );
...@@ -16263,7 +16269,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16263,7 +16269,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16263 return sema.addConstant(16269 return sema.addConstant(
16264 type_info_ty,16270 type_info_ty,
16265 try Value.Tag.@"union".create(sema.arena, .{16271 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)),
16267 .val = errors_val,16273 .val = errors_val,
16268 }),16274 }),
16269 );16275 );
...@@ -16278,7 +16284,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16278,7 +16284,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16278 return sema.addConstant(16284 return sema.addConstant(
16279 type_info_ty,16285 type_info_ty,
16280 try Value.Tag.@"union".create(sema.arena, .{16286 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)),
16282 .val = try Value.Tag.aggregate.create(sema.arena, field_values),16288 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
16283 }),16289 }),
16284 );16290 );
...@@ -16365,7 +16371,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16365,7 +16371,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16365 return sema.addConstant(16371 return sema.addConstant(
16366 type_info_ty,16372 type_info_ty,
16367 try Value.Tag.@"union".create(sema.arena, .{16373 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)),
16369 .val = try Value.Tag.aggregate.create(sema.arena, field_values),16375 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
16370 }),16376 }),
16371 );16377 );
...@@ -16454,13 +16460,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16454,13 +16460,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16454 break :v try Value.Tag.opt_payload.create(sema.arena, ty_val);16460 break :v try Value.Tag.opt_payload.create(sema.arena, ty_val);
16455 } else Value.null;16461 } else Value.null;
1645616462
16463 const container_layout_ty = try sema.getBuiltinType("TmpContainerLayoutAlias");
16464
16457 const field_values = try sema.arena.create([4]Value);16465 const field_values = try sema.arena.create([4]Value);
16458 field_values.* = .{16466 field_values.* = .{
16459 // layout: ContainerLayout,16467 // layout: ContainerLayout,
16460 try Value.Tag.enum_field_index.create(16468 try mod.enumValueFieldIndex(container_layout_ty, @enumToInt(layout)),
16461 sema.arena,
16462 @enumToInt(layout),
16463 ),
1646416469
16465 // tag_type: ?type,16470 // tag_type: ?type,
16466 enum_tag_ty_val,16471 enum_tag_ty_val,
...@@ -16473,7 +16478,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16473,7 +16478,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16473 return sema.addConstant(16478 return sema.addConstant(
16474 type_info_ty,16479 type_info_ty,
16475 try Value.Tag.@"union".create(sema.arena, .{16480 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)),
16477 .val = try Value.Tag.aggregate.create(sema.arena, field_values),16482 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
16478 }),16483 }),
16479 );16484 );
...@@ -16625,13 +16630,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16625,13 +16630,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16625 }16630 }
16626 };16631 };
1662716632
16633 const container_layout_ty = try sema.getBuiltinType("TmpContainerLayoutAlias");
16634
16628 const field_values = try sema.arena.create([5]Value);16635 const field_values = try sema.arena.create([5]Value);
16629 field_values.* = .{16636 field_values.* = .{
16630 // layout: ContainerLayout,16637 // layout: ContainerLayout,
16631 try Value.Tag.enum_field_index.create(16638 try mod.enumValueFieldIndex(container_layout_ty, @enumToInt(layout)),
16632 sema.arena,
16633 @enumToInt(layout),
16634 ),
16635 // backing_integer: ?type,16639 // backing_integer: ?type,
16636 backing_integer_val,16640 backing_integer_val,
16637 // fields: []const StructField,16641 // fields: []const StructField,
...@@ -16645,7 +16649,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16645,7 +16649,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16645 return sema.addConstant(16649 return sema.addConstant(
16646 type_info_ty,16650 type_info_ty,
16647 try Value.Tag.@"union".create(sema.arena, .{16651 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)),
16649 .val = try Value.Tag.aggregate.create(sema.arena, field_values),16653 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
16650 }),16654 }),
16651 );16655 );
...@@ -16665,7 +16669,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16665,7 +16669,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16665 return sema.addConstant(16669 return sema.addConstant(
16666 type_info_ty,16670 type_info_ty,
16667 try Value.Tag.@"union".create(sema.arena, .{16671 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)),
16669 .val = try Value.Tag.aggregate.create(sema.arena, field_values),16673 .val = try Value.Tag.aggregate.create(sema.arena, field_values),
16670 }),16674 }),
16671 );16675 );
...@@ -16912,7 +16916,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -16912,7 +16916,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1691216916
16913 const operand = try sema.coerce(block, Type.bool, uncasted_operand, operand_src);16917 const operand = try sema.coerce(block, Type.bool, uncasted_operand, operand_src);
16914 if (try sema.resolveMaybeUndefVal(operand)) |val| {16918 if (try sema.resolveMaybeUndefVal(operand)) |val| {
16915 return if (val.isUndef())16919 return if (val.isUndef(mod))
16916 sema.addConstUndef(Type.bool)16920 sema.addConstUndef(Type.bool)
16917 else if (val.toBool(mod))16921 else if (val.toBool(mod))
16918 Air.Inst.Ref.bool_false16922 Air.Inst.Ref.bool_false
...@@ -17879,7 +17883,7 @@ fn unionInit(...@@ -17879,7 +17883,7 @@ fn unionInit(
17879 if (try sema.resolveMaybeUndefVal(init)) |init_val| {17883 if (try sema.resolveMaybeUndefVal(init)) |init_val| {
17880 const tag_ty = union_ty.unionTagTypeHypothetical(mod);17884 const tag_ty = union_ty.unionTagTypeHypothetical(mod);
17881 const enum_field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name, mod).?);17885 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);
17883 return sema.addConstant(union_ty, try Value.Tag.@"union".create(sema.arena, .{17887 return sema.addConstant(union_ty, try Value.Tag.@"union".create(sema.arena, .{
17884 .tag = tag_val,17888 .tag = tag_val,
17885 .val = init_val,17889 .val = init_val,
...@@ -17980,7 +17984,7 @@ fn zirStructInit(...@@ -17980,7 +17984,7 @@ fn zirStructInit(
17980 const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src);17984 const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src);
17981 const tag_ty = resolved_ty.unionTagTypeHypothetical(mod);17985 const tag_ty = resolved_ty.unionTagTypeHypothetical(mod);
17982 const enum_field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name, mod).?);17986 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
17985 const init_inst = try sema.resolveInst(item.data.init);17989 const init_inst = try sema.resolveInst(item.data.init);
17986 if (try sema.resolveMaybeUndefVal(init_inst)) |val| {17990 if (try sema.resolveMaybeUndefVal(init_inst)) |val| {
...@@ -18614,7 +18618,7 @@ fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -18614,7 +18618,7 @@ fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
18614 const inst_data = sema.code.instructions.items(.data)[inst].un_node;18618 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
18615 const operand = try sema.resolveInst(inst_data.operand);18619 const operand = try sema.resolveInst(inst_data.operand);
18616 if (try sema.resolveMaybeUndefVal(operand)) |val| {18620 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);
18618 if (val.toBool(mod)) return sema.addConstant(Type.u1, try mod.intValue(Type.u1, 1));18622 if (val.toBool(mod)) return sema.addConstant(Type.u1, try mod.intValue(Type.u1, 1));
18619 return sema.addConstant(Type.u1, try mod.intValue(Type.u1, 0));18623 return sema.addConstant(Type.u1, try mod.intValue(Type.u1, 0));
18620 }18624 }
...@@ -18673,7 +18677,7 @@ fn zirUnaryMath(...@@ -18673,7 +18677,7 @@ fn zirUnaryMath(
18673 .child = scalar_ty.ip_index,18677 .child = scalar_ty.ip_index,
18674 });18678 });
18675 if (try sema.resolveMaybeUndefVal(operand)) |val| {18679 if (try sema.resolveMaybeUndefVal(operand)) |val| {
18676 if (val.isUndef())18680 if (val.isUndef(mod))
18677 return sema.addConstUndef(result_ty);18681 return sema.addConstUndef(result_ty);
1867818682
18679 const elems = try sema.arena.alloc(Value, vec_len);18683 const elems = try sema.arena.alloc(Value, vec_len);
...@@ -18692,7 +18696,7 @@ fn zirUnaryMath(...@@ -18692,7 +18696,7 @@ fn zirUnaryMath(
18692 },18696 },
18693 .ComptimeFloat, .Float => {18697 .ComptimeFloat, .Float => {
18694 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {18698 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
18695 if (operand_val.isUndef())18699 if (operand_val.isUndef(mod))
18696 return sema.addConstUndef(operand_ty);18700 return sema.addConstUndef(operand_ty);
18697 const result_val = try eval(operand_val, operand_ty, sema.arena, sema.mod);18701 const result_val = try eval(operand_val, operand_ty, sema.arena, sema.mod);
18698 return sema.addConstant(operand_ty, result_val);18702 return sema.addConstant(operand_ty, result_val);
...@@ -18809,7 +18813,7 @@ fn zirReify(...@@ -18809,7 +18813,7 @@ fn zirReify(
18809 const signedness_val = struct_val[0];18813 const signedness_val = struct_val[0];
18810 const bits_val = struct_val[1];18814 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);
18813 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));18817 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
18814 const ty = try mod.intType(signedness, bits);18818 const ty = try mod.intType(signedness, bits);
18815 return sema.addType(ty);18819 return sema.addType(ty);
...@@ -18874,7 +18878,7 @@ fn zirReify(...@@ -18874,7 +18878,7 @@ fn zirReify(
18874 break :t elem_ty;18878 break :t elem_ty;
18875 };18879 };
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
18879 var actual_sentinel: ?Value = null;18883 var actual_sentinel: ?Value = null;
18880 if (!sentinel_val.isNull(mod)) {18884 if (!sentinel_val.isNull(mod)) {
...@@ -18927,7 +18931,7 @@ fn zirReify(...@@ -18927,7 +18931,7 @@ fn zirReify(
18927 .mutable = !is_const_val.toBool(mod),18931 .mutable = !is_const_val.toBool(mod),
18928 .@"volatile" = is_volatile_val.toBool(mod),18932 .@"volatile" = is_volatile_val.toBool(mod),
18929 .@"align" = abi_align,18933 .@"align" = abi_align,
18930 .@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace),18934 .@"addrspace" = mod.toEnum(std.builtin.AddressSpace, address_space_val),
18931 .pointee_type = try elem_ty.copy(sema.arena),18935 .pointee_type = try elem_ty.copy(sema.arena),
18932 .@"allowzero" = is_allowzero_val.toBool(mod),18936 .@"allowzero" = is_allowzero_val.toBool(mod),
18933 .sentinel = actual_sentinel,18937 .sentinel = actual_sentinel,
...@@ -19033,7 +19037,7 @@ fn zirReify(...@@ -19033,7 +19037,7 @@ fn zirReify(
19033 const is_tuple_val = struct_val[4];19037 const is_tuple_val = struct_val[4];
19034 assert(struct_val.len == 5);19038 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
19038 // Decls19042 // Decls
19039 if (decls_val.sliceLen(mod) > 0) {19043 if (decls_val.sliceLen(mod) > 0) {
...@@ -19208,7 +19212,7 @@ fn zirReify(...@@ -19208,7 +19212,7 @@ fn zirReify(
19208 if (decls_val.sliceLen(mod) > 0) {19212 if (decls_val.sliceLen(mod) > 0) {
19209 return sema.fail(block, src, "reified unions must have no decls", .{});19213 return sema.fail(block, src, "reified unions must have no decls", .{});
19210 }19214 }
19211 const layout = layout_val.toEnum(std.builtin.Type.ContainerLayout);19215 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
1921219216
19213 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);19217 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
19214 errdefer new_decl_arena.deinit();19218 errdefer new_decl_arena.deinit();
...@@ -19309,7 +19313,7 @@ fn zirReify(...@@ -19309,7 +19313,7 @@ fn zirReify(
19309 }19313 }
1931019314
19311 if (explicit_enum_info) |tag_info| {19315 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 {
19313 const msg = msg: {19317 const msg = msg: {
19314 const msg = try sema.errMsg(block, src, "no field named '{s}' in enum '{}'", .{ field_name, union_obj.tag_ty.fmt(mod) });19318 const msg = try sema.errMsg(block, src, "no field named '{s}' in enum '{}'", .{ field_name, union_obj.tag_ty.fmt(mod) });
19315 errdefer msg.destroy(gpa);19319 errdefer msg.destroy(gpa);
...@@ -19402,7 +19406,7 @@ fn zirReify(...@@ -19402,7 +19406,7 @@ fn zirReify(
19402 const struct_val: []const Value = union_val.val.castTag(.aggregate).?.data;19406 const struct_val: []const Value = union_val.val.castTag(.aggregate).?.data;
19403 // TODO use reflection instead of magic numbers here19407 // TODO use reflection instead of magic numbers here
19404 // calling_convention: CallingConvention,19408 // calling_convention: CallingConvention,
19405 const cc = struct_val[0].toEnum(std.builtin.CallingConvention);19409 const cc = mod.toEnum(std.builtin.CallingConvention, struct_val[0]);
19406 // alignment: comptime_int,19410 // alignment: comptime_int,
19407 const alignment_val = struct_val[1];19411 const alignment_val = struct_val[1];
19408 // is_generic: bool,19412 // is_generic: bool,
...@@ -20180,7 +20184,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -20180,7 +20184,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
20180 }20184 }
2018120185
20182 if (try sema.resolveMaybeUndefVal(ptr)) |operand_val| {20186 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)) {
20184 return sema.failWithUseOfUndef(block, operand_src);20188 return sema.failWithUseOfUndef(block, operand_src);
20185 }20189 }
20186 if (!dest_ty.ptrAllowsZero(mod) and operand_val.isNull(mod)) {20190 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...@@ -20315,7 +20319,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
20315 }20319 }
2031620320
20317 if (try sema.resolveMaybeUndefValIntable(operand)) |val| {20321 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);
20319 if (!is_vector) {20323 if (!is_vector) {
20320 return sema.addConstant(20324 return sema.addConstant(
20321 dest_ty,20325 dest_ty,
...@@ -20419,7 +20423,7 @@ fn zirBitCount(...@@ -20419,7 +20423,7 @@ fn zirBitCount(
20419 .child = result_scalar_ty.ip_index,20423 .child = result_scalar_ty.ip_index,
20420 });20424 });
20421 if (try sema.resolveMaybeUndefVal(operand)) |val| {20425 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
20424 const elems = try sema.arena.alloc(Value, vec_len);20428 const elems = try sema.arena.alloc(Value, vec_len);
20425 const scalar_ty = operand_ty.scalarType(mod);20429 const scalar_ty = operand_ty.scalarType(mod);
...@@ -20439,7 +20443,7 @@ fn zirBitCount(...@@ -20439,7 +20443,7 @@ fn zirBitCount(
20439 },20443 },
20440 .Int => {20444 .Int => {
20441 if (try sema.resolveMaybeUndefVal(operand)) |val| {20445 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);
20443 try sema.resolveLazyValue(val);20447 try sema.resolveLazyValue(val);
20444 return sema.addIntUnsigned(result_scalar_ty, comptimeOp(val, operand_ty, mod));20448 return sema.addIntUnsigned(result_scalar_ty, comptimeOp(val, operand_ty, mod));
20445 } else {20449 } else {
...@@ -20476,7 +20480,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -20476,7 +20480,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
20476 switch (operand_ty.zigTypeTag(mod)) {20480 switch (operand_ty.zigTypeTag(mod)) {
20477 .Int => {20481 .Int => {
20478 const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {20482 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);
20480 const result_val = try val.byteSwap(operand_ty, mod, sema.arena);20484 const result_val = try val.byteSwap(operand_ty, mod, sema.arena);
20481 return sema.addConstant(operand_ty, result_val);20485 return sema.addConstant(operand_ty, result_val);
20482 } else operand_src;20486 } else operand_src;
...@@ -20486,7 +20490,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -20486,7 +20490,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
20486 },20490 },
20487 .Vector => {20491 .Vector => {
20488 const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {20492 const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {
20489 if (val.isUndef())20493 if (val.isUndef(mod))
20490 return sema.addConstUndef(operand_ty);20494 return sema.addConstUndef(operand_ty);
2049120495
20492 const vec_len = operand_ty.vectorLen(mod);20496 const vec_len = operand_ty.vectorLen(mod);
...@@ -20524,7 +20528,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -20524,7 +20528,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
20524 switch (operand_ty.zigTypeTag(mod)) {20528 switch (operand_ty.zigTypeTag(mod)) {
20525 .Int => {20529 .Int => {
20526 const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {20530 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);
20528 const result_val = try val.bitReverse(operand_ty, mod, sema.arena);20532 const result_val = try val.bitReverse(operand_ty, mod, sema.arena);
20529 return sema.addConstant(operand_ty, result_val);20533 return sema.addConstant(operand_ty, result_val);
20530 } else operand_src;20534 } else operand_src;
...@@ -20534,7 +20538,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -20534,7 +20538,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
20534 },20538 },
20535 .Vector => {20539 .Vector => {
20536 const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {20540 const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {
20537 if (val.isUndef())20541 if (val.isUndef(mod))
20538 return sema.addConstUndef(operand_ty);20542 return sema.addConstUndef(operand_ty);
2053920543
20540 const vec_len = operand_ty.vectorLen(mod);20544 const vec_len = operand_ty.vectorLen(mod);
...@@ -21072,7 +21076,7 @@ fn resolveExportOptions(...@@ -21072,7 +21076,7 @@ fn resolveExportOptions(
2107221076
21073 const linkage_operand = try sema.fieldVal(block, src, options, "linkage", linkage_src);21077 const linkage_operand = try sema.fieldVal(block, src, options, "linkage", linkage_src);
21074 const linkage_val = try sema.resolveConstValue(block, linkage_src, linkage_operand, "linkage of exported value must be comptime-known");21078 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
21077 const section_operand = try sema.fieldVal(block, src, options, "section", section_src);21081 const section_operand = try sema.fieldVal(block, src, options, "section", section_src);
21078 const section_opt_val = try sema.resolveConstValue(block, section_src, section_operand, "linksection of exported value must be comptime-known");21082 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(...@@ -21084,7 +21088,7 @@ fn resolveExportOptions(
2108421088
21085 const visibility_operand = try sema.fieldVal(block, src, options, "visibility", visibility_src);21089 const visibility_operand = try sema.fieldVal(block, src, options, "visibility", visibility_src);
21086 const visibility_val = try sema.resolveConstValue(block, visibility_src, visibility_operand, "visibility of exported value must be comptime-known");21090 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
21089 if (name.len < 1) {21093 if (name.len < 1) {
21090 return sema.fail(block, name_src, "exported symbol name cannot be empty", .{});21094 return sema.fail(block, name_src, "exported symbol name cannot be empty", .{});
...@@ -21112,11 +21116,12 @@ fn resolveBuiltinEnum(...@@ -21112,11 +21116,12 @@ fn resolveBuiltinEnum(
21112 comptime name: []const u8,21116 comptime name: []const u8,
21113 reason: []const u8,21117 reason: []const u8,
21114) CompileError!@field(std.builtin, name) {21118) CompileError!@field(std.builtin, name) {
21119 const mod = sema.mod;
21115 const ty = try sema.getBuiltinType(name);21120 const ty = try sema.getBuiltinType(name);
21116 const air_ref = try sema.resolveInst(zir_ref);21121 const air_ref = try sema.resolveInst(zir_ref);
21117 const coerced = try sema.coerce(block, ty, air_ref, src);21122 const coerced = try sema.coerce(block, ty, air_ref, src);
21118 const val = try sema.resolveConstValue(block, src, coerced, reason);21123 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);
21120}21125}
2112121126
21122fn resolveAtomicOrder(21127fn resolveAtomicOrder(
...@@ -21198,7 +21203,7 @@ fn zirCmpxchg(...@@ -21198,7 +21203,7 @@ fn zirCmpxchg(
21198 const runtime_src = if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| rs: {21203 const runtime_src = if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| rs: {
21199 if (try sema.resolveMaybeUndefVal(expected_value)) |expected_val| {21204 if (try sema.resolveMaybeUndefVal(expected_value)) |expected_val| {
21200 if (try sema.resolveMaybeUndefVal(new_value)) |new_val| {21205 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)) {
21202 // TODO: this should probably cause the memory stored at the pointer21207 // TODO: this should probably cause the memory stored at the pointer
21203 // to become undef as well21208 // to become undef as well
21204 return sema.addConstUndef(result_ty);21209 return sema.addConstUndef(result_ty);
...@@ -21248,7 +21253,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -21248,7 +21253,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
21248 .child = scalar_ty.ip_index,21253 .child = scalar_ty.ip_index,
21249 });21254 });
21250 if (try sema.resolveMaybeUndefVal(scalar)) |scalar_val| {21255 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
21253 return sema.addConstant(21258 return sema.addConstant(
21254 vector_ty,21259 vector_ty,
...@@ -21300,7 +21305,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -21300,7 +21305,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
21300 }21305 }
2130121306
21302 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {21307 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
21305 var accum: Value = try operand_val.elemValue(mod, 0);21310 var accum: Value = try operand_val.elemValue(mod, 0);
21306 var i: u32 = 1;21311 var i: u32 = 1;
...@@ -21420,7 +21425,7 @@ fn analyzeShuffle(...@@ -21420,7 +21425,7 @@ fn analyzeShuffle(
21420 var i: usize = 0;21425 var i: usize = 0;
21421 while (i < mask_len) : (i += 1) {21426 while (i < mask_len) : (i += 1) {
21422 const elem = try mask.elemValue(sema.mod, i);21427 const elem = try mask.elemValue(sema.mod, i);
21423 if (elem.isUndef()) continue;21428 if (elem.isUndef(mod)) continue;
21424 const int = elem.toSignedInt(mod);21429 const int = elem.toSignedInt(mod);
21425 var unsigned: u32 = undefined;21430 var unsigned: u32 = undefined;
21426 var chosen: u32 = undefined;21431 var chosen: u32 = undefined;
...@@ -21458,7 +21463,7 @@ fn analyzeShuffle(...@@ -21458,7 +21463,7 @@ fn analyzeShuffle(
21458 i = 0;21463 i = 0;
21459 while (i < mask_len) : (i += 1) {21464 while (i < mask_len) : (i += 1) {
21460 const mask_elem_val = try mask.elemValue(sema.mod, i);21465 const mask_elem_val = try mask.elemValue(sema.mod, i);
21461 if (mask_elem_val.isUndef()) {21466 if (mask_elem_val.isUndef(mod)) {
21462 values[i] = Value.undef;21467 values[i] = Value.undef;
21463 continue;21468 continue;
21464 }21469 }
...@@ -21559,13 +21564,13 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -21559,13 +21564,13 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
21559 const maybe_b = try sema.resolveMaybeUndefVal(b);21564 const maybe_b = try sema.resolveMaybeUndefVal(b);
2156021565
21561 const runtime_src = if (maybe_pred) |pred_val| rs: {21566 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
21564 if (maybe_a) |a_val| {21569 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
21567 if (maybe_b) |b_val| {21572 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
21570 const elems = try sema.gpa.alloc(Value, vec_len);21575 const elems = try sema.gpa.alloc(Value, vec_len);
21571 for (elems, 0..) |*elem, i| {21576 for (elems, 0..) |*elem, i| {
...@@ -21587,16 +21592,16 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -21587,16 +21592,16 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
21587 }21592 }
21588 } else {21593 } else {
21589 if (maybe_b) |b_val| {21594 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);
21591 }21596 }
21592 break :rs a_src;21597 break :rs a_src;
21593 }21598 }
21594 } else rs: {21599 } else rs: {
21595 if (maybe_a) |a_val| {21600 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);
21597 }21602 }
21598 if (maybe_b) |b_val| {21603 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);
21600 }21605 }
21601 break :rs pred_src;21606 break :rs pred_src;
21602 };21607 };
...@@ -21803,10 +21808,10 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -21803,10 +21808,10 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
2180321808
21804 const runtime_src = if (maybe_mulend1) |mulend1_val| rs: {21809 const runtime_src = if (maybe_mulend1) |mulend1_val| rs: {
21805 if (maybe_mulend2) |mulend2_val| {21810 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
21808 if (maybe_addend) |addend_val| {21813 if (maybe_addend) |addend_val| {
21809 if (addend_val.isUndef()) return sema.addConstUndef(ty);21814 if (addend_val.isUndef(mod)) return sema.addConstUndef(ty);
21810 const result_val = try Value.mulAdd(ty, mulend1_val, mulend2_val, addend_val, sema.arena, sema.mod);21815 const result_val = try Value.mulAdd(ty, mulend1_val, mulend2_val, addend_val, sema.arena, sema.mod);
21811 return sema.addConstant(ty, result_val);21816 return sema.addConstant(ty, result_val);
21812 } else {21817 } else {
...@@ -21814,16 +21819,16 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -21814,16 +21819,16 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
21814 }21819 }
21815 } else {21820 } else {
21816 if (maybe_addend) |addend_val| {21821 if (maybe_addend) |addend_val| {
21817 if (addend_val.isUndef()) return sema.addConstUndef(ty);21822 if (addend_val.isUndef(mod)) return sema.addConstUndef(ty);
21818 }21823 }
21819 break :rs mulend2_src;21824 break :rs mulend2_src;
21820 }21825 }
21821 } else rs: {21826 } else rs: {
21822 if (maybe_mulend2) |mulend2_val| {21827 if (maybe_mulend2) |mulend2_val| {
21823 if (mulend2_val.isUndef()) return sema.addConstUndef(ty);21828 if (mulend2_val.isUndef(mod)) return sema.addConstUndef(ty);
21824 }21829 }
21825 if (maybe_addend) |addend_val| {21830 if (maybe_addend) |addend_val| {
21826 if (addend_val.isUndef()) return sema.addConstUndef(ty);21831 if (addend_val.isUndef(mod)) return sema.addConstUndef(ty);
21827 }21832 }
21828 break :rs mulend1_src;21833 break :rs mulend1_src;
21829 };21834 };
...@@ -21859,7 +21864,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -21859,7 +21864,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
21859 const air_ref = try sema.resolveInst(extra.modifier);21864 const air_ref = try sema.resolveInst(extra.modifier);
21860 const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src);21865 const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src);
21861 const modifier_val = try sema.resolveConstValue(block, modifier_src, modifier_ref, "call modifier must be comptime-known");21866 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);
21863 switch (modifier) {21868 switch (modifier) {
21864 // These can be upgraded to comptime or nosuspend calls.21869 // These can be upgraded to comptime or nosuspend calls.
21865 .auto, .never_tail, .no_async => {21870 .auto, .never_tail, .no_async => {
...@@ -22111,8 +22116,8 @@ fn analyzeMinMax(...@@ -22111,8 +22116,8 @@ fn analyzeMinMax(
2211122116
22112 runtime_known.unset(operand_idx);22117 runtime_known.unset(operand_idx);
2211322118
22114 if (cur_val.isUndef()) continue; // result is also undef22119 if (cur_val.isUndef(mod)) continue; // result is also undef
22115 if (operand_val.isUndef()) {22120 if (operand_val.isUndef(mod)) {
22116 cur_minmax = try sema.addConstUndef(simd_op.result_ty);22121 cur_minmax = try sema.addConstUndef(simd_op.result_ty);
22117 continue;22122 continue;
22118 }22123 }
...@@ -22165,7 +22170,7 @@ fn analyzeMinMax(...@@ -22165,7 +22170,7 @@ fn analyzeMinMax(
22165 var cur_max: Value = cur_min;22170 var cur_max: Value = cur_min;
22166 for (1..len) |idx| {22171 for (1..len) |idx| {
22167 const elem_val = try val.elemValue(mod, idx);22172 const elem_val = try val.elemValue(mod, idx);
22168 if (elem_val.isUndef()) break :blk orig_ty; // can't refine undef22173 if (elem_val.isUndef(mod)) break :blk orig_ty; // can't refine undef
22169 if (Value.order(elem_val, cur_min, mod).compare(.lt)) cur_min = elem_val;22174 if (Value.order(elem_val, cur_min, mod).compare(.lt)) cur_min = elem_val;
22170 if (Value.order(elem_val, cur_max, mod).compare(.gt)) cur_max = elem_val;22175 if (Value.order(elem_val, cur_max, mod).compare(.gt)) cur_max = elem_val;
22171 }22176 }
...@@ -22177,7 +22182,7 @@ fn analyzeMinMax(...@@ -22177,7 +22182,7 @@ fn analyzeMinMax(
22177 });22182 });
22178 } else blk: {22183 } else blk: {
22179 if (orig_ty.isAnyFloat()) break :blk orig_ty; // can't refine floats22184 if (orig_ty.isAnyFloat()) break :blk orig_ty; // can't refine floats
22180 if (val.isUndef()) break :blk orig_ty; // can't refine undef22185 if (val.isUndef(mod)) break :blk orig_ty; // can't refine undef
22181 break :blk try mod.intFittingRange(val, val);22186 break :blk try mod.intFittingRange(val, val);
22182 };22187 };
2218322188
...@@ -22205,7 +22210,7 @@ fn analyzeMinMax(...@@ -22205,7 +22210,7 @@ fn analyzeMinMax(
22205 // If the comptime-known part is undef we can avoid emitting actual instructions later22210 // If the comptime-known part is undef we can avoid emitting actual instructions later
22206 const known_undef = if (cur_minmax) |operand| blk: {22211 const known_undef = if (cur_minmax) |operand| blk: {
22207 const val = (try sema.resolveMaybeUndefVal(operand)).?;22212 const val = (try sema.resolveMaybeUndefVal(operand)).?;
22208 break :blk val.isUndef();22213 break :blk val.isUndef(mod);
22209 } else false;22214 } else false;
2221022215
22211 if (cur_minmax == null) {22216 if (cur_minmax == null) {
...@@ -22749,7 +22754,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -22749,7 +22754,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
22749 if (val.isGenericPoison()) {22754 if (val.isGenericPoison()) {
22750 break :blk null;22755 break :blk null;
22751 }22756 }
22752 break :blk val.toEnum(std.builtin.AddressSpace);22757 break :blk mod.toEnum(std.builtin.AddressSpace, val);
22753 } else if (extra.data.bits.has_addrspace_ref) blk: {22758 } else if (extra.data.bits.has_addrspace_ref) blk: {
22754 const addrspace_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);22759 const addrspace_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
22755 extra_index += 1;22760 extra_index += 1;
...@@ -22759,7 +22764,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -22759,7 +22764,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
22759 },22764 },
22760 else => |e| return e,22765 else => |e| return e,
22761 };22766 };
22762 break :blk addrspace_tv.val.toEnum(std.builtin.AddressSpace);22767 break :blk mod.toEnum(std.builtin.AddressSpace, addrspace_tv.val);
22763 } else target_util.defaultAddressSpace(target, .function);22768 } else target_util.defaultAddressSpace(target, .function);
2276422769
22765 const @"linksection": FuncLinkSection = if (extra.data.bits.has_section_body) blk: {22770 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...@@ -22797,7 +22802,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
22797 if (val.isGenericPoison()) {22802 if (val.isGenericPoison()) {
22798 break :blk null;22803 break :blk null;
22799 }22804 }
22800 break :blk val.toEnum(std.builtin.CallingConvention);22805 break :blk mod.toEnum(std.builtin.CallingConvention, val);
22801 } else if (extra.data.bits.has_cc_ref) blk: {22806 } else if (extra.data.bits.has_cc_ref) blk: {
22802 const cc_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);22807 const cc_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
22803 extra_index += 1;22808 extra_index += 1;
...@@ -22807,7 +22812,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -22807,7 +22812,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
22807 },22812 },
22808 else => |e| return e,22813 else => |e| return e,
22809 };22814 };
22810 break :blk cc_tv.val.toEnum(std.builtin.CallingConvention);22815 break :blk mod.toEnum(std.builtin.CallingConvention, cc_tv.val);
22811 } else if (sema.owner_decl.is_exported and has_body)22816 } else if (sema.owner_decl.is_exported and has_body)
22812 .C22817 .C
22813 else22818 else
...@@ -22994,9 +22999,9 @@ fn resolvePrefetchOptions(...@@ -22994,9 +22999,9 @@ fn resolvePrefetchOptions(
22994 const cache_val = try sema.resolveConstValue(block, cache_src, cache, "prefetch cache must be comptime-known");22999 const cache_val = try sema.resolveConstValue(block, cache_src, cache, "prefetch cache must be comptime-known");
2299523000
22996 return std.builtin.PrefetchOptions{23001 return std.builtin.PrefetchOptions{
22997 .rw = rw_val.toEnum(std.builtin.PrefetchOptions.Rw),23002 .rw = mod.toEnum(std.builtin.PrefetchOptions.Rw, rw_val),
22998 .locality = @intCast(u2, locality_val.toUnsignedInt(mod)),23003 .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),
23000 };23005 };
23001}23006}
2300223007
...@@ -23059,7 +23064,7 @@ fn resolveExternOptions(...@@ -23059,7 +23064,7 @@ fn resolveExternOptions(
2305923064
23060 const linkage_ref = try sema.fieldVal(block, src, options, "linkage", linkage_src);23065 const linkage_ref = try sema.fieldVal(block, src, options, "linkage", linkage_src);
23061 const linkage_val = try sema.resolveConstValue(block, linkage_src, linkage_ref, "linkage of the extern symbol must be comptime-known");23066 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
23064 const is_thread_local = try sema.fieldVal(block, src, options, "is_thread_local", thread_local_src);23069 const is_thread_local = try sema.fieldVal(block, src, options, "is_thread_local", thread_local_src);
23065 const is_thread_local_val = try sema.resolveConstValue(block, thread_local_src, is_thread_local, "threadlocality of the extern symbol must be comptime-known");23070 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(...@@ -24140,7 +24145,7 @@ fn fieldVal(
24140 const field_index = @intCast(u32, field_index_usize);24145 const field_index = @intCast(u32, field_index_usize);
24141 return sema.addConstant(24146 return sema.addConstant(
24142 enum_ty,24147 enum_ty,
24143 try Value.Tag.enum_field_index.create(sema.arena, field_index),24148 try mod.enumValueFieldIndex(enum_ty, field_index),
24144 );24149 );
24145 }24150 }
24146 }24151 }
...@@ -24155,8 +24160,8 @@ fn fieldVal(...@@ -24155,8 +24160,8 @@ fn fieldVal(
24155 const field_index_usize = child_type.enumFieldIndex(field_name, mod) orelse24160 const field_index_usize = child_type.enumFieldIndex(field_name, mod) orelse
24156 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);24161 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
24157 const field_index = @intCast(u32, field_index_usize);24162 const field_index = @intCast(u32, field_index_usize);
24158 const enum_val = try Value.Tag.enum_field_index.create(arena, field_index);24163 const enum_val = try mod.enumValueFieldIndex(child_type, field_index);
24159 return sema.addConstant(try child_type.copy(arena), enum_val);24164 return sema.addConstant(child_type, enum_val);
24160 },24165 },
24161 .Struct, .Opaque => {24166 .Struct, .Opaque => {
24162 if (child_type.getNamespaceIndex(mod).unwrap()) |namespace| {24167 if (child_type.getNamespaceIndex(mod).unwrap()) |namespace| {
...@@ -24355,8 +24360,8 @@ fn fieldPtr(...@@ -24355,8 +24360,8 @@ fn fieldPtr(
24355 var anon_decl = try block.startAnonDecl();24360 var anon_decl = try block.startAnonDecl();
24356 defer anon_decl.deinit();24361 defer anon_decl.deinit();
24357 return sema.analyzeDeclRef(try anon_decl.finish(24362 return sema.analyzeDeclRef(try anon_decl.finish(
24358 try enum_ty.copy(anon_decl.arena()),24363 enum_ty,
24359 try Value.Tag.enum_field_index.create(anon_decl.arena(), field_index_u32),24364 try mod.enumValueFieldIndex(enum_ty, field_index_u32),
24360 0, // default alignment24365 0, // default alignment
24361 ));24366 ));
24362 }24367 }
...@@ -24376,8 +24381,8 @@ fn fieldPtr(...@@ -24376,8 +24381,8 @@ fn fieldPtr(
24376 var anon_decl = try block.startAnonDecl();24381 var anon_decl = try block.startAnonDecl();
24377 defer anon_decl.deinit();24382 defer anon_decl.deinit();
24378 return sema.analyzeDeclRef(try anon_decl.finish(24383 return sema.analyzeDeclRef(try anon_decl.finish(
24379 try child_type.copy(anon_decl.arena()),24384 child_type,
24380 try Value.Tag.enum_field_index.create(anon_decl.arena(), field_index_u32),24385 try mod.enumValueFieldIndex(child_type, field_index_u32),
24381 0, // default alignment24386 0, // default alignment
24382 ));24387 ));
24383 },24388 },
...@@ -24850,7 +24855,7 @@ fn structFieldVal(...@@ -24850,7 +24855,7 @@ fn structFieldVal(
24850 }24855 }
2485124856
24852 if (try sema.resolveMaybeUndefVal(struct_byval)) |struct_val| {24857 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);
24854 if ((try sema.typeHasOnePossibleValue(field.ty))) |opv| {24859 if ((try sema.typeHasOnePossibleValue(field.ty))) |opv| {
24855 return sema.addConstant(field.ty, opv);24860 return sema.addConstant(field.ty, opv);
24856 }24861 }
...@@ -24922,7 +24927,7 @@ fn tupleFieldValByIndex(...@@ -24922,7 +24927,7 @@ fn tupleFieldValByIndex(
24922 }24927 }
2492324928
24924 if (try sema.resolveMaybeUndefVal(tuple_byval)) |tuple_val| {24929 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);
24926 if ((try sema.typeHasOnePossibleValue(field_ty))) |opv| {24931 if ((try sema.typeHasOnePossibleValue(field_ty))) |opv| {
24927 return sema.addConstant(field_ty, opv);24932 return sema.addConstant(field_ty, opv);
24928 }24933 }
...@@ -24983,19 +24988,15 @@ fn unionFieldPtr(...@@ -24983,19 +24988,15 @@ fn unionFieldPtr(
24983 .Auto => if (!initializing) {24988 .Auto => if (!initializing) {
24984 const union_val = (try sema.pointerDeref(block, src, union_ptr_val, union_ptr_ty)) orelse24989 const union_val = (try sema.pointerDeref(block, src, union_ptr_val, union_ptr_ty)) orelse
24985 break :ct;24990 break :ct;
24986 if (union_val.isUndef()) {24991 if (union_val.isUndef(mod)) {
24987 return sema.failWithUseOfUndef(block, src);24992 return sema.failWithUseOfUndef(block, src);
24988 }24993 }
24989 const tag_and_val = union_val.castTag(.@"union").?.data;24994 const tag_and_val = union_val.castTag(.@"union").?.data;
24990 var field_tag_buf: Value.Payload.U32 = .{24995 const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);
24991 .base = .{ .tag = .enum_field_index },
24992 .data = enum_field_index,
24993 };
24994 const field_tag = Value.initPayload(&field_tag_buf.base);
24995 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, mod);24996 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, mod);
24996 if (!tag_matches) {24997 if (!tag_matches) {
24997 const msg = msg: {24998 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).?;
24999 const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod);25000 const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod);
25000 const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });25001 const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });
25001 errdefer msg.destroy(sema.gpa);25002 errdefer msg.destroy(sema.gpa);
...@@ -25021,7 +25022,7 @@ fn unionFieldPtr(...@@ -25021,7 +25022,7 @@ fn unionFieldPtr(
25021 if (!initializing and union_obj.layout == .Auto and block.wantSafety() and25022 if (!initializing and union_obj.layout == .Auto and block.wantSafety() and
25022 union_ty.unionTagTypeSafety(mod) != null and union_obj.fields.count() > 1)25023 union_ty.unionTagTypeSafety(mod) != null and union_obj.fields.count() > 1)
25023 {25024 {
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);
25025 const wanted_tag = try sema.addConstant(union_obj.tag_ty, wanted_tag_val);25026 const wanted_tag = try sema.addConstant(union_obj.tag_ty, wanted_tag_val);
25026 // TODO would it be better if get_union_tag supported pointers to unions?25027 // TODO would it be better if get_union_tag supported pointers to unions?
25027 const union_val = try block.addTyOp(.load, union_ty, union_ptr);25028 const union_val = try block.addTyOp(.load, union_ty, union_ptr);
...@@ -25054,14 +25055,10 @@ fn unionFieldVal(...@@ -25054,14 +25055,10 @@ fn unionFieldVal(
25054 const enum_field_index = @intCast(u32, union_obj.tag_ty.enumFieldIndex(field_name, mod).?);25055 const enum_field_index = @intCast(u32, union_obj.tag_ty.enumFieldIndex(field_name, mod).?);
2505525056
25056 if (try sema.resolveMaybeUndefVal(union_byval)) |union_val| {25057 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
25059 const tag_and_val = union_val.castTag(.@"union").?.data;25060 const tag_and_val = union_val.castTag(.@"union").?.data;
25060 var field_tag_buf: Value.Payload.U32 = .{25061 const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);
25061 .base = .{ .tag = .enum_field_index },
25062 .data = enum_field_index,
25063 };
25064 const field_tag = Value.initPayload(&field_tag_buf.base);
25065 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, mod);25062 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, mod);
25066 switch (union_obj.layout) {25063 switch (union_obj.layout) {
25067 .Auto => {25064 .Auto => {
...@@ -25069,7 +25066,7 @@ fn unionFieldVal(...@@ -25069,7 +25066,7 @@ fn unionFieldVal(
25069 return sema.addConstant(field.ty, tag_and_val.val);25066 return sema.addConstant(field.ty, tag_and_val.val);
25070 } else {25067 } else {
25071 const msg = msg: {25068 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).?;
25073 const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod);25070 const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod);
25074 const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });25071 const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });
25075 errdefer msg.destroy(sema.gpa);25072 errdefer msg.destroy(sema.gpa);
...@@ -25096,7 +25093,7 @@ fn unionFieldVal(...@@ -25096,7 +25093,7 @@ fn unionFieldVal(
25096 if (union_obj.layout == .Auto and block.wantSafety() and25093 if (union_obj.layout == .Auto and block.wantSafety() and
25097 union_ty.unionTagTypeSafety(mod) != null and union_obj.fields.count() > 1)25094 union_ty.unionTagTypeSafety(mod) != null and union_obj.fields.count() > 1)
25098 {25095 {
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);
25100 const wanted_tag = try sema.addConstant(union_obj.tag_ty, wanted_tag_val);25097 const wanted_tag = try sema.addConstant(union_obj.tag_ty, wanted_tag_val);
25101 const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_byval);25098 const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_byval);
25102 try sema.panicInactiveUnionField(block, active_tag, wanted_tag);25099 try sema.panicInactiveUnionField(block, active_tag, wanted_tag);
...@@ -25364,7 +25361,7 @@ fn tupleField(...@@ -25364,7 +25361,7 @@ fn tupleField(
25364 }25361 }
2536525362
25366 if (try sema.resolveMaybeUndefVal(tuple)) |tuple_val| {25363 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);
25368 return sema.addConstant(field_ty, try tuple_val.fieldValue(tuple_ty, mod, field_index));25365 return sema.addConstant(field_ty, try tuple_val.fieldValue(tuple_ty, mod, field_index));
25369 }25366 }
2537025367
...@@ -25412,7 +25409,7 @@ fn elemValArray(...@@ -25412,7 +25409,7 @@ fn elemValArray(
25412 }25409 }
25413 }25410 }
25414 if (maybe_undef_array_val) |array_val| {25411 if (maybe_undef_array_val) |array_val| {
25415 if (array_val.isUndef()) {25412 if (array_val.isUndef(mod)) {
25416 return sema.addConstUndef(elem_ty);25413 return sema.addConstUndef(elem_ty);
25417 }25414 }
25418 if (maybe_index_val) |index_val| {25415 if (maybe_index_val) |index_val| {
...@@ -25473,7 +25470,7 @@ fn elemPtrArray(...@@ -25473,7 +25470,7 @@ fn elemPtrArray(
25473 const elem_ptr_ty = try sema.elemPtrType(array_ptr_ty, offset);25470 const elem_ptr_ty = try sema.elemPtrType(array_ptr_ty, offset);
2547425471
25475 if (maybe_undef_array_ptr_val) |array_ptr_val| {25472 if (maybe_undef_array_ptr_val) |array_ptr_val| {
25476 if (array_ptr_val.isUndef()) {25473 if (array_ptr_val.isUndef(mod)) {
25477 return sema.addConstUndef(elem_ptr_ty);25474 return sema.addConstUndef(elem_ptr_ty);
25478 }25475 }
25479 if (offset) |index| {25476 if (offset) |index| {
...@@ -25580,7 +25577,7 @@ fn elemPtrSlice(...@@ -25580,7 +25577,7 @@ fn elemPtrSlice(
25580 const elem_ptr_ty = try sema.elemPtrType(slice_ty, offset);25577 const elem_ptr_ty = try sema.elemPtrType(slice_ty, offset);
2558125578
25582 if (maybe_undef_slice_val) |slice_val| {25579 if (maybe_undef_slice_val) |slice_val| {
25583 if (slice_val.isUndef()) {25580 if (slice_val.isUndef(mod)) {
25584 return sema.addConstUndef(elem_ptr_ty);25581 return sema.addConstUndef(elem_ptr_ty);
25585 }25582 }
25586 const slice_len = slice_val.sliceLen(mod);25583 const slice_len = slice_val.sliceLen(mod);
...@@ -25605,7 +25602,7 @@ fn elemPtrSlice(...@@ -25605,7 +25602,7 @@ fn elemPtrSlice(
25605 if (oob_safety and block.wantSafety()) {25602 if (oob_safety and block.wantSafety()) {
25606 const len_inst = len: {25603 const len_inst = len: {
25607 if (maybe_undef_slice_val) |slice_val|25604 if (maybe_undef_slice_val) |slice_val|
25608 if (!slice_val.isUndef())25605 if (!slice_val.isUndef(mod))
25609 break :len try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(mod));25606 break :len try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(mod));
25610 break :len try block.addTyOp(.slice_len, Type.usize, slice);25607 break :len try block.addTyOp(.slice_len, Type.usize, slice);
25611 };25608 };
...@@ -25681,7 +25678,6 @@ fn coerceExtra(...@@ -25681,7 +25678,6 @@ fn coerceExtra(
25681 if (dest_ty.eql(inst_ty, mod))25678 if (dest_ty.eql(inst_ty, mod))
25682 return inst;25679 return inst;
2568325680
25684 const arena = sema.arena;
25685 const maybe_inst_val = try sema.resolveMaybeUndefVal(inst);25681 const maybe_inst_val = try sema.resolveMaybeUndefVal(inst);
2568625682
25687 var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src);25683 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(...@@ -26175,7 +26171,7 @@ fn coerceExtra(
26175 };26171 };
26176 return sema.addConstant(26172 return sema.addConstant(
26177 dest_ty,26173 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)),
26179 );26175 );
26180 },26176 },
26181 .Union => blk: {26177 .Union => blk: {
...@@ -27858,8 +27854,9 @@ fn beginComptimePtrMutation(...@@ -27858,8 +27854,9 @@ fn beginComptimePtrMutation(
27858 },27854 },
27859 .Union => {27855 .Union => {
27860 const payload = try arena.create(Value.Payload.Union);27856 const payload = try arena.create(Value.Payload.Union);
27857 const tag_ty = parent.ty.unionTagTypeHypothetical(mod);
27861 payload.* = .{ .data = .{27858 payload.* = .{ .data = .{
27862 .tag = try Value.Tag.enum_field_index.create(arena, field_index),27859 .tag = try mod.enumValueFieldIndex(tag_ty, field_index),
27863 .val = Value.undef,27860 .val = Value.undef,
27864 } };27861 } };
2786527862
...@@ -27934,11 +27931,10 @@ fn beginComptimePtrMutation(...@@ -27934,11 +27931,10 @@ fn beginComptimePtrMutation(
2793427931
27935 .@"union" => {27932 .@"union" => {
27936 // We need to set the active field of the union.27933 // We need to set the active field of the union.
27937 const arena = parent.beginArena(sema.mod);27934 const union_tag_ty = field_ptr.container_ty.unionTagTypeHypothetical(mod);
27938 defer parent.finishArena(sema.mod);
2793927935
27940 const payload = &val_ptr.castTag(.@"union").?.data;27936 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
27943 return beginComptimePtrMutationInner(27939 return beginComptimePtrMutationInner(
27944 sema,27940 sema,
...@@ -28575,7 +28571,7 @@ fn coerceCompatiblePtrs(...@@ -28575,7 +28571,7 @@ fn coerceCompatiblePtrs(
28575 const mod = sema.mod;28571 const mod = sema.mod;
28576 const inst_ty = sema.typeOf(inst);28572 const inst_ty = sema.typeOf(inst);
28577 if (try sema.resolveMaybeUndefVal(inst)) |val| {28573 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)) {
28579 return sema.fail(block, inst_src, "null pointer casted to type '{}'", .{dest_ty.fmt(sema.mod)});28575 return sema.fail(block, inst_src, "null pointer casted to type '{}'", .{dest_ty.fmt(sema.mod)});
28580 }28576 }
28581 // The comptime Value representation is compatible with both types.28577 // The comptime Value representation is compatible with both types.
...@@ -29426,7 +29422,7 @@ fn analyzeSlicePtr(...@@ -29426,7 +29422,7 @@ fn analyzeSlicePtr(
29426 const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer);29422 const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer);
29427 const result_ty = slice_ty.slicePtrFieldType(buf, mod);29423 const result_ty = slice_ty.slicePtrFieldType(buf, mod);
29428 if (try sema.resolveMaybeUndefVal(slice)) |val| {29424 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);
29430 return sema.addConstant(result_ty, val.slicePtr());29426 return sema.addConstant(result_ty, val.slicePtr());
29431 }29427 }
29432 try sema.requireRuntimeBlock(block, slice_src, null);29428 try sema.requireRuntimeBlock(block, slice_src, null);
...@@ -29439,8 +29435,9 @@ fn analyzeSliceLen(...@@ -29439,8 +29435,9 @@ fn analyzeSliceLen(
29439 src: LazySrcLoc,29435 src: LazySrcLoc,
29440 slice_inst: Air.Inst.Ref,29436 slice_inst: Air.Inst.Ref,
29441) CompileError!Air.Inst.Ref {29437) CompileError!Air.Inst.Ref {
29438 const mod = sema.mod;
29442 if (try sema.resolveMaybeUndefVal(slice_inst)) |slice_val| {29439 if (try sema.resolveMaybeUndefVal(slice_inst)) |slice_val| {
29443 if (slice_val.isUndef()) {29440 if (slice_val.isUndef(mod)) {
29444 return sema.addConstUndef(Type.usize);29441 return sema.addConstUndef(Type.usize);
29445 }29442 }
29446 return sema.addIntUnsigned(Type.usize, slice_val.sliceLen(sema.mod));29443 return sema.addIntUnsigned(Type.usize, slice_val.sliceLen(sema.mod));
...@@ -29459,7 +29456,7 @@ fn analyzeIsNull(...@@ -29459,7 +29456,7 @@ fn analyzeIsNull(
29459 const mod = sema.mod;29456 const mod = sema.mod;
29460 const result_ty = Type.bool;29457 const result_ty = Type.bool;
29461 if (try sema.resolveMaybeUndefVal(operand)) |opt_val| {29458 if (try sema.resolveMaybeUndefVal(operand)) |opt_val| {
29462 if (opt_val.isUndef()) {29459 if (opt_val.isUndef(mod)) {
29463 return sema.addConstUndef(result_ty);29460 return sema.addConstUndef(result_ty);
29464 }29461 }
29465 const is_null = opt_val.isNull(mod);29462 const is_null = opt_val.isNull(mod);
...@@ -29588,7 +29585,7 @@ fn analyzeIsNonErrComptimeOnly(...@@ -29588,7 +29585,7 @@ fn analyzeIsNonErrComptimeOnly(
29588 }29585 }
2958929586
29590 if (maybe_operand_val) |err_union| {29587 if (maybe_operand_val) |err_union| {
29591 if (err_union.isUndef()) {29588 if (err_union.isUndef(mod)) {
29592 return sema.addConstUndef(Type.bool);29589 return sema.addConstUndef(Type.bool);
29593 }29590 }
29594 if (err_union.getError() == null) {29591 if (err_union.getError() == null) {
...@@ -29768,7 +29765,7 @@ fn analyzeSlice(...@@ -29768,7 +29765,7 @@ fn analyzeSlice(
29768 } else try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);29765 } else try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
29769 if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| {29766 if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| {
29770 if (try sema.resolveMaybeUndefVal(ptr_or_slice)) |slice_val| {29767 if (try sema.resolveMaybeUndefVal(ptr_or_slice)) |slice_val| {
29771 if (slice_val.isUndef()) {29768 if (slice_val.isUndef(mod)) {
29772 return sema.fail(block, src, "slice of undefined", .{});29769 return sema.fail(block, src, "slice of undefined", .{});
29773 }29770 }
29774 const has_sentinel = slice_ty.sentinel(mod) != null;29771 const has_sentinel = slice_ty.sentinel(mod) != null;
...@@ -29948,7 +29945,7 @@ fn analyzeSlice(...@@ -29948,7 +29945,7 @@ fn analyzeSlice(
29948 return result;29945 return result;
29949 };29946 };
2995029947
29951 if (!new_ptr_val.isUndef()) {29948 if (!new_ptr_val.isUndef(mod)) {
29952 return sema.addConstant(return_ty, new_ptr_val);29949 return sema.addConstant(return_ty, new_ptr_val);
29953 }29950 }
2995429951
...@@ -30069,19 +30066,19 @@ fn cmpNumeric(...@@ -30069,19 +30066,19 @@ fn cmpNumeric(
30069 if (try sema.resolveMaybeUndefVal(lhs)) |lhs_val| {30066 if (try sema.resolveMaybeUndefVal(lhs)) |lhs_val| {
30070 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {30067 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {
30071 // Compare ints: const vs. undefined (or vice versa)30068 // 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)) {
30073 try sema.resolveLazyValue(lhs_val);30070 try sema.resolveLazyValue(lhs_val);
30074 if (try sema.compareIntsOnlyPossibleResult(lhs_val, op, rhs_ty)) |res| {30071 if (try sema.compareIntsOnlyPossibleResult(lhs_val, op, rhs_ty)) |res| {
30075 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;30072 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;
30076 }30073 }
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)) {
30078 try sema.resolveLazyValue(rhs_val);30075 try sema.resolveLazyValue(rhs_val);
30079 if (try sema.compareIntsOnlyPossibleResult(rhs_val, op.reverse(), lhs_ty)) |res| {30076 if (try sema.compareIntsOnlyPossibleResult(rhs_val, op.reverse(), lhs_ty)) |res| {
30080 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;30077 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;
30081 }30078 }
30082 }30079 }
3008330080
30084 if (lhs_val.isUndef() or rhs_val.isUndef()) {30081 if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) {
30085 return sema.addConstUndef(Type.bool);30082 return sema.addConstUndef(Type.bool);
30086 }30083 }
30087 if (lhs_val.isNan(mod) or rhs_val.isNan(mod)) {30084 if (lhs_val.isNan(mod) or rhs_val.isNan(mod)) {
...@@ -30097,7 +30094,7 @@ fn cmpNumeric(...@@ -30097,7 +30094,7 @@ fn cmpNumeric(
30097 return Air.Inst.Ref.bool_false;30094 return Air.Inst.Ref.bool_false;
30098 }30095 }
30099 } else {30096 } 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)) {
30101 // Compare ints: const vs. var30098 // Compare ints: const vs. var
30102 try sema.resolveLazyValue(lhs_val);30099 try sema.resolveLazyValue(lhs_val);
30103 if (try sema.compareIntsOnlyPossibleResult(lhs_val, op, rhs_ty)) |res| {30100 if (try sema.compareIntsOnlyPossibleResult(lhs_val, op, rhs_ty)) |res| {
...@@ -30108,7 +30105,7 @@ fn cmpNumeric(...@@ -30108,7 +30105,7 @@ fn cmpNumeric(
30108 }30105 }
30109 } else {30106 } else {
30110 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {30107 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)) {
30112 // Compare ints: var vs. const30109 // Compare ints: var vs. const
30113 try sema.resolveLazyValue(rhs_val);30110 try sema.resolveLazyValue(rhs_val);
30114 if (try sema.compareIntsOnlyPossibleResult(rhs_val, op.reverse(), lhs_ty)) |res| {30111 if (try sema.compareIntsOnlyPossibleResult(rhs_val, op.reverse(), lhs_ty)) |res| {
...@@ -30177,7 +30174,7 @@ fn cmpNumeric(...@@ -30177,7 +30174,7 @@ fn cmpNumeric(
30177 var lhs_bits: usize = undefined;30174 var lhs_bits: usize = undefined;
30178 if (try sema.resolveMaybeUndefVal(lhs)) |lhs_val| {30175 if (try sema.resolveMaybeUndefVal(lhs)) |lhs_val| {
30179 try sema.resolveLazyValue(lhs_val);30176 try sema.resolveLazyValue(lhs_val);
30180 if (lhs_val.isUndef())30177 if (lhs_val.isUndef(mod))
30181 return sema.addConstUndef(Type.bool);30178 return sema.addConstUndef(Type.bool);
30182 if (lhs_val.isNan(mod)) switch (op) {30179 if (lhs_val.isNan(mod)) switch (op) {
30183 .neq => return Air.Inst.Ref.bool_true,30180 .neq => return Air.Inst.Ref.bool_true,
...@@ -30236,7 +30233,7 @@ fn cmpNumeric(...@@ -30236,7 +30233,7 @@ fn cmpNumeric(
30236 var rhs_bits: usize = undefined;30233 var rhs_bits: usize = undefined;
30237 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {30234 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {
30238 try sema.resolveLazyValue(rhs_val);30235 try sema.resolveLazyValue(rhs_val);
30239 if (rhs_val.isUndef())30236 if (rhs_val.isUndef(mod))
30240 return sema.addConstUndef(Type.bool);30237 return sema.addConstUndef(Type.bool);
30241 if (rhs_val.isNan(mod)) switch (op) {30238 if (rhs_val.isNan(mod)) switch (op) {
30242 .neq => return Air.Inst.Ref.bool_true,30239 .neq => return Air.Inst.Ref.bool_true,
...@@ -30441,7 +30438,7 @@ fn cmpVector(...@@ -30441,7 +30438,7 @@ fn cmpVector(
30441 const runtime_src: LazySrcLoc = src: {30438 const runtime_src: LazySrcLoc = src: {
30442 if (try sema.resolveMaybeUndefVal(casted_lhs)) |lhs_val| {30439 if (try sema.resolveMaybeUndefVal(casted_lhs)) |lhs_val| {
30443 if (try sema.resolveMaybeUndefVal(casted_rhs)) |rhs_val| {30440 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)) {
30445 return sema.addConstUndef(result_ty);30442 return sema.addConstUndef(result_ty);
30446 }30443 }
30447 const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_ty);30444 const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_ty);
...@@ -30558,11 +30555,12 @@ fn unionToTag(...@@ -30558,11 +30555,12 @@ fn unionToTag(
30558 un: Air.Inst.Ref,30555 un: Air.Inst.Ref,
30559 un_src: LazySrcLoc,30556 un_src: LazySrcLoc,
30560) !Air.Inst.Ref {30557) !Air.Inst.Ref {
30558 const mod = sema.mod;
30561 if ((try sema.typeHasOnePossibleValue(enum_ty))) |opv| {30559 if ((try sema.typeHasOnePossibleValue(enum_ty))) |opv| {
30562 return sema.addConstant(enum_ty, opv);30560 return sema.addConstant(enum_ty, opv);
30563 }30561 }
30564 if (try sema.resolveMaybeUndefVal(un)) |un_val| {30562 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));
30566 }30564 }
30567 try sema.requireRuntimeBlock(block, un_src, null);30565 try sema.requireRuntimeBlock(block, un_src, null);
30568 return block.addTyOp(.get_union_tag, enum_ty, un);30566 return block.addTyOp(.get_union_tag, enum_ty, un);
...@@ -31718,6 +31716,7 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -31718,6 +31716,7 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
31718 .enum_type => |enum_type| try sema.resolveTypeRequiresComptime(enum_type.tag_ty.toType()),31716 .enum_type => |enum_type| try sema.resolveTypeRequiresComptime(enum_type.tag_ty.toType()),
3171931717
31720 // values, not types31718 // values, not types
31719 .undef => unreachable,
31721 .un => unreachable,31720 .un => unreachable,
31722 .simple_value => unreachable,31721 .simple_value => unreachable,
31723 .extern_func => unreachable,31722 .extern_func => unreachable,
...@@ -31845,6 +31844,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {...@@ -31845,6 +31844,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
31845 .none => return ty,31844 .none => return ty,
3184631845
31847 .u1_type,31846 .u1_type,
31847 .u5_type,
31848 .u8_type,31848 .u8_type,
31849 .i8_type,31849 .i8_type,
31850 .u16_type,31850 .u16_type,
...@@ -31904,6 +31904,8 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {...@@ -31904,6 +31904,8 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
31904 .zero_u8 => unreachable,31904 .zero_u8 => unreachable,
31905 .one => unreachable,31905 .one => unreachable,
31906 .one_usize => unreachable,31906 .one_usize => unreachable,
31907 .one_u5 => unreachable,
31908 .four_u5 => unreachable,
31907 .negative_one => unreachable,31909 .negative_one => unreachable,
31908 .calling_convention_c => unreachable,31910 .calling_convention_c => unreachable,
31909 .calling_convention_inline => unreachable,31911 .calling_convention_inline => unreachable,
...@@ -32720,7 +32722,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -32720,7 +32722,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
32720 }32722 }
3272132723
32722 if (explicit_enum_info) |tag_info| {32724 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 {
32724 const msg = msg: {32726 const msg = msg: {
32725 const ty_src = mod.fieldSrcLoc(union_obj.owner_decl, .{32727 const ty_src = mod.fieldSrcLoc(union_obj.owner_decl, .{
32726 .index = field_i,32728 .index = field_i,
...@@ -33186,19 +33188,30 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -33186,19 +33188,30 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
33186 .opaque_type => null,33188 .opaque_type => null,
33187 .enum_type => |enum_type| switch (enum_type.tag_mode) {33189 .enum_type => |enum_type| switch (enum_type.tag_mode) {
33188 .nonexhaustive => {33190 .nonexhaustive => {
33189 if (enum_type.tag_ty != .comptime_int_type and33191 if (enum_type.tag_ty == .comptime_int_type) return null;
33190 !(try sema.typeHasRuntimeBits(enum_type.tag_ty.toType())))33192
33191 {33193 if (try sema.typeHasOnePossibleValue(enum_type.tag_ty.toType())) |int_opv| {
33192 return Value.enum_field_0;33194 const only = try mod.intern(.{ .enum_tag = .{
33193 } else {33195 .ty = ty.ip_index,
33194 return null;33196 .int = int_opv.ip_index,
33197 } });
33198 return only.toValue();
33195 }33199 }
33200
33201 return null;
33196 },33202 },
33197 .auto, .explicit => switch (enum_type.names.len) {33203 .auto, .explicit => switch (enum_type.names.len) {
33198 0 => return Value.@"unreachable",33204 0 => return Value.@"unreachable",
33199 1 => {33205 1 => {
33200 if (enum_type.values.len == 0) {33206 if (enum_type.values.len == 0) {
33201 return Value.enum_field_0; // auto-numbered33207 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();
33202 } else {33215 } else {
33203 return enum_type.values[0].toValue();33216 return enum_type.values[0].toValue();
33204 }33217 }
...@@ -33208,6 +33221,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -33208,6 +33221,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
33208 },33221 },
3320933222
33210 // values, not types33223 // values, not types
33224 .undef => unreachable,
33211 .un => unreachable,33225 .un => unreachable,
33212 .simple_value => unreachable,33226 .simple_value => unreachable,
33213 .extern_func => unreachable,33227 .extern_func => unreachable,
...@@ -33397,8 +33411,9 @@ pub fn analyzeAddressSpace(...@@ -33397,8 +33411,9 @@ pub fn analyzeAddressSpace(
33397 zir_ref: Zir.Inst.Ref,33411 zir_ref: Zir.Inst.Ref,
33398 ctx: AddressSpaceContext,33412 ctx: AddressSpaceContext,
33399) !std.builtin.AddressSpace {33413) !std.builtin.AddressSpace {
33414 const mod = sema.mod;
33400 const addrspace_tv = try sema.resolveInstConst(block, src, zir_ref, "addresspace must be comptime-known");33415 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);
33402 const target = sema.mod.getTarget();33417 const target = sema.mod.getTarget();
33403 const arch = target.cpu.arch;33418 const arch = target.cpu.arch;
3340433419
...@@ -33766,6 +33781,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -33766,6 +33781,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
33766 .enum_type => |enum_type| try sema.typeRequiresComptime(enum_type.tag_ty.toType()),33781 .enum_type => |enum_type| try sema.typeRequiresComptime(enum_type.tag_ty.toType()),
3376733782
33768 // values, not types33783 // values, not types
33784 .undef => unreachable,
33769 .un => unreachable,33785 .un => unreachable,
33770 .simple_value => unreachable,33786 .simple_value => unreachable,
33771 .extern_func => unreachable,33787 .extern_func => unreachable,
...@@ -33921,9 +33937,9 @@ fn numberAddWrapScalar(...@@ -33921,9 +33937,9 @@ fn numberAddWrapScalar(
33921 rhs: Value,33937 rhs: Value,
33922 ty: Type,33938 ty: Type,
33923) !Value {33939) !Value {
33924 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;
33925
33926 const mod = sema.mod;33940 const mod = sema.mod;
33941 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.undef;
33942
33927 if (ty.zigTypeTag(mod) == .ComptimeInt) {33943 if (ty.zigTypeTag(mod) == .ComptimeInt) {
33928 return sema.intAdd(lhs, rhs, ty);33944 return sema.intAdd(lhs, rhs, ty);
33929 }33945 }
...@@ -33975,9 +33991,9 @@ fn numberSubWrapScalar(...@@ -33975,9 +33991,9 @@ fn numberSubWrapScalar(
33975 rhs: Value,33991 rhs: Value,
33976 ty: Type,33992 ty: Type,
33977) !Value {33993) !Value {
33978 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;
33979
33980 const mod = sema.mod;33994 const mod = sema.mod;
33995 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.undef;
33996
33981 if (ty.zigTypeTag(mod) == .ComptimeInt) {33997 if (ty.zigTypeTag(mod) == .ComptimeInt) {
33982 return sema.intSub(lhs, rhs, ty);33998 return sema.intSub(lhs, rhs, ty);
33983 }33999 }
...@@ -34222,17 +34238,12 @@ fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool {...@@ -34222,17 +34238,12 @@ fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool {
34222 const mod = sema.mod;34238 const mod = sema.mod;
34223 const enum_type = mod.intern_pool.indexToKey(ty.ip_index).enum_type;34239 const enum_type = mod.intern_pool.indexToKey(ty.ip_index).enum_type;
34224 assert(enum_type.tag_mode != .nonexhaustive);34240 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
34230 // The `tagValueIndex` function call below relies on the type being the integer tag type.34241 // The `tagValueIndex` function call below relies on the type being the integer tag type.
34231 // `getCoerced` assumes the value will fit the new type.34242 // `getCoerced` assumes the value will fit the new type.
34232 if (!(try sema.intFitsInType(int, enum_type.tag_ty.toType(), null))) return false;34243 if (!(try sema.intFitsInType(int, enum_type.tag_ty.toType(), null))) return false;
34233 const int_coerced = try mod.intern_pool.getCoerced(sema.gpa, int.ip_index, enum_type.tag_ty);34244 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;
34236}34247}
3423734248
34238fn intAddWithOverflow(34249fn intAddWithOverflow(
src/TypedValue.zig+16-5
...@@ -197,9 +197,6 @@ pub fn print(...@@ -197,9 +197,6 @@ pub fn print(
197 },197 },
198 .empty_array => return writer.writeAll(".{}"),198 .empty_array => return writer.writeAll(".{}"),
199 .enum_literal => return writer.print(".{}", .{std.zig.fmtId(val.castTag(.enum_literal).?.data)}),199 .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 },
203 .bytes => return writer.print("\"{}\"", .{std.zig.fmtEscapes(val.castTag(.bytes).?.data)}),200 .bytes => return writer.print("\"{}\"", .{std.zig.fmtEscapes(val.castTag(.bytes).?.data)}),
204 .str_lit => {201 .str_lit => {
205 const str_lit = val.castTag(.str_lit).?.data;202 const str_lit = val.castTag(.str_lit).?.data;
...@@ -255,7 +252,7 @@ pub fn print(...@@ -255,7 +252,7 @@ pub fn print(
255 const elem_val = payload.ptr.elemValue(mod, i) catch |err| switch (err) {252 const elem_val = payload.ptr.elemValue(mod, i) catch |err| switch (err) {
256 error.OutOfMemory => @panic("OOM"), // TODO: eliminate this panic253 error.OutOfMemory => @panic("OOM"), // TODO: eliminate this panic
257 };254 };
258 if (elem_val.isUndef()) break :str;255 if (elem_val.isUndef(mod)) break :str;
259 buf[i] = std.math.cast(u8, elem_val.toUnsignedInt(mod)) orelse break :str;256 buf[i] = std.math.cast(u8, elem_val.toUnsignedInt(mod)) orelse break :str;
260 }257 }
261258
...@@ -358,6 +355,20 @@ pub fn print(...@@ -358,6 +355,20 @@ pub fn print(
358 .int => |int| switch (int.storage) {355 .int => |int| switch (int.storage) {
359 inline .u64, .i64, .big_int => |x| return writer.print("{}", .{x}),356 inline .u64, .i64, .big_int => |x| return writer.print("{}", .{x}),
360 },357 },
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 },
361 .float => |float| switch (float.storage) {372 .float => |float| switch (float.storage) {
362 inline else => |x| return writer.print("{}", .{x}),373 inline else => |x| return writer.print("{}", .{x}),
363 },374 },
...@@ -414,7 +425,7 @@ fn printAggregate(...@@ -414,7 +425,7 @@ fn printAggregate(
414 var i: u32 = 0;425 var i: u32 = 0;
415 while (i < max_len) : (i += 1) {426 while (i < max_len) : (i += 1) {
416 const elem = try val.fieldValue(ty, mod, i);427 const elem = try val.fieldValue(ty, mod, i);
417 if (elem.isUndef()) break :str;428 if (elem.isUndef(mod)) break :str;
418 buf[i] = std.math.cast(u8, elem.toUnsignedInt(mod)) orelse break :str;429 buf[i] = std.math.cast(u8, elem.toUnsignedInt(mod)) orelse break :str;
419 }430 }
420431
src/Zir.zig+3
...@@ -2052,6 +2052,7 @@ pub const Inst = struct {...@@ -2052,6 +2052,7 @@ pub const Inst = struct {
2052 /// and `[]Ref`.2052 /// and `[]Ref`.
2053 pub const Ref = enum(u32) {2053 pub const Ref = enum(u32) {
2054 u1_type = @enumToInt(InternPool.Index.u1_type),2054 u1_type = @enumToInt(InternPool.Index.u1_type),
2055 u5_type = @enumToInt(InternPool.Index.u5_type),
2055 u8_type = @enumToInt(InternPool.Index.u8_type),2056 u8_type = @enumToInt(InternPool.Index.u8_type),
2056 i8_type = @enumToInt(InternPool.Index.i8_type),2057 i8_type = @enumToInt(InternPool.Index.i8_type),
2057 u16_type = @enumToInt(InternPool.Index.u16_type),2058 u16_type = @enumToInt(InternPool.Index.u16_type),
...@@ -2120,6 +2121,8 @@ pub const Inst = struct {...@@ -2120,6 +2121,8 @@ pub const Inst = struct {
2120 zero_u8 = @enumToInt(InternPool.Index.zero_u8),2121 zero_u8 = @enumToInt(InternPool.Index.zero_u8),
2121 one = @enumToInt(InternPool.Index.one),2122 one = @enumToInt(InternPool.Index.one),
2122 one_usize = @enumToInt(InternPool.Index.one_usize),2123 one_usize = @enumToInt(InternPool.Index.one_usize),
2124 one_u5 = @enumToInt(InternPool.Index.one_u5),
2125 four_u5 = @enumToInt(InternPool.Index.four_u5),
2123 negative_one = @enumToInt(InternPool.Index.negative_one),2126 negative_one = @enumToInt(InternPool.Index.negative_one),
2124 calling_convention_c = @enumToInt(InternPool.Index.calling_convention_c),2127 calling_convention_c = @enumToInt(InternPool.Index.calling_convention_c),
2125 calling_convention_inline = @enumToInt(InternPool.Index.calling_convention_inline),2128 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);...@@ -11,6 +11,7 @@ const log = std.log.scoped(.codegen);
1111
12const codegen = @import("../../codegen.zig");12const codegen = @import("../../codegen.zig");
13const Module = @import("../../Module.zig");13const Module = @import("../../Module.zig");
14const InternPool = @import("../../InternPool.zig");
14const Decl = Module.Decl;15const Decl = Module.Decl;
15const Type = @import("../../type.zig").Type;16const Type = @import("../../type.zig").Type;
16const Value = @import("../../value.zig").Value;17const Value = @import("../../value.zig").Value;
...@@ -3044,11 +3045,12 @@ fn toTwosComplement(value: anytype, bits: u7) std.meta.Int(.unsigned, @typeInfo(...@@ -3044,11 +3045,12 @@ fn toTwosComplement(value: anytype, bits: u7) std.meta.Int(.unsigned, @typeInfo(
3044}3045}
30453046
3046fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {3047fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3048 const mod = func.bin_file.base.options.module.?;
3047 var val = arg_val;3049 var val = arg_val;
3048 if (val.castTag(.runtime_value)) |rt| {3050 if (val.castTag(.runtime_value)) |rt| {
3049 val = rt.data;3051 val = rt.data;
3050 }3052 }
3051 if (val.isUndefDeep()) return func.emitUndefined(ty);3053 if (val.isUndefDeep(mod)) return func.emitUndefined(ty);
3052 if (val.castTag(.decl_ref)) |decl_ref| {3054 if (val.castTag(.decl_ref)) |decl_ref| {
3053 const decl_index = decl_ref.data;3055 const decl_index = decl_ref.data;
3054 return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl_index, 0);3056 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 {...@@ -3057,7 +3059,6 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3057 const decl_index = decl_ref_mut.data.decl_index;3059 const decl_index = decl_ref_mut.data.decl_index;
3058 return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl_index, 0);3060 return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl_index, 0);
3059 }3061 }
3060 const mod = func.bin_file.base.options.module.?;
3061 switch (ty.zigTypeTag(mod)) {3062 switch (ty.zigTypeTag(mod)) {
3062 .Void => return WValue{ .none = {} },3063 .Void => return WValue{ .none = {} },
3063 .Int => {3064 .Int => {
...@@ -3100,18 +3101,9 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {...@@ -3100,18 +3101,9 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3100 },3101 },
3101 },3102 },
3102 .Enum => {3103 .Enum => {
3103 if (val.castTag(.enum_field_index)) |field_index| {3104 const enum_tag = mod.intern_pool.indexToKey(val.ip_index).enum_tag;
3104 const enum_type = mod.intern_pool.indexToKey(ty.ip_index).enum_type;3105 const int_tag_ty = mod.intern_pool.typeOf(enum_tag.int);
3105 if (enum_type.values.len != 0) {3106 return func.lowerConstant(enum_tag.int.toValue(), int_tag_ty.toType());
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 }
3115 },3107 },
3116 .ErrorSet => switch (val.tag()) {3108 .ErrorSet => switch (val.tag()) {
3117 .@"error" => {3109 .@"error" => {
...@@ -3223,37 +3215,42 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {...@@ -3223,37 +3215,42 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
3223/// Returns a `Value` as a signed 32 bit value.3215/// Returns a `Value` as a signed 32 bit value.
3224/// It's illegal to provide a value with a type that cannot be represented3216/// It's illegal to provide a value with a type that cannot be represented
3225/// as an integer value.3217/// as an integer value.
3226fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) !i32 {3218fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {
3227 const mod = func.bin_file.base.options.module.?;3219 const mod = func.bin_file.base.options.module.?;
3228 switch (ty.zigTypeTag(mod)) {3220
3229 .Enum => {3221 switch (val.ip_index) {
3230 if (val.castTag(.enum_field_index)) |field_index| {3222 .none => {},
3231 const enum_type = mod.intern_pool.indexToKey(ty.ip_index).enum_type;3223 .bool_true => return 1,
3232 if (enum_type.values.len != 0) {3224 .bool_false => return 0,
3233 const tag_val = enum_type.values[field_index.data];3225 else => return switch (mod.intern_pool.indexToKey(val.ip_index)) {
3234 return func.valueAsI32(tag_val.toValue(), enum_type.tag_ty.toType());3226 .enum_tag => |enum_tag| intIndexAsI32(&mod.intern_pool, enum_tag.int),
3235 } else {3227 .int => |int| intStorageAsI32(int.storage),
3236 return @bitCast(i32, field_index.data);3228 .ptr => |ptr| intIndexAsI32(&mod.intern_pool, ptr.addr.int),
3237 }3229 else => unreachable,
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))),
3246 },3230 },
3231 }
3232
3233 switch (ty.zigTypeTag(mod)) {
3247 .ErrorSet => {3234 .ErrorSet => {
3248 const kv = func.bin_file.base.options.module.?.getErrorValue(val.getError().?) catch unreachable; // passed invalid `Value` to function3235 const kv = func.bin_file.base.options.module.?.getErrorValue(val.getError().?) catch unreachable; // passed invalid `Value` to function
3249 return @bitCast(i32, kv.value);3236 return @bitCast(i32, kv.value);
3250 },3237 },
3251 .Bool => return @intCast(i32, val.toSignedInt(mod)),
3252 .Pointer => return @intCast(i32, val.toSignedInt(mod)),
3253 else => unreachable, // Programmer called this function for an illegal type3238 else => unreachable, // Programmer called this function for an illegal type
3254 }3239 }
3255}3240}
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
3257fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {3254fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3258 const mod = func.bin_file.base.options.module.?;3255 const mod = func.bin_file.base.options.module.?;
3259 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;3256 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 {...@@ -3772,7 +3769,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37723769
3773 for (items, 0..) |ref, i| {3770 for (items, 0..) |ref, i| {
3774 const item_val = (try func.air.value(ref, mod)).?;3771 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);
3776 if (lowest_maybe == null or int_val < lowest_maybe.?) {3773 if (lowest_maybe == null or int_val < lowest_maybe.?) {
3777 lowest_maybe = int_val;3774 lowest_maybe = int_val;
3778 }3775 }
...@@ -5071,12 +5068,8 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5071,12 +5068,8 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
50715068
5072 const tag_int = blk: {5069 const tag_int = blk: {
5073 const tag_ty = union_ty.unionTagTypeHypothetical(mod);5070 const tag_ty = union_ty.unionTagTypeHypothetical(mod);
5074 const enum_field_index = tag_ty.enumFieldIndex(field_name).?;5071 const enum_field_index = tag_ty.enumFieldIndex(field_name, mod).?;
5075 var tag_val_payload: Value.Payload.U32 = .{5072 const tag_val = try mod.enumValueFieldIndex(tag_ty, enum_field_index);
5076 .base = .{ .tag = .enum_field_index },
5077 .data = @intCast(u32, enum_field_index),
5078 };
5079 const tag_val = Value.initPayload(&tag_val_payload.base);
5080 break :blk try func.lowerConstant(tag_val, tag_ty);5073 break :blk try func.lowerConstant(tag_val, tag_ty);
5081 };5074 };
5082 if (layout.payload_size == 0) {5075 if (layout.payload_size == 0) {
...@@ -6815,7 +6808,8 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -6815,7 +6808,8 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
68156808
6816 // TODO: Make switch implementation generic so we can use a jump table for this when the tags are not sparse.6809 // TODO: Make switch implementation generic so we can use a jump table for this when the tags are not sparse.
6817 // generate an if-else chain for each tag value as well as constant.6810 // 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);
6819 const tag_name = mod.intern_pool.stringToSlice(tag_name_ip);6813 const tag_name = mod.intern_pool.stringToSlice(tag_name_ip);
6820 // for each tag name, create an unnamed const,6814 // for each tag name, create an unnamed const,
6821 // and then get a pointer to its value.6815 // and then get a pointer to its value.
...@@ -6857,11 +6851,8 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -6857,11 +6851,8 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
6857 try writer.writeByte(std.wasm.opcode(.local_get));6851 try writer.writeByte(std.wasm.opcode(.local_get));
6858 try leb.writeULEB128(writer, @as(u32, 1));6852 try leb.writeULEB128(writer, @as(u32, 1));
68596853
6860 var tag_val_payload: Value.Payload.U32 = .{6854 const tag_val = try mod.enumValueFieldIndex(enum_ty, field_index);
6861 .base = .{ .tag = .enum_field_index },6855 const tag_value = try func.lowerConstant(tag_val, enum_ty);
6862 .data = @intCast(u32, field_index),
6863 };
6864 const tag_value = try func.lowerConstant(Value.initPayload(&tag_val_payload.base), enum_ty);
68656856
6866 switch (tag_value) {6857 switch (tag_value) {
6867 .imm32 => |value| {6858 .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 {...@@ -2029,13 +2029,10 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
2029 exitlude_jump_relocs,2029 exitlude_jump_relocs,
2030 enum_ty.enumFields(mod),2030 enum_ty.enumFields(mod),
2031 0..,2031 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);
2033 const tag_name = mod.intern_pool.stringToSlice(tag_name_ip);2034 const tag_name = mod.intern_pool.stringToSlice(tag_name_ip);
2034 var tag_pl = Value.Payload.U32{2035 const tag_val = try mod.enumValueFieldIndex(enum_ty, index);
2035 .base = .{ .tag = .enum_field_index },
2036 .data = @intCast(u32, index),
2037 };
2038 const tag_val = Value.initPayload(&tag_pl.base);
2039 const tag_mcv = try self.genTypedValue(.{ .ty = enum_ty, .val = tag_val });2036 const tag_mcv = try self.genTypedValue(.{ .ty = enum_ty, .val = tag_val });
2040 try self.genBinOpMir(.{ ._, .cmp }, enum_ty, enum_mcv, tag_mcv);2037 try self.genBinOpMir(.{ ._, .cmp }, enum_ty, enum_mcv, tag_mcv);
2041 const skip_reloc = try self.asmJccReloc(undefined, .ne);2038 const skip_reloc = try self.asmJccReloc(undefined, .ne);
...@@ -11415,8 +11412,7 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -11415,8 +11412,7 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
11415 const field_name = union_obj.fields.keys()[extra.field_index];11412 const field_name = union_obj.fields.keys()[extra.field_index];
11416 const tag_ty = union_obj.tag_ty;11413 const tag_ty = union_obj.tag_ty;
11417 const field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name, mod).?);11414 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 };11415 const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index);
11419 const tag_val = Value.initPayload(&tag_pl.base);
11420 const tag_int_val = try tag_val.enumToInt(tag_ty, mod);11416 const tag_int_val = try tag_val.enumToInt(tag_ty, mod);
11421 const tag_int = tag_int_val.toUnsignedInt(mod);11417 const tag_int = tag_int_val.toUnsignedInt(mod);
11422 const tag_off = if (layout.tag_align < layout.payload_align)11418 const tag_off = if (layout.tag_align < layout.payload_align)
src/codegen.zig+8-20
...@@ -196,7 +196,7 @@ pub fn generateSymbol(...@@ -196,7 +196,7 @@ pub fn generateSymbol(
196 typed_value.val.fmtValue(typed_value.ty, mod),196 typed_value.val.fmtValue(typed_value.ty, mod),
197 });197 });
198198
199 if (typed_value.val.isUndefDeep()) {199 if (typed_value.val.isUndefDeep(mod)) {
200 const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow;200 const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow;
201 try code.appendNTimes(0xaa, abi_size);201 try code.appendNTimes(0xaa, abi_size);
202 return Result.ok;202 return Result.ok;
...@@ -1168,7 +1168,7 @@ pub fn genTypedValue(...@@ -1168,7 +1168,7 @@ pub fn genTypedValue(
1168 typed_value.val.fmtValue(typed_value.ty, mod),1168 typed_value.val.fmtValue(typed_value.ty, mod),
1169 });1169 });
11701170
1171 if (typed_value.val.isUndef())1171 if (typed_value.val.isUndef(mod))
1172 return GenResult.mcv(.undef);1172 return GenResult.mcv(.undef);
11731173
1174 const target = bin_file.options.target;1174 const target = bin_file.options.target;
...@@ -1229,24 +1229,12 @@ pub fn genTypedValue(...@@ -1229,24 +1229,12 @@ pub fn genTypedValue(
1229 }1229 }
1230 },1230 },
1231 .Enum => {1231 .Enum => {
1232 if (typed_value.val.castTag(.enum_field_index)) |field_index| {1232 const enum_tag = mod.intern_pool.indexToKey(typed_value.val.ip_index).enum_tag;
1233 const enum_type = mod.intern_pool.indexToKey(typed_value.ty.ip_index).enum_type;1233 const int_tag_ty = mod.intern_pool.typeOf(enum_tag.int);
1234 if (enum_type.values.len != 0) {1234 return genTypedValue(bin_file, src_loc, .{
1235 const tag_val = enum_type.values[field_index.data];1235 .ty = int_tag_ty.toType(),
1236 return genTypedValue(bin_file, src_loc, .{1236 .val = enum_tag.int.toValue(),
1237 .ty = enum_type.tag_ty.toType(),1237 }, owner_decl_index);
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 }
1250 },1238 },
1251 .ErrorSet => {1239 .ErrorSet => {
1252 switch (typed_value.val.tag()) {1240 switch (typed_value.val.tag()) {
src/codegen/c.zig+21-35
...@@ -748,7 +748,7 @@ pub const DeclGen = struct {...@@ -748,7 +748,7 @@ pub const DeclGen = struct {
748 .ReleaseFast, .ReleaseSmall => false,748 .ReleaseFast, .ReleaseSmall => false,
749 };749 };
750750
751 if (val.isUndefDeep()) {751 if (val.isUndefDeep(mod)) {
752 switch (ty.zigTypeTag(mod)) {752 switch (ty.zigTypeTag(mod)) {
753 .Bool => {753 .Bool => {
754 if (safety_on) {754 if (safety_on) {
...@@ -1183,7 +1183,7 @@ pub const DeclGen = struct {...@@ -1183,7 +1183,7 @@ pub const DeclGen = struct {
1183 var index: usize = 0;1183 var index: usize = 0;
1184 while (index < ai.len) : (index += 1) {1184 while (index < ai.len) : (index += 1) {
1185 const elem_val = try val.elemValue(mod, index);1185 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));
1187 try literal.writeChar(elem_val_u8);1187 try literal.writeChar(elem_val_u8);
1188 }1188 }
1189 if (ai.sentinel) |s| {1189 if (ai.sentinel) |s| {
...@@ -1197,7 +1197,7 @@ pub const DeclGen = struct {...@@ -1197,7 +1197,7 @@ pub const DeclGen = struct {
1197 while (index < ai.len) : (index += 1) {1197 while (index < ai.len) : (index += 1) {
1198 if (index != 0) try writer.writeByte(',');1198 if (index != 0) try writer.writeByte(',');
1199 const elem_val = try val.elemValue(mod, index);1199 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));
1201 try writer.print("'\\x{x}'", .{elem_val_u8});1201 try writer.print("'\\x{x}'", .{elem_val_u8});
1202 }1202 }
1203 if (ai.sentinel) |s| {1203 if (ai.sentinel) |s| {
...@@ -1284,23 +1284,16 @@ pub const DeclGen = struct {...@@ -1284,23 +1284,16 @@ pub const DeclGen = struct {
1284 try dg.renderValue(writer, error_ty, error_val, initializer_type);1284 try dg.renderValue(writer, error_ty, error_val, initializer_type);
1285 try writer.writeAll(" }");1285 try writer.writeAll(" }");
1286 },1286 },
1287 .Enum => {1287 .Enum => switch (val.ip_index) {
1288 switch (val.tag()) {1288 .none => {
1289 .enum_field_index => {1289 const int_tag_ty = try ty.intTagType(mod);
1290 const field_index = val.castTag(.enum_field_index).?.data;1290 return dg.renderValue(writer, int_tag_ty, val, location);
1291 const enum_type = mod.intern_pool.indexToKey(ty.ip_index).enum_type;1291 },
1292 if (enum_type.values.len != 0) {1292 else => {
1293 const tag_val = enum_type.values[field_index];1293 const enum_tag = mod.intern_pool.indexToKey(val.ip_index).enum_tag;
1294 return dg.renderValue(writer, enum_type.tag_ty.toType(), tag_val.toValue(), location);1294 const int_tag_ty = mod.intern_pool.typeOf(enum_tag.int);
1295 } else {1295 return dg.renderValue(writer, int_tag_ty.toType(), enum_tag.int.toValue(), location);
1296 return writer.print("{d}", .{field_index});1296 },
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 }
1304 },1297 },
1305 .Fn => switch (val.tag()) {1298 .Fn => switch (val.tag()) {
1306 .function => {1299 .function => {
...@@ -2524,13 +2517,10 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {...@@ -2524,13 +2517,10 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
2524 try w.writeByte('(');2517 try w.writeByte('(');
2525 try o.dg.renderTypeAndName(w, enum_ty, .{ .identifier = "tag" }, Const, 0, .complete);2518 try o.dg.renderTypeAndName(w, enum_ty, .{ .identifier = "tag" }, Const, 0, .complete);
2526 try w.writeAll(") {\n switch (tag) {\n");2519 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);
2528 const name = mod.intern_pool.stringToSlice(name_ip);2522 const name = mod.intern_pool.stringToSlice(name_ip);
2529 var tag_pl: Value.Payload.U32 = .{2523 const tag_val = try mod.enumValueFieldIndex(enum_ty, index);
2530 .base = .{ .tag = .enum_field_index },
2531 .data = @intCast(u32, index),
2532 };
2533 const tag_val = Value.initPayload(&tag_pl.base);
25342524
2535 const int_val = try tag_val.enumToInt(enum_ty, mod);2525 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 {...@@ -3609,7 +3599,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3609 const ptr_val = try f.resolveInst(bin_op.lhs);3599 const ptr_val = try f.resolveInst(bin_op.lhs);
3610 const src_ty = f.typeOf(bin_op.rhs);3600 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
3614 if (val_is_undef) {3604 if (val_is_undef) {
3615 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3605 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
...@@ -4267,7 +4257,7 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4267,7 +4257,7 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
4267 const mod = f.object.dg.module;4257 const mod = f.object.dg.module;
4268 const pl_op = f.air.instructions.items(.data)[inst].pl_op;4258 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
4269 const name = f.air.nullTerminatedString(pl_op.payload);4259 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;
4271 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);4261 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);
42724262
4273 try reap(f, inst, &.{pl_op.operand});4263 try reap(f, inst, &.{pl_op.operand});
...@@ -6290,7 +6280,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -6290,7 +6280,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
6290 const value = try f.resolveInst(bin_op.rhs);6280 const value = try f.resolveInst(bin_op.rhs);
6291 const elem_ty = f.typeOf(bin_op.rhs);6281 const elem_ty = f.typeOf(bin_op.rhs);
6292 const elem_abi_size = elem_ty.abiSize(mod);6282 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;
6294 const writer = f.object.writer();6284 const writer = f.object.writer();
62956285
6296 if (val_is_undef) {6286 if (val_is_undef) {
...@@ -6907,11 +6897,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6907,11 +6897,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
6907 if (layout.tag_size != 0) {6897 if (layout.tag_size != 0) {
6908 const field_index = tag_ty.enumFieldIndex(field_name, mod).?;6898 const field_index = tag_ty.enumFieldIndex(field_name, mod).?;
69096899
6910 var tag_pl: Value.Payload.U32 = .{6900 const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index);
6911 .base = .{ .tag = .enum_field_index },
6912 .data = @intCast(u32, field_index),
6913 };
6914 const tag_val = Value.initPayload(&tag_pl.base);
69156901
6916 const int_val = try tag_val.enumToInt(tag_ty, mod);6902 const int_val = try tag_val.enumToInt(tag_ty, mod);
69176903
...@@ -7438,7 +7424,7 @@ fn formatIntLiteral(...@@ -7438,7 +7424,7 @@ fn formatIntLiteral(
7438 defer allocator.free(undef_limbs);7424 defer allocator.free(undef_limbs);
74397425
7440 var int_buf: Value.BigIntSpace = undefined;7426 var int_buf: Value.BigIntSpace = undefined;
7441 const int = if (data.val.isUndefDeep()) blk: {7427 const int = if (data.val.isUndefDeep(mod)) blk: {
7442 undef_limbs = try allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(data.int_info.bits));7428 undef_limbs = try allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(data.int_info.bits));
7443 @memset(undef_limbs, undefPattern(BigIntLimb));7429 @memset(undef_limbs, undefPattern(BigIntLimb));
74447430
src/codegen/llvm.zig+16-28
...@@ -3233,16 +3233,16 @@ pub const DeclGen = struct {...@@ -3233,16 +3233,16 @@ pub const DeclGen = struct {
3233 }3233 }
32343234
3235 fn lowerValue(dg: *DeclGen, arg_tv: TypedValue) Error!*llvm.Value {3235 fn lowerValue(dg: *DeclGen, arg_tv: TypedValue) Error!*llvm.Value {
3236 const mod = dg.module;
3237 const target = mod.getTarget();
3236 var tv = arg_tv;3238 var tv = arg_tv;
3237 if (tv.val.castTag(.runtime_value)) |rt| {3239 if (tv.val.castTag(.runtime_value)) |rt| {
3238 tv.val = rt.data;3240 tv.val = rt.data;
3239 }3241 }
3240 if (tv.val.isUndef()) {3242 if (tv.val.isUndef(mod)) {
3241 const llvm_type = try dg.lowerType(tv.ty);3243 const llvm_type = try dg.lowerType(tv.ty);
3242 return llvm_type.getUndef();3244 return llvm_type.getUndef();
3243 }3245 }
3244 const mod = dg.module;
3245 const target = mod.getTarget();
3246 switch (tv.ty.zigTypeTag(mod)) {3246 switch (tv.ty.zigTypeTag(mod)) {
3247 .Bool => {3247 .Bool => {
3248 const llvm_type = try dg.lowerType(tv.ty);3248 const llvm_type = try dg.lowerType(tv.ty);
...@@ -8204,7 +8204,7 @@ pub const FuncGen = struct {...@@ -8204,7 +8204,7 @@ pub const FuncGen = struct {
8204 const ptr_ty = self.typeOf(bin_op.lhs);8204 const ptr_ty = self.typeOf(bin_op.lhs);
8205 const operand_ty = ptr_ty.childType(mod);8205 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;
8208 if (val_is_undef) {8208 if (val_is_undef) {
8209 // Even if safety is disabled, we still emit a memset to undefined since it conveys8209 // Even if safety is disabled, we still emit a memset to undefined since it conveys
8210 // extra information to LLVM. However, safety makes the difference between using8210 // extra information to LLVM. However, safety makes the difference between using
...@@ -8496,7 +8496,7 @@ pub const FuncGen = struct {...@@ -8496,7 +8496,7 @@ pub const FuncGen = struct {
8496 const is_volatile = ptr_ty.isVolatilePtr(mod);8496 const is_volatile = ptr_ty.isVolatilePtr(mod);
84978497
8498 if (try self.air.value(bin_op.rhs, mod)) |elem_val| {8498 if (try self.air.value(bin_op.rhs, mod)) |elem_val| {
8499 if (elem_val.isUndefDeep()) {8499 if (elem_val.isUndefDeep(mod)) {
8500 // Even if safety is disabled, we still emit a memset to undefined since it conveys8500 // Even if safety is disabled, we still emit a memset to undefined since it conveys
8501 // extra information to LLVM. However, safety makes the difference between using8501 // extra information to LLVM. However, safety makes the difference between using
8502 // 0xaa or actual undefined for the fill byte.8502 // 0xaa or actual undefined for the fill byte.
...@@ -8890,15 +8890,12 @@ pub const FuncGen = struct {...@@ -8890,15 +8890,12 @@ pub const FuncGen = struct {
8890 const tag_int_value = fn_val.getParam(0);8890 const tag_int_value = fn_val.getParam(0);
8891 const switch_instr = self.builder.buildSwitch(tag_int_value, unnamed_block, @intCast(c_uint, enum_type.names.len));8891 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);
8894 const this_tag_int_value = int: {8895 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 };
8899 break :int try self.dg.lowerValue(.{8896 break :int try self.dg.lowerValue(.{
8900 .ty = enum_ty,8897 .ty = enum_ty,
8901 .val = Value.initPayload(&tag_val_payload.base),8898 .val = try mod.enumValueFieldIndex(enum_ty, field_index),
8902 });8899 });
8903 };8900 };
8904 switch_instr.addCase(this_tag_int_value, named_block);8901 switch_instr.addCase(this_tag_int_value, named_block);
...@@ -8973,7 +8970,8 @@ pub const FuncGen = struct {...@@ -8973,7 +8970,8 @@ pub const FuncGen = struct {
8973 usize_llvm_ty.constNull(), usize_llvm_ty.constNull(),8970 usize_llvm_ty.constNull(), usize_llvm_ty.constNull(),
8974 };8971 };
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);
8977 const name = mod.intern_pool.stringToSlice(name_ip);8975 const name = mod.intern_pool.stringToSlice(name_ip);
8978 const str_init = self.context.constString(name.ptr, @intCast(c_uint, name.len), .False);8976 const str_init = self.context.constString(name.ptr, @intCast(c_uint, name.len), .False);
8979 const str_init_llvm_ty = str_init.typeOf();8977 const str_init_llvm_ty = str_init.typeOf();
...@@ -8997,16 +8995,10 @@ pub const FuncGen = struct {...@@ -8997,16 +8995,10 @@ pub const FuncGen = struct {
8997 slice_global.setAlignment(slice_alignment);8995 slice_global.setAlignment(slice_alignment);
89988996
8999 const return_block = self.context.appendBasicBlock(fn_val, "Name");8997 const return_block = self.context.appendBasicBlock(fn_val, "Name");
9000 const this_tag_int_value = int: {8998 const this_tag_int_value = try self.dg.lowerValue(.{
9001 var tag_val_payload: Value.Payload.U32 = .{8999 .ty = enum_ty,
9002 .base = .{ .tag = .enum_field_index },9000 .val = try mod.enumValueFieldIndex(enum_ty, field_index),
9003 .data = @intCast(u32, field_index),9001 });
9004 };
9005 break :int try self.dg.lowerValue(.{
9006 .ty = enum_ty,
9007 .val = Value.initPayload(&tag_val_payload.base),
9008 });
9009 };
9010 switch_instr.addCase(this_tag_int_value, return_block);9002 switch_instr.addCase(this_tag_int_value, return_block);
90119003
9012 self.builder.positionBuilderAtEnd(return_block);9004 self.builder.positionBuilderAtEnd(return_block);
...@@ -9094,7 +9086,7 @@ pub const FuncGen = struct {...@@ -9094,7 +9086,7 @@ pub const FuncGen = struct {
90949086
9095 for (values, 0..) |*val, i| {9087 for (values, 0..) |*val, i| {
9096 const elem = try mask.elemValue(mod, i);9088 const elem = try mask.elemValue(mod, i);
9097 if (elem.isUndef()) {9089 if (elem.isUndef(mod)) {
9098 val.* = llvm_i32.getUndef();9090 val.* = llvm_i32.getUndef();
9099 } else {9091 } else {
9100 const int = elem.toSignedInt(mod);9092 const int = elem.toSignedInt(mod);
...@@ -9419,11 +9411,7 @@ pub const FuncGen = struct {...@@ -9419,11 +9411,7 @@ pub const FuncGen = struct {
9419 const tag_ty = union_ty.unionTagTypeHypothetical(mod);9411 const tag_ty = union_ty.unionTagTypeHypothetical(mod);
9420 const union_field_name = union_obj.fields.keys()[extra.field_index];9412 const union_field_name = union_obj.fields.keys()[extra.field_index];
9421 const enum_field_index = tag_ty.enumFieldIndex(union_field_name, mod).?;9413 const enum_field_index = tag_ty.enumFieldIndex(union_field_name, mod).?;
9422 var tag_val_payload: Value.Payload.U32 = .{9414 const tag_val = try mod.enumValueFieldIndex(tag_ty, enum_field_index);
9423 .base = .{ .tag = .enum_field_index },
9424 .data = @intCast(u32, enum_field_index),
9425 };
9426 const tag_val = Value.initPayload(&tag_val_payload.base);
9427 const tag_int_val = try tag_val.enumToInt(tag_ty, mod);9415 const tag_int_val = try tag_val.enumToInt(tag_ty, mod);
9428 break :blk tag_int_val.toUnsignedInt(mod);9416 break :blk tag_int_val.toUnsignedInt(mod);
9429 };9417 };
src/codegen/spirv.zig+4-4
...@@ -614,7 +614,7 @@ pub const DeclGen = struct {...@@ -614,7 +614,7 @@ pub const DeclGen = struct {
614 const dg = self.dg;614 const dg = self.dg;
615 const mod = dg.module;615 const mod = dg.module;
616616
617 if (val.isUndef()) {617 if (val.isUndef(mod)) {
618 const size = ty.abiSize(mod);618 const size = ty.abiSize(mod);
619 return try self.addUndef(size);619 return try self.addUndef(size);
620 }620 }
...@@ -882,7 +882,7 @@ pub const DeclGen = struct {...@@ -882,7 +882,7 @@ pub const DeclGen = struct {
882 // const target = self.getTarget();882 // const target = self.getTarget();
883883
884 // TODO: Fix the resulting global linking for these paths.884 // TODO: Fix the resulting global linking for these paths.
885 // if (val.isUndef()) {885 // if (val.isUndef(mod)) {
886 // // Special case: the entire value is undefined. In this case, we can just886 // // Special case: the entire value is undefined. In this case, we can just
887 // // generate an OpVariable with no initializer.887 // // generate an OpVariable with no initializer.
888 // return try section.emit(self.spv.gpa, .OpVariable, .{888 // return try section.emit(self.spv.gpa, .OpVariable, .{
...@@ -978,7 +978,7 @@ pub const DeclGen = struct {...@@ -978,7 +978,7 @@ pub const DeclGen = struct {
978978
979 log.debug("constant: ty = {}, val = {}", .{ ty.fmt(self.module), val.fmtValue(ty, self.module) });979 log.debug("constant: ty = {}, val = {}", .{ ty.fmt(self.module), val.fmtValue(ty, self.module) });
980980
981 if (val.isUndef()) {981 if (val.isUndef(mod)) {
982 return self.spv.constUndef(result_ty_ref);982 return self.spv.constUndef(result_ty_ref);
983 }983 }
984984
...@@ -2091,7 +2091,7 @@ pub const DeclGen = struct {...@@ -2091,7 +2091,7 @@ pub const DeclGen = struct {
2091 var i: usize = 0;2091 var i: usize = 0;
2092 while (i < mask_len) : (i += 1) {2092 while (i < mask_len) : (i += 1) {
2093 const elem = try mask.elemValue(self.module, i);2093 const elem = try mask.elemValue(self.module, i);
2094 if (elem.isUndef()) {2094 if (elem.isUndef(mod)) {
2095 self.func.body.writeOperand(spec.LiteralInteger, 0xFFFF_FFFF);2095 self.func.body.writeOperand(spec.LiteralInteger, 0xFFFF_FFFF);
2096 } else {2096 } else {
2097 const int = elem.toSignedInt(mod);2097 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 {...@@ -1304,7 +1304,7 @@ fn getDeclOutputSection(self: *Coff, decl_index: Module.Decl.Index) u16 {
1304 const zig_ty = ty.zigTypeTag(mod);1304 const zig_ty = ty.zigTypeTag(mod);
1305 const val = decl.val;1305 const val = decl.val;
1306 const index: u16 = blk: {1306 const index: u16 = blk: {
1307 if (val.isUndefDeep()) {1307 if (val.isUndefDeep(mod)) {
1308 // TODO in release-fast and release-small, we should put undef in .bss1308 // TODO in release-fast and release-small, we should put undef in .bss
1309 break :blk self.data_section_index.?;1309 break :blk self.data_section_index.?;
1310 }1310 }
src/link/Elf.zig+1-1
...@@ -2456,7 +2456,7 @@ fn getDeclShdrIndex(self: *Elf, decl_index: Module.Decl.Index) u16 {...@@ -2456,7 +2456,7 @@ fn getDeclShdrIndex(self: *Elf, decl_index: Module.Decl.Index) u16 {
2456 const zig_ty = ty.zigTypeTag(mod);2456 const zig_ty = ty.zigTypeTag(mod);
2457 const val = decl.val;2457 const val = decl.val;
2458 const shdr_index: u16 = blk: {2458 const shdr_index: u16 = blk: {
2459 if (val.isUndefDeep()) {2459 if (val.isUndefDeep(mod)) {
2460 // TODO in release-fast and release-small, we should put undef in .bss2460 // TODO in release-fast and release-small, we should put undef in .bss
2461 break :blk self.data_section_index.?;2461 break :blk self.data_section_index.?;
2462 }2462 }
src/link/MachO.zig+1-1
...@@ -2270,7 +2270,7 @@ fn getDeclOutputSection(self: *MachO, decl_index: Module.Decl.Index) u8 {...@@ -2270,7 +2270,7 @@ fn getDeclOutputSection(self: *MachO, decl_index: Module.Decl.Index) u8 {
2270 const single_threaded = self.base.options.single_threaded;2270 const single_threaded = self.base.options.single_threaded;
2271 const sect_id: u8 = blk: {2271 const sect_id: u8 = blk: {
2272 // TODO finish and audit this function2272 // TODO finish and audit this function
2273 if (val.isUndefDeep()) {2273 if (val.isUndefDeep(mod)) {
2274 if (mode == .ReleaseFast or mode == .ReleaseSmall) {2274 if (mode == .ReleaseFast or mode == .ReleaseSmall) {
2275 @panic("TODO __DATA,__bss");2275 @panic("TODO __DATA,__bss");
2276 } else {2276 } else {
src/link/Wasm.zig+1-1
...@@ -3374,7 +3374,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -3374,7 +3374,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
3374 } else if (decl.getVariable()) |variable| {3374 } else if (decl.getVariable()) |variable| {
3375 if (!variable.is_mutable) {3375 if (!variable.is_mutable) {
3376 try wasm.parseAtom(atom_index, .{ .data = .read_only });3376 try wasm.parseAtom(atom_index, .{ .data = .read_only });
3377 } else if (variable.init.isUndefDeep()) {3377 } else if (variable.init.isUndefDeep(mod)) {
3378 // for safe build modes, we store the atom in the data segment,3378 // for safe build modes, we store the atom in the data segment,
3379 // whereas for unsafe build modes we store it in bss.3379 // whereas for unsafe build modes we store it in bss.
3380 const is_initialized = wasm.base.options.optimize_mode == .Debug or3380 const is_initialized = wasm.base.options.optimize_mode == .Debug or
src/type.zig+33-26
...@@ -126,6 +126,7 @@ pub const Type = struct {...@@ -126,6 +126,7 @@ pub const Type = struct {
126 },126 },
127127
128 // values, not types128 // values, not types
129 .undef => unreachable,
129 .un => unreachable,130 .un => unreachable,
130 .extern_func => unreachable,131 .extern_func => unreachable,
131 .int => unreachable,132 .int => unreachable,
...@@ -1350,6 +1351,7 @@ pub const Type = struct {...@@ -1350,6 +1351,7 @@ pub const Type = struct {
1350 },1351 },
13511352
1352 // values, not types1353 // values, not types
1354 .undef => unreachable,
1353 .un => unreachable,1355 .un => unreachable,
1354 .simple_value => unreachable,1356 .simple_value => unreachable,
1355 .extern_func => unreachable,1357 .extern_func => unreachable,
...@@ -1600,6 +1602,7 @@ pub const Type = struct {...@@ -1600,6 +1602,7 @@ pub const Type = struct {
1600 .enum_type => |enum_type| enum_type.tag_ty.toType().hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat),1602 .enum_type => |enum_type| enum_type.tag_ty.toType().hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat),
16011603
1602 // values, not types1604 // values, not types
1605 .undef => unreachable,
1603 .un => unreachable,1606 .un => unreachable,
1604 .simple_value => unreachable,1607 .simple_value => unreachable,
1605 .extern_func => unreachable,1608 .extern_func => unreachable,
...@@ -1713,6 +1716,7 @@ pub const Type = struct {...@@ -1713,6 +1716,7 @@ pub const Type = struct {
1713 },1716 },
17141717
1715 // values, not types1718 // values, not types
1719 .undef => unreachable,
1716 .un => unreachable,1720 .un => unreachable,
1717 .simple_value => unreachable,1721 .simple_value => unreachable,
1718 .extern_func => unreachable,1722 .extern_func => unreachable,
...@@ -2104,6 +2108,7 @@ pub const Type = struct {...@@ -2104,6 +2108,7 @@ pub const Type = struct {
2104 .enum_type => |enum_type| return AbiAlignmentAdvanced{ .scalar = enum_type.tag_ty.toType().abiAlignment(mod) },2108 .enum_type => |enum_type| return AbiAlignmentAdvanced{ .scalar = enum_type.tag_ty.toType().abiAlignment(mod) },
21052109
2106 // values, not types2110 // values, not types
2111 .undef => unreachable,
2107 .un => unreachable,2112 .un => unreachable,
2108 .simple_value => unreachable,2113 .simple_value => unreachable,
2109 .extern_func => unreachable,2114 .extern_func => unreachable,
...@@ -2499,6 +2504,7 @@ pub const Type = struct {...@@ -2499,6 +2504,7 @@ pub const Type = struct {
2499 .enum_type => |enum_type| return AbiSizeAdvanced{ .scalar = enum_type.tag_ty.toType().abiSize(mod) },2504 .enum_type => |enum_type| return AbiSizeAdvanced{ .scalar = enum_type.tag_ty.toType().abiSize(mod) },
25002505
2501 // values, not types2506 // values, not types
2507 .undef => unreachable,
2502 .un => unreachable,2508 .un => unreachable,
2503 .simple_value => unreachable,2509 .simple_value => unreachable,
2504 .extern_func => unreachable,2510 .extern_func => unreachable,
...@@ -2736,6 +2742,7 @@ pub const Type = struct {...@@ -2736,6 +2742,7 @@ pub const Type = struct {
2736 .enum_type => |enum_type| return bitSizeAdvanced(enum_type.tag_ty.toType(), mod, opt_sema),2742 .enum_type => |enum_type| return bitSizeAdvanced(enum_type.tag_ty.toType(), mod, opt_sema),
27372743
2738 // values, not types2744 // values, not types
2745 .undef => unreachable,
2739 .un => unreachable,2746 .un => unreachable,
2740 .simple_value => unreachable,2747 .simple_value => unreachable,
2741 .extern_func => unreachable,2748 .extern_func => unreachable,
...@@ -3492,6 +3499,7 @@ pub const Type = struct {...@@ -3492,6 +3499,7 @@ pub const Type = struct {
3492 .opaque_type => unreachable,3499 .opaque_type => unreachable,
34933500
3494 // values, not types3501 // values, not types
3502 .undef => unreachable,
3495 .un => unreachable,3503 .un => unreachable,
3496 .simple_value => unreachable,3504 .simple_value => unreachable,
3497 .extern_func => unreachable,3505 .extern_func => unreachable,
...@@ -3826,19 +3834,30 @@ pub const Type = struct {...@@ -3826,19 +3834,30 @@ pub const Type = struct {
3826 .opaque_type => return null,3834 .opaque_type => return null,
3827 .enum_type => |enum_type| switch (enum_type.tag_mode) {3835 .enum_type => |enum_type| switch (enum_type.tag_mode) {
3828 .nonexhaustive => {3836 .nonexhaustive => {
3829 if (enum_type.tag_ty != .comptime_int_type and3837 if (enum_type.tag_ty == .comptime_int_type) return null;
3830 !enum_type.tag_ty.toType().hasRuntimeBits(mod))3838
3831 {3839 if (try enum_type.tag_ty.toType().onePossibleValue(mod)) |int_opv| {
3832 return Value.enum_field_0;3840 const only = try mod.intern(.{ .enum_tag = .{
3833 } else {3841 .ty = ty.ip_index,
3834 return null;3842 .int = int_opv.ip_index,
3843 } });
3844 return only.toValue();
3835 }3845 }
3846
3847 return null;
3836 },3848 },
3837 .auto, .explicit => switch (enum_type.names.len) {3849 .auto, .explicit => switch (enum_type.names.len) {
3838 0 => return Value.@"unreachable",3850 0 => return Value.@"unreachable",
3839 1 => {3851 1 => {
3840 if (enum_type.values.len == 0) {3852 if (enum_type.values.len == 0) {
3841 return Value.enum_field_0; // auto-numbered3853 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();
3842 } else {3861 } else {
3843 return enum_type.values[0].toValue();3862 return enum_type.values[0].toValue();
3844 }3863 }
...@@ -3848,6 +3867,7 @@ pub const Type = struct {...@@ -3848,6 +3867,7 @@ pub const Type = struct {
3848 },3867 },
38493868
3850 // values, not types3869 // values, not types
3870 .undef => unreachable,
3851 .un => unreachable,3871 .un => unreachable,
3852 .simple_value => unreachable,3872 .simple_value => unreachable,
3853 .extern_func => unreachable,3873 .extern_func => unreachable,
...@@ -4006,6 +4026,7 @@ pub const Type = struct {...@@ -4006,6 +4026,7 @@ pub const Type = struct {
4006 .enum_type => |enum_type| enum_type.tag_ty.toType().comptimeOnly(mod),4026 .enum_type => |enum_type| enum_type.tag_ty.toType().comptimeOnly(mod),
40074027
4008 // values, not types4028 // values, not types
4029 .undef => unreachable,
4009 .un => unreachable,4030 .un => unreachable,
4010 .simple_value => unreachable,4031 .simple_value => unreachable,
4011 .extern_func => unreachable,4032 .extern_func => unreachable,
...@@ -4224,36 +4245,22 @@ pub const Type = struct {...@@ -4224,36 +4245,22 @@ pub const Type = struct {
4224 return ip.stringToSlice(field_name);4245 return ip.stringToSlice(field_name);
4225 }4246 }
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 {
4228 const ip = &mod.intern_pool;4249 const ip = &mod.intern_pool;
4229 const enum_type = ip.indexToKey(ty.ip_index).enum_type;4250 const enum_type = ip.indexToKey(ty.ip_index).enum_type;
4230 // If the string is not interned, then the field certainly is not present.4251 // If the string is not interned, then the field certainly is not present.
4231 const field_name_interned = ip.getString(field_name).unwrap() orelse return null;4252 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);
4233 }4254 }
42344255
4235 /// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or4256 /// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or
4236 /// an integer which represents the enum value. Returns the field index in4257 /// an integer which represents the enum value. Returns the field index in
4237 /// declaration order, or `null` if `enum_tag` does not match any field.4258 /// declaration order, or `null` if `enum_tag` does not match any field.
4238 pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?usize {4259 pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?u32 {
4239 if (enum_tag.castTag(.enum_field_index)) |payload| {
4240 return @as(usize, payload.data);
4241 }
4242 const ip = &mod.intern_pool;4260 const ip = &mod.intern_pool;
4243 const enum_type = ip.indexToKey(ty.ip_index).enum_type;4261 const enum_type = ip.indexToKey(ty.ip_index).enum_type;
4244 const tag_ty = enum_type.tag_ty.toType();4262 assert(ip.typeOf(enum_tag.ip_index) == enum_type.tag_ty);
4245 if (enum_type.values.len == 0) {4263 return enum_type.tagValueIndex(ip, enum_tag.ip_index);
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 }
4257 }4264 }
42584265
4259 pub fn structFields(ty: Type, mod: *Module) Module.Struct.Fields {4266 pub fn structFields(ty: Type, mod: *Module) Module.Struct.Fields {
src/value.zig+99-155
...@@ -73,8 +73,6 @@ pub const Value = struct {...@@ -73,8 +73,6 @@ pub const Value = struct {
73 /// Pointer and length as sub `Value` objects.73 /// Pointer and length as sub `Value` objects.
74 slice,74 slice,
75 enum_literal,75 enum_literal,
76 /// A specific enum tag, indicated by the field index (declaration order).
77 enum_field_index,
78 @"error",76 @"error",
79 /// When the type is error union:77 /// When the type is error union:
80 /// * If the tag is `.@"error"`, the error union is an error.78 /// * If the tag is `.@"error"`, the error union is an error.
...@@ -143,8 +141,6 @@ pub const Value = struct {...@@ -143,8 +141,6 @@ pub const Value = struct {
143 .str_lit => Payload.StrLit,141 .str_lit => Payload.StrLit,
144 .slice => Payload.Slice,142 .slice => Payload.Slice,
145143
146 .enum_field_index => Payload.U32,
147
148 .ty,144 .ty,
149 .lazy_align,145 .lazy_align,
150 .lazy_size,146 .lazy_size,
...@@ -397,7 +393,6 @@ pub const Value = struct {...@@ -397,7 +393,6 @@ pub const Value = struct {
397 .legacy = .{ .ptr_otherwise = &new_payload.base },393 .legacy = .{ .ptr_otherwise = &new_payload.base },
398 };394 };
399 },395 },
400 .enum_field_index => return self.copyPayloadShallow(arena, Payload.U32),
401 .@"error" => return self.copyPayloadShallow(arena, Payload.Error),396 .@"error" => return self.copyPayloadShallow(arena, Payload.Error),
402397
403 .aggregate => {398 .aggregate => {
...@@ -515,7 +510,6 @@ pub const Value = struct {...@@ -515,7 +510,6 @@ pub const Value = struct {
515 },510 },
516 .empty_array => return out_stream.writeAll(".{}"),511 .empty_array => return out_stream.writeAll(".{}"),
517 .enum_literal => return out_stream.print(".{}", .{std.zig.fmtId(val.castTag(.enum_literal).?.data)}),512 .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}),
519 .bytes => return out_stream.print("\"{}\"", .{std.zig.fmtEscapes(val.castTag(.bytes).?.data)}),513 .bytes => return out_stream.print("\"{}\"", .{std.zig.fmtEscapes(val.castTag(.bytes).?.data)}),
520 .str_lit => {514 .str_lit => {
521 const str_lit = val.castTag(.str_lit).?.data;515 const str_lit = val.castTag(.str_lit).?.data;
...@@ -618,87 +612,58 @@ pub const Value = struct {...@@ -618,87 +612,58 @@ pub const Value = struct {
618 };612 };
619 }613 }
620614
621 /// Asserts the type is an enum type.615 pub fn enumToInt(val: Value, ty: Type, mod: *Module) Allocator.Error!Value {
622 pub fn toEnum(val: Value, comptime E: type) E {616 const ip = &mod.intern_pool;
623 switch (val.ip_index) {617 switch (val.ip_index) {
624 .calling_convention_c => {618 .none => {
625 if (E == std.builtin.CallingConvention) {619 const field_index = switch (val.tag()) {
626 return .C;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();
627 } else {633 } else {
628 unreachable;634 // Field index and integer values are the same.
635 return mod.intValue(enum_type.tag_ty.toType(), field_index);
629 }636 }
630 },637 },
631 .calling_convention_inline => {638 else => {
632 if (E == std.builtin.CallingConvention) {639 const enum_type = ip.indexToKey(ip.typeOf(val.ip_index)).enum_type;
633 return .Inline;640 const int = try ip.getCoerced(mod.gpa, val.ip_index, enum_type.tag_ty);
634 } else {641 return int.toValue();
635 unreachable;
636 }
637 },642 },
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,
651 }643 }
652 }644 }
653645
654 pub fn enumToInt(val: Value, ty: Type, mod: *Module) Allocator.Error!Value {646 pub fn tagName(val: Value, ty: Type, mod: *Module) []const u8 {
655 const field_index = switch (val.tag()) {647 _ = ty; // TODO: remove this parameter now that we use InternPool
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 };
668648
669 const enum_type = mod.intern_pool.indexToKey(ty.ip_index).enum_type;649 if (val.castTag(.enum_literal)) |payload| {
670 if (enum_type.values.len != 0) {650 return payload.data;
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);
675 }651 }
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()) {655 const enum_tag = switch (ip.indexToKey(val.ip_index)) {
684 .enum_field_index => val.castTag(.enum_field_index).?.data,656 .un => |un| ip.indexToKey(un.tag).enum_tag,
685 .the_only_possible_value => blk: {657 .enum_tag => |x| x,
686 assert(ty.enumFieldCount(mod) == 1);658 else => unreachable,
687 break :blk 0;659 };
688 },660 const enum_type = ip.indexToKey(enum_tag.ty).enum_type;
689 .enum_literal => return val.castTag(.enum_literal).?.data,661 const field_index = field_index: {
690 else => field_index: {662 const field_index = enum_type.tagValueIndex(ip, val.ip_index).?;
691 if (enum_type.values.len == 0) {663 break :field_index @intCast(u32, field_index);
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 },
698 };664 };
699
700 const field_name = enum_type.names[field_index];665 const field_name = enum_type.names[field_index];
701 return mod.intern_pool.stringToSlice(field_name);666 return ip.stringToSlice(field_name);
702 }667 }
703668
704 /// Asserts the value is an integer.669 /// Asserts the value is an integer.
...@@ -722,10 +687,6 @@ pub const Value = struct {...@@ -722,10 +687,6 @@ pub const Value = struct {
722 .the_only_possible_value, // i0, u0687 .the_only_possible_value, // i0, u0
723 => BigIntMutable.init(&space.limbs, 0).toConst(),688 => 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 },
729 .runtime_value => {690 .runtime_value => {
730 const sub_val = val.castTag(.runtime_value).?.data;691 const sub_val = val.castTag(.runtime_value).?.data;
731 return sub_val.toBigIntAdvanced(space, mod, opt_sema);692 return sub_val.toBigIntAdvanced(space, mod, opt_sema);
...@@ -759,6 +720,7 @@ pub const Value = struct {...@@ -759,6 +720,7 @@ pub const Value = struct {
759 },720 },
760 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {721 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
761 .int => |int| int.storage.toBigInt(space),722 .int => |int| int.storage.toBigInt(space),
723 .enum_tag => |enum_tag| mod.intern_pool.indexToKey(enum_tag.int).int.storage.toBigInt(space),
762 else => unreachable,724 else => unreachable,
763 },725 },
764 };726 };
...@@ -886,7 +848,7 @@ pub const Value = struct {...@@ -886,7 +848,7 @@ pub const Value = struct {
886 }!void {848 }!void {
887 const target = mod.getTarget();849 const target = mod.getTarget();
888 const endian = target.cpu.arch.endian();850 const endian = target.cpu.arch.endian();
889 if (val.isUndef()) {851 if (val.isUndef(mod)) {
890 const size = @intCast(usize, ty.abiSize(mod));852 const size = @intCast(usize, ty.abiSize(mod));
891 @memset(buffer[0..size], 0xaa);853 @memset(buffer[0..size], 0xaa);
892 return;854 return;
...@@ -1007,7 +969,7 @@ pub const Value = struct {...@@ -1007,7 +969,7 @@ pub const Value = struct {
1007 ) error{ ReinterpretDeclRef, OutOfMemory }!void {969 ) error{ ReinterpretDeclRef, OutOfMemory }!void {
1008 const target = mod.getTarget();970 const target = mod.getTarget();
1009 const endian = target.cpu.arch.endian();971 const endian = target.cpu.arch.endian();
1010 if (val.isUndef()) {972 if (val.isUndef(mod)) {
1011 const bit_size = @intCast(usize, ty.bitSize(mod));973 const bit_size = @intCast(usize, ty.bitSize(mod));
1012 std.mem.writeVarPackedInt(buffer, bit_offset, bit_size, @as(u1, 0), endian);974 std.mem.writeVarPackedInt(buffer, bit_offset, bit_size, @as(u1, 0), endian);
1013 return;975 return;
...@@ -1087,7 +1049,7 @@ pub const Value = struct {...@@ -1087,7 +1049,7 @@ pub const Value = struct {
1087 .Auto => unreachable, // Sema is supposed to have emitted a compile error already1049 .Auto => unreachable, // Sema is supposed to have emitted a compile error already
1088 .Extern => unreachable, // Handled in non-packed writeToMemory1050 .Extern => unreachable, // Handled in non-packed writeToMemory
1089 .Packed => {1051 .Packed => {
1090 const field_index = ty.unionTagFieldIndex(val.unionTag(), mod);1052 const field_index = ty.unionTagFieldIndex(val.unionTag(mod), mod);
1091 const field_type = ty.unionFields(mod).values()[field_index.?].ty;1053 const field_type = ty.unionFields(mod).values()[field_index.?].ty;
1092 const field_val = try val.fieldValue(field_type, mod, field_index.?);1054 const field_val = try val.fieldValue(field_type, mod, field_index.?);
10931055
...@@ -1432,7 +1394,7 @@ pub const Value = struct {...@@ -1432,7 +1394,7 @@ pub const Value = struct {
1432 }1394 }
14331395
1434 pub fn popCount(val: Value, ty: Type, mod: *Module) u64 {1396 pub fn popCount(val: Value, ty: Type, mod: *Module) u64 {
1435 assert(!val.isUndef());1397 assert(!val.isUndef(mod));
1436 switch (val.ip_index) {1398 switch (val.ip_index) {
1437 .bool_false => return 0,1399 .bool_false => return 0,
1438 .bool_true => return 1,1400 .bool_true => return 1,
...@@ -1450,7 +1412,7 @@ pub const Value = struct {...@@ -1450,7 +1412,7 @@ pub const Value = struct {
1450 }1412 }
14511413
1452 pub fn bitReverse(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {1414 pub fn bitReverse(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {
1453 assert(!val.isUndef());1415 assert(!val.isUndef(mod));
14541416
1455 const info = ty.intInfo(mod);1417 const info = ty.intInfo(mod);
14561418
...@@ -1468,7 +1430,7 @@ pub const Value = struct {...@@ -1468,7 +1430,7 @@ pub const Value = struct {
1468 }1430 }
14691431
1470 pub fn byteSwap(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {1432 pub fn byteSwap(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {
1471 assert(!val.isUndef());1433 assert(!val.isUndef(mod));
14721434
1473 const info = ty.intInfo(mod);1435 const info = ty.intInfo(mod);
14741436
...@@ -1578,7 +1540,6 @@ pub const Value = struct {...@@ -1578,7 +1540,6 @@ pub const Value = struct {
1578 .variable,1540 .variable,
1579 => .gt,1541 => .gt,
15801542
1581 .enum_field_index => return std.math.order(lhs.castTag(.enum_field_index).?.data, 0),
1582 .runtime_value => {1543 .runtime_value => {
1583 // This is needed to correctly handle hashing the value.1544 // This is needed to correctly handle hashing the value.
1584 // Checks in Sema should prevent direct comparisons from reaching here.1545 // Checks in Sema should prevent direct comparisons from reaching here.
...@@ -1633,6 +1594,10 @@ pub const Value = struct {...@@ -1633,6 +1594,10 @@ pub const Value = struct {
1633 .big_int => |big_int| big_int.orderAgainstScalar(0),1594 .big_int => |big_int| big_int.orderAgainstScalar(0),
1634 inline .u64, .i64 => |x| std.math.order(x, 0),1595 inline .u64, .i64 => |x| std.math.order(x, 0),
1635 },1596 },
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 },
1636 .float => |float| switch (float.storage) {1601 .float => |float| switch (float.storage) {
1637 inline else => |x| std.math.order(x, 0),1602 inline else => |x| std.math.order(x, 0),
1638 },1603 },
...@@ -1861,11 +1826,6 @@ pub const Value = struct {...@@ -1861,11 +1826,6 @@ pub const Value = struct {
1861 const b_name = b.castTag(.enum_literal).?.data;1826 const b_name = b.castTag(.enum_literal).?.data;
1862 return std.mem.eql(u8, a_name, b_name);1827 return std.mem.eql(u8, a_name, b_name);
1863 },1828 },
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 },
1869 .opt_payload => {1829 .opt_payload => {
1870 const a_payload = a.castTag(.opt_payload).?.data;1830 const a_payload = a.castTag(.opt_payload).?.data;
1871 const b_payload = b.castTag(.opt_payload).?.data;1831 const b_payload = b.castTag(.opt_payload).?.data;
...@@ -2064,13 +2024,9 @@ pub const Value = struct {...@@ -2064,13 +2024,9 @@ pub const Value = struct {
2064 }2024 }
2065 const field_name = tuple.names[0];2025 const field_name = tuple.names[0];
2066 const union_obj = mod.typeToUnion(ty).?;2026 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);
2068 const tag_and_val = b.castTag(.@"union").?.data;2028 const tag_and_val = b.castTag(.@"union").?.data;
2069 var field_tag_buf: Value.Payload.U32 = .{2029 const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, field_index);
2070 .base = .{ .tag = .enum_field_index },
2071 .data = @intCast(u32, field_index),
2072 };
2073 const field_tag = Value.initPayload(&field_tag_buf.base);
2074 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, mod);2030 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, mod);
2075 if (!tag_matches) return false;2031 if (!tag_matches) return false;
2076 return eqlAdvanced(tag_and_val.val, union_obj.tag_ty, tuple.values[0], tuple.types[0], mod, opt_sema);2032 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 {...@@ -2132,7 +2088,7 @@ pub const Value = struct {
2132 }2088 }
2133 const zig_ty_tag = ty.zigTypeTag(mod);2089 const zig_ty_tag = ty.zigTypeTag(mod);
2134 std.hash.autoHash(hasher, zig_ty_tag);2090 std.hash.autoHash(hasher, zig_ty_tag);
2135 if (val.isUndef()) return;2091 if (val.isUndef(mod)) return;
2136 // The value is runtime-known and shouldn't affect the hash.2092 // The value is runtime-known and shouldn't affect the hash.
2137 if (val.isRuntimeValue()) return;2093 if (val.isRuntimeValue()) return;
21382094
...@@ -2277,7 +2233,7 @@ pub const Value = struct {...@@ -2277,7 +2233,7 @@ pub const Value = struct {
2277 /// This function is used by hash maps and so treats floating-point NaNs as equal2233 /// This function is used by hash maps and so treats floating-point NaNs as equal
2278 /// to each other, and not equal to other floating-point values.2234 /// to each other, and not equal to other floating-point values.
2279 pub fn hashUncoerced(val: Value, ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void {2235 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;
2281 // The value is runtime-known and shouldn't affect the hash.2237 // The value is runtime-known and shouldn't affect the hash.
2282 if (val.isRuntimeValue()) return;2238 if (val.isRuntimeValue()) return;
22832239
...@@ -2726,16 +2682,12 @@ pub const Value = struct {...@@ -2726,16 +2682,12 @@ pub const Value = struct {
2726 }2682 }
2727 }2683 }
27282684
2729 pub fn unionTag(val: Value) Value {2685 pub fn unionTag(val: Value, mod: *Module) Value {
2730 switch (val.ip_index) {2686 return switch (mod.intern_pool.indexToKey(val.ip_index)) {
2731 .undef => return val,2687 .undef, .enum_tag => val,
2732 .none => switch (val.tag()) {2688 .un => |un| un.tag.toValue(),
2733 .enum_field_index => return val,
2734 .@"union" => return val.castTag(.@"union").?.data.tag,
2735 else => unreachable,
2736 },
2737 else => unreachable,2689 else => unreachable,
2738 }2690 };
2739 }2691 }
27402692
2741 /// Returns a pointer to the element value at the index.2693 /// Returns a pointer to the element value at the index.
...@@ -2769,27 +2721,30 @@ pub const Value = struct {...@@ -2769,27 +2721,30 @@ pub const Value = struct {
2769 });2721 });
2770 }2722 }
27712723
2772 pub fn isUndef(val: Value) bool {2724 pub fn isUndef(val: Value, mod: *Module) bool {
2773 return val.ip_index == .undef;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 };
2774 }2731 }
27752732
2776 /// TODO: check for cases such as array that is not marked undef but all the element2733 /// TODO: check for cases such as array that is not marked undef but all the element
2777 /// values are marked undef, or struct that is not marked undef but all fields are marked2734 /// values are marked undef, or struct that is not marked undef but all fields are marked
2778 /// undef, etc.2735 /// undef, etc.
2779 pub fn isUndefDeep(val: Value) bool {2736 pub fn isUndefDeep(val: Value, mod: *Module) bool {
2780 return val.isUndef();2737 return val.isUndef(mod);
2781 }2738 }
27822739
2783 /// Returns true if any value contained in `self` is undefined.2740 /// 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 element2741 pub fn anyUndef(val: Value, mod: *Module) !bool {
2785 /// values are marked undef, or struct that is not marked undef but all fields are marked2742 if (val.ip_index == .none) return false;
2786 /// undef, etc.2743 switch (val.ip_index) {
2787 pub fn anyUndef(self: Value, mod: *Module) !bool {
2788 switch (self.ip_index) {
2789 .undef => return true,2744 .undef => return true,
2790 .none => switch (self.tag()) {2745 .none => switch (val.tag()) {
2791 .slice => {2746 .slice => {
2792 const payload = self.castTag(.slice).?;2747 const payload = val.castTag(.slice).?;
2793 const len = payload.data.len.toUnsignedInt(mod);2748 const len = payload.data.len.toUnsignedInt(mod);
27942749
2795 for (0..len) |i| {2750 for (0..len) |i| {
...@@ -2799,14 +2754,21 @@ pub const Value = struct {...@@ -2799,14 +2754,21 @@ pub const Value = struct {
2799 },2754 },
28002755
2801 .aggregate => {2756 .aggregate => {
2802 const payload = self.castTag(.aggregate).?;2757 const payload = val.castTag(.aggregate).?;
2803 for (payload.data) |val| {2758 for (payload.data) |field| {
2804 if (try val.anyUndef(mod)) return true;2759 if (try field.anyUndef(mod)) return true;
2805 }2760 }
2806 },2761 },
2807 else => {},2762 else => {},
2808 },2763 },
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 },
2810 }2772 }
28112773
2812 return false;2774 return false;
...@@ -2819,11 +2781,7 @@ pub const Value = struct {...@@ -2819,11 +2781,7 @@ pub const Value = struct {
2819 .undef => unreachable,2781 .undef => unreachable,
2820 .unreachable_value => unreachable,2782 .unreachable_value => unreachable,
28212783
2822 .null_value,2784 .null_value => true,
2823 .zero,
2824 .zero_usize,
2825 .zero_u8,
2826 => true,
28272785
2828 .none => switch (val.tag()) {2786 .none => switch (val.tag()) {
2829 .opt_payload => false,2787 .opt_payload => false,
...@@ -2843,6 +2801,7 @@ pub const Value = struct {...@@ -2843,6 +2801,7 @@ pub const Value = struct {
2843 .big_int => |big_int| big_int.eqZero(),2801 .big_int => |big_int| big_int.eqZero(),
2844 inline .u64, .i64 => |x| x == 0,2802 inline .u64, .i64 => |x| x == 0,
2845 },2803 },
2804 .opt => |opt| opt.val == .none,
2846 else => unreachable,2805 else => unreachable,
2847 },2806 },
2848 };2807 };
...@@ -3024,8 +2983,8 @@ pub const Value = struct {...@@ -3024,8 +2983,8 @@ pub const Value = struct {
3024 arena: Allocator,2983 arena: Allocator,
3025 mod: *Module,2984 mod: *Module,
3026 ) !Value {2985 ) !Value {
3027 assert(!lhs.isUndef());2986 assert(!lhs.isUndef(mod));
3028 assert(!rhs.isUndef());2987 assert(!rhs.isUndef(mod));
30292988
3030 const info = ty.intInfo(mod);2989 const info = ty.intInfo(mod);
30312990
...@@ -3071,8 +3030,8 @@ pub const Value = struct {...@@ -3071,8 +3030,8 @@ pub const Value = struct {
3071 arena: Allocator,3030 arena: Allocator,
3072 mod: *Module,3031 mod: *Module,
3073 ) !Value {3032 ) !Value {
3074 assert(!lhs.isUndef());3033 assert(!lhs.isUndef(mod));
3075 assert(!rhs.isUndef());3034 assert(!rhs.isUndef(mod));
30763035
3077 const info = ty.intInfo(mod);3036 const info = ty.intInfo(mod);
30783037
...@@ -3178,7 +3137,7 @@ pub const Value = struct {...@@ -3178,7 +3137,7 @@ pub const Value = struct {
3178 arena: Allocator,3137 arena: Allocator,
3179 mod: *Module,3138 mod: *Module,
3180 ) !Value {3139 ) !Value {
3181 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;3140 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.undef;
31823141
3183 if (ty.zigTypeTag(mod) == .ComptimeInt) {3142 if (ty.zigTypeTag(mod) == .ComptimeInt) {
3184 return intMul(lhs, rhs, ty, arena, mod);3143 return intMul(lhs, rhs, ty, arena, mod);
...@@ -3220,8 +3179,8 @@ pub const Value = struct {...@@ -3220,8 +3179,8 @@ pub const Value = struct {
3220 arena: Allocator,3179 arena: Allocator,
3221 mod: *Module,3180 mod: *Module,
3222 ) !Value {3181 ) !Value {
3223 assert(!lhs.isUndef());3182 assert(!lhs.isUndef(mod));
3224 assert(!rhs.isUndef());3183 assert(!rhs.isUndef(mod));
32253184
3226 const info = ty.intInfo(mod);3185 const info = ty.intInfo(mod);
32273186
...@@ -3249,7 +3208,7 @@ pub const Value = struct {...@@ -3249,7 +3208,7 @@ pub const Value = struct {
32493208
3250 /// Supports both floats and ints; handles undefined.3209 /// Supports both floats and ints; handles undefined.
3251 pub fn numberMax(lhs: Value, rhs: Value, mod: *Module) Value {3210 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;
3253 if (lhs.isNan(mod)) return rhs;3212 if (lhs.isNan(mod)) return rhs;
3254 if (rhs.isNan(mod)) return lhs;3213 if (rhs.isNan(mod)) return lhs;
32553214
...@@ -3261,7 +3220,7 @@ pub const Value = struct {...@@ -3261,7 +3220,7 @@ pub const Value = struct {
32613220
3262 /// Supports both floats and ints; handles undefined.3221 /// Supports both floats and ints; handles undefined.
3263 pub fn numberMin(lhs: Value, rhs: Value, mod: *Module) Value {3222 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;
3265 if (lhs.isNan(mod)) return rhs;3224 if (lhs.isNan(mod)) return rhs;
3266 if (rhs.isNan(mod)) return lhs;3225 if (rhs.isNan(mod)) return lhs;
32673226
...@@ -3286,7 +3245,7 @@ pub const Value = struct {...@@ -3286,7 +3245,7 @@ pub const Value = struct {
32863245
3287 /// operands must be integers; handles undefined.3246 /// operands must be integers; handles undefined.
3288 pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value {3247 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
3291 const info = ty.intInfo(mod);3250 const info = ty.intInfo(mod);
32923251
...@@ -3324,7 +3283,7 @@ pub const Value = struct {...@@ -3324,7 +3283,7 @@ pub const Value = struct {
33243283
3325 /// operands must be integers; handles undefined.3284 /// operands must be integers; handles undefined.
3326 pub fn bitwiseAndScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {3285 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
3329 // TODO is this a performance issue? maybe we should try the operation without3288 // TODO is this a performance issue? maybe we should try the operation without
3330 // resorting to BigInt first.3289 // resorting to BigInt first.
...@@ -3358,7 +3317,7 @@ pub const Value = struct {...@@ -3358,7 +3317,7 @@ pub const Value = struct {
33583317
3359 /// operands must be integers; handles undefined.3318 /// operands must be integers; handles undefined.
3360 pub fn bitwiseNandScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {3319 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
3363 const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod);3322 const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod);
3364 const all_ones = if (ty.isSignedInt(mod)) try mod.intValue(ty, -1) else try ty.maxIntScalar(mod, ty);3323 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 {...@@ -3381,7 +3340,7 @@ pub const Value = struct {
33813340
3382 /// operands must be integers; handles undefined.3341 /// operands must be integers; handles undefined.
3383 pub fn bitwiseOrScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {3342 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
3386 // TODO is this a performance issue? maybe we should try the operation without3345 // TODO is this a performance issue? maybe we should try the operation without
3387 // resorting to BigInt first.3346 // resorting to BigInt first.
...@@ -3415,7 +3374,7 @@ pub const Value = struct {...@@ -3415,7 +3374,7 @@ pub const Value = struct {
34153374
3416 /// operands must be integers; handles undefined.3375 /// operands must be integers; handles undefined.
3417 pub fn bitwiseXorScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {3376 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
3420 // TODO is this a performance issue? maybe we should try the operation without3379 // TODO is this a performance issue? maybe we should try the operation without
3421 // resorting to BigInt first.3380 // resorting to BigInt first.
...@@ -4697,11 +4656,6 @@ pub const Value = struct {...@@ -4697,11 +4656,6 @@ pub const Value = struct {
4697 pub const Payload = struct {4656 pub const Payload = struct {
4698 tag: Tag,4657 tag: Tag,
46994658
4700 pub const U32 = struct {
4701 base: Payload,
4702 data: u32,
4703 };
4704
4705 pub const Function = struct {4659 pub const Function = struct {
4706 base: Payload,4660 base: Payload,
4707 data: *Module.Fn,4661 data: *Module.Fn,
...@@ -4885,16 +4839,6 @@ pub const Value = struct {...@@ -4885,16 +4839,6 @@ pub const Value = struct {
4885 pub const generic_poison_type: Value = .{ .ip_index = .generic_poison_type, .legacy = undefined };4839 pub const generic_poison_type: Value = .{ .ip_index = .generic_poison_type, .legacy = undefined };
4886 pub const empty_struct: Value = .{ .ip_index = .empty_struct, .legacy = undefined };4840 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
4898 pub fn makeBool(x: bool) Value {4842 pub fn makeBool(x: bool) Value {
4899 return if (x) Value.true else Value.false;4843 return if (x) Value.true else Value.false;
4900 }4844 }