authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-06-03 20:22:05-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-06-20 14:02:08-04:00
logad3e0e4eb4afc3f633f5f8f04affc3e9ff886cb6
treee4fb117e0cb673ee4dbea06621d9e284882a8721
parent3c4b58cea76e51da1b79dee9e6c0a5cd2627a283

Sema: optimize typeHasOnePossibleValue


4 files changed, 322 insertions(+), 209 deletions(-)

src/Air.zig+3
......@@ -850,6 +850,8 @@ pub const Inst = struct {
850850 pub const Index = u32;
851851
852852 pub const Ref = enum(u32) {
853 u0_type = @intFromEnum(InternPool.Index.u0_type),
854 i0_type = @intFromEnum(InternPool.Index.i0_type),
853855 u1_type = @intFromEnum(InternPool.Index.u1_type),
854856 u8_type = @intFromEnum(InternPool.Index.u8_type),
855857 i8_type = @intFromEnum(InternPool.Index.i8_type),
......@@ -909,6 +911,7 @@ pub const Inst = struct {
909911 single_const_pointer_to_comptime_int_type = @intFromEnum(InternPool.Index.single_const_pointer_to_comptime_int_type),
910912 slice_const_u8_type = @intFromEnum(InternPool.Index.slice_const_u8_type),
911913 slice_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.slice_const_u8_sentinel_0_type),
914 optional_noreturn_type = @intFromEnum(InternPool.Index.optional_noreturn_type),
912915 anyerror_void_error_union_type = @intFromEnum(InternPool.Index.anyerror_void_error_union_type),
913916 generic_poison_type = @intFromEnum(InternPool.Index.generic_poison_type),
914917 empty_struct_type = @intFromEnum(InternPool.Index.empty_struct_type),
src/InternPool.zig+30-6
......@@ -1243,11 +1243,13 @@ pub const Item = struct {
12431243/// When adding a tag to this enum, consider adding a corresponding entry to
12441244/// `primitives` in AstGen.zig.
12451245pub const Index = enum(u32) {
1246 pub const first_type: Index = .u1_type;
1246 pub const first_type: Index = .u0_type;
12471247 pub const last_type: Index = .empty_struct_type;
12481248 pub const first_value: Index = .undef;
12491249 pub const last_value: Index = .empty_struct;
12501250
1251 u0_type,
1252 i0_type,
12511253 u1_type,
12521254 u8_type,
12531255 i8_type,
......@@ -1307,6 +1309,7 @@ pub const Index = enum(u32) {
13071309 single_const_pointer_to_comptime_int_type,
13081310 slice_const_u8_type,
13091311 slice_const_u8_sentinel_0_type,
1312 optional_noreturn_type,
13101313 anyerror_void_error_union_type,
13111314 generic_poison_type,
13121315 /// `@TypeOf(.{})`
......@@ -1533,6 +1536,16 @@ pub const Index = enum(u32) {
15331536};
15341537
15351538pub const static_keys = [_]Key{
1539 .{ .int_type = .{
1540 .signedness = .unsigned,
1541 .bits = 0,
1542 } },
1543
1544 .{ .int_type = .{
1545 .signedness = .signed,
1546 .bits = 0,
1547 } },
1548
15361549 .{ .int_type = .{
15371550 .signedness = .unsigned,
15381551 .bits = 1,
......@@ -1639,6 +1652,7 @@ pub const static_keys = [_]Key{
16391652 .{ .simple_type = .extern_options },
16401653 .{ .simple_type = .type_info },
16411654
1655 // [*]u8
16421656 .{ .ptr_type = .{
16431657 .child = .u8_type,
16441658 .flags = .{
......@@ -1646,7 +1660,7 @@ pub const static_keys = [_]Key{
16461660 },
16471661 } },
16481662
1649 // manyptr_const_u8_type
1663 // [*]const u8
16501664 .{ .ptr_type = .{
16511665 .child = .u8_type,
16521666 .flags = .{
......@@ -1655,7 +1669,7 @@ pub const static_keys = [_]Key{
16551669 },
16561670 } },
16571671
1658 // manyptr_const_u8_sentinel_0_type
1672 // [*:0]const u8
16591673 .{ .ptr_type = .{
16601674 .child = .u8_type,
16611675 .sentinel = .zero_u8,
......@@ -1665,6 +1679,7 @@ pub const static_keys = [_]Key{
16651679 },
16661680 } },
16671681
1682 // comptime_int
16681683 .{ .ptr_type = .{
16691684 .child = .comptime_int_type,
16701685 .flags = .{
......@@ -1673,7 +1688,7 @@ pub const static_keys = [_]Key{
16731688 },
16741689 } },
16751690
1676 // slice_const_u8_type
1691 // []const u8
16771692 .{ .ptr_type = .{
16781693 .child = .u8_type,
16791694 .flags = .{
......@@ -1682,7 +1697,7 @@ pub const static_keys = [_]Key{
16821697 },
16831698 } },
16841699
1685 // slice_const_u8_sentinel_0_type
1700 // [:0]const u8
16861701 .{ .ptr_type = .{
16871702 .child = .u8_type,
16881703 .sentinel = .zero_u8,
......@@ -1692,7 +1707,10 @@ pub const static_keys = [_]Key{
16921707 },
16931708 } },
16941709
1695 // anyerror_void_error_union_type
1710 // ?noreturn
1711 .{ .opt_type = .noreturn_type },
1712
1713 // anyerror!void
16961714 .{ .error_union_type = .{
16971715 .error_set_type = .anyerror_type,
16981716 .payload_type = .void_type,
......@@ -5465,6 +5483,8 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
54655483 // An alternative would be to topological sort the static keys, but this would
54665484 // mean that the range of type indices would not be dense.
54675485 return switch (index) {
5486 .u0_type,
5487 .i0_type,
54685488 .u1_type,
54695489 .u8_type,
54705490 .i8_type,
......@@ -5524,6 +5544,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
55245544 .single_const_pointer_to_comptime_int_type,
55255545 .slice_const_u8_type,
55265546 .slice_const_u8_sentinel_0_type,
5547 .optional_noreturn_type,
55275548 .anyerror_void_error_union_type,
55285549 .generic_poison_type,
55295550 .empty_struct_type,
......@@ -5685,6 +5706,8 @@ pub fn isNoReturn(ip: *const InternPool, ty: Index) bool {
56855706/// rather than the more straightforward implementation of calling `indexToKey`.
56865707pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPoison}!std.builtin.TypeId {
56875708 return switch (index) {
5709 .u0_type,
5710 .i0_type,
56885711 .u1_type,
56895712 .u8_type,
56905713 .i8_type,
......@@ -5756,6 +5779,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
57565779 .slice_const_u8_sentinel_0_type,
57575780 => .Pointer,
57585781
5782 .optional_noreturn_type => .Optional,
57595783 .anyerror_void_error_union_type => .ErrorUnion,
57605784 .empty_struct_type => .Struct,
57615785
src/Sema.zig+286-203
......@@ -33749,6 +33749,8 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
3374933749
3375033750 .none => unreachable,
3375133751
33752 .u0_type,
33753 .i0_type,
3375233754 .u1_type,
3375333755 .u8_type,
3375433756 .i8_type,
......@@ -33797,6 +33799,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
3379733799 .single_const_pointer_to_comptime_int_type,
3379833800 .slice_const_u8_type,
3379933801 .slice_const_u8_sentinel_0_type,
33802 .optional_noreturn_type,
3380033803 .anyerror_void_error_union_type,
3380133804 .generic_poison_type,
3380233805 .empty_struct_type,
......@@ -34935,231 +34938,311 @@ fn getBuiltinType(sema: *Sema, name: []const u8) CompileError!Type {
3493534938pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3493634939 const mod = sema.mod;
3493734940 return switch (ty.toIntern()) {
34941 .u0_type,
34942 .i0_type,
34943 => try mod.intValue(ty, 0),
34944 .u1_type,
34945 .u8_type,
34946 .i8_type,
34947 .u16_type,
34948 .i16_type,
34949 .u29_type,
34950 .u32_type,
34951 .i32_type,
34952 .u64_type,
34953 .i64_type,
34954 .u80_type,
34955 .u128_type,
34956 .i128_type,
34957 .usize_type,
34958 .isize_type,
34959 .c_char_type,
34960 .c_short_type,
34961 .c_ushort_type,
34962 .c_int_type,
34963 .c_uint_type,
34964 .c_long_type,
34965 .c_ulong_type,
34966 .c_longlong_type,
34967 .c_ulonglong_type,
34968 .c_longdouble_type,
34969 .f16_type,
34970 .f32_type,
34971 .f64_type,
34972 .f80_type,
34973 .f128_type,
34974 .anyopaque_type,
34975 .bool_type,
34976 .type_type,
34977 .anyerror_type,
34978 .comptime_int_type,
34979 .comptime_float_type,
34980 .enum_literal_type,
34981 .atomic_order_type,
34982 .atomic_rmw_op_type,
34983 .calling_convention_type,
34984 .address_space_type,
34985 .float_mode_type,
34986 .reduce_op_type,
34987 .call_modifier_type,
34988 .prefetch_options_type,
34989 .export_options_type,
34990 .extern_options_type,
34991 .type_info_type,
34992 .manyptr_u8_type,
34993 .manyptr_const_u8_type,
34994 .manyptr_const_u8_sentinel_0_type,
34995 .single_const_pointer_to_comptime_int_type,
34996 .slice_const_u8_type,
34997 .slice_const_u8_sentinel_0_type,
34998 .anyerror_void_error_union_type,
34999 => null,
35000 .void_type => Value.void,
35001 .noreturn_type => Value.@"unreachable",
35002 .anyframe_type => unreachable,
35003 .null_type => Value.null,
35004 .undefined_type => Value.undef,
35005 .optional_noreturn_type => try mod.nullValue(ty),
35006 .generic_poison_type => error.GenericPoison,
3493835007 .empty_struct_type => Value.empty_struct,
34939 else => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
34940 .int_type => |int_type| {
34941 if (int_type.bits == 0) {
34942 return try mod.intValue(ty, 0);
34943 } else {
34944 return null;
34945 }
34946 },
34947
34948 .ptr_type,
34949 .error_union_type,
34950 .func_type,
34951 .anyframe_type,
34952 .error_set_type,
34953 .inferred_error_set_type,
35008 // values, not types
35009 .undef,
35010 .zero,
35011 .zero_usize,
35012 .zero_u8,
35013 .one,
35014 .one_usize,
35015 .one_u8,
35016 .four_u8,
35017 .negative_one,
35018 .calling_convention_c,
35019 .calling_convention_inline,
35020 .void_value,
35021 .unreachable_value,
35022 .null_value,
35023 .bool_true,
35024 .bool_false,
35025 .empty_struct,
35026 .generic_poison,
35027 // invalid
35028 .var_args_param_type,
35029 .none,
35030 => unreachable,
35031 _ => switch (mod.intern_pool.items.items(.tag)[@intFromEnum(ty.toIntern())]) {
35032 .type_int_signed, // i0 handled above
35033 .type_int_unsigned, // u0 handled above
35034 .type_pointer,
35035 .type_slice,
35036 .type_optional, // ?noreturn handled above
35037 .type_anyframe,
35038 .type_error_union,
35039 .type_error_set,
35040 .type_inferred_error_set,
35041 .type_opaque,
35042 .type_function,
3495435043 => null,
34955
34956 inline .array_type, .vector_type => |seq_type, seq_tag| {
34957 const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none;
34958 if (seq_type.len + @intFromBool(has_sentinel) == 0) return (try mod.intern(.{ .aggregate = .{
34959 .ty = ty.toIntern(),
34960 .storage = .{ .elems = &.{} },
34961 } })).toValue();
34962
34963 if (try sema.typeHasOnePossibleValue(seq_type.child.toType())) |opv| {
34964 return (try mod.intern(.{ .aggregate = .{
35044 .simple_type, // handled above
35045 // values, not types
35046 .undef,
35047 .runtime_value,
35048 .simple_value,
35049 .ptr_decl,
35050 .ptr_mut_decl,
35051 .ptr_comptime_field,
35052 .ptr_int,
35053 .ptr_eu_payload,
35054 .ptr_opt_payload,
35055 .ptr_elem,
35056 .ptr_field,
35057 .ptr_slice,
35058 .opt_payload,
35059 .opt_null,
35060 .int_u8,
35061 .int_u16,
35062 .int_u32,
35063 .int_i32,
35064 .int_usize,
35065 .int_comptime_int_u32,
35066 .int_comptime_int_i32,
35067 .int_small,
35068 .int_positive,
35069 .int_negative,
35070 .int_lazy_align,
35071 .int_lazy_size,
35072 .error_set_error,
35073 .error_union_error,
35074 .error_union_payload,
35075 .enum_literal,
35076 .enum_tag,
35077 .float_f16,
35078 .float_f32,
35079 .float_f64,
35080 .float_f80,
35081 .float_f128,
35082 .float_c_longdouble_f80,
35083 .float_c_longdouble_f128,
35084 .float_comptime_float,
35085 .variable,
35086 .extern_func,
35087 .func,
35088 .only_possible_value,
35089 .union_value,
35090 .bytes,
35091 .aggregate,
35092 .repeated,
35093 // memoized value, not types
35094 .memoized_call,
35095 => unreachable,
35096 .type_array_big,
35097 .type_array_small,
35098 .type_vector,
35099 .type_enum_auto,
35100 .type_enum_explicit,
35101 .type_enum_nonexhaustive,
35102 .type_struct,
35103 .type_struct_ns,
35104 .type_struct_anon,
35105 .type_tuple_anon,
35106 .type_union_tagged,
35107 .type_union_untagged,
35108 .type_union_safety,
35109 => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
35110 inline .array_type, .vector_type => |seq_type, seq_tag| {
35111 const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none;
35112 if (seq_type.len + @intFromBool(has_sentinel) == 0) return (try mod.intern(.{ .aggregate = .{
3496535113 .ty = ty.toIntern(),
34966 .storage = .{ .repeated_elem = opv.toIntern() },
35114 .storage = .{ .elems = &.{} },
3496735115 } })).toValue();
34968 }
34969 return null;
34970 },
34971 .opt_type => |child| {
34972 if (child == .noreturn_type) {
34973 return try mod.nullValue(ty);
34974 } else {
34975 return null;
34976 }
34977 },
3497835116
34979 .simple_type => |t| switch (t) {
34980 .f16,
34981 .f32,
34982 .f64,
34983 .f80,
34984 .f128,
34985 .usize,
34986 .isize,
34987 .c_char,
34988 .c_short,
34989 .c_ushort,
34990 .c_int,
34991 .c_uint,
34992 .c_long,
34993 .c_ulong,
34994 .c_longlong,
34995 .c_ulonglong,
34996 .c_longdouble,
34997 .anyopaque,
34998 .bool,
34999 .type,
35000 .anyerror,
35001 .comptime_int,
35002 .comptime_float,
35003 .enum_literal,
35004 .atomic_order,
35005 .atomic_rmw_op,
35006 .calling_convention,
35007 .address_space,
35008 .float_mode,
35009 .reduce_op,
35010 .call_modifier,
35011 .prefetch_options,
35012 .export_options,
35013 .extern_options,
35014 .type_info,
35015 => null,
35016
35017 .void => Value.void,
35018 .noreturn => Value.@"unreachable",
35019 .null => Value.null,
35020 .undefined => Value.undef,
35117 if (try sema.typeHasOnePossibleValue(seq_type.child.toType())) |opv| {
35118 return (try mod.intern(.{ .aggregate = .{
35119 .ty = ty.toIntern(),
35120 .storage = .{ .repeated_elem = opv.toIntern() },
35121 } })).toValue();
35122 }
35123 return null;
35124 },
3502135125
35022 .generic_poison => return error.GenericPoison,
35023 },
35024 .struct_type => |struct_type| {
35025 const resolved_ty = try sema.resolveTypeFields(ty);
35026 if (mod.structPtrUnwrap(struct_type.index)) |s| {
35027 const field_vals = try sema.arena.alloc(InternPool.Index, s.fields.count());
35028 for (field_vals, s.fields.values(), 0..) |*field_val, field, i| {
35029 if (field.is_comptime) {
35030 field_val.* = field.default_val;
35031 continue;
35032 }
35033 if (field.ty.eql(resolved_ty, sema.mod)) {
35034 const msg = try Module.ErrorMsg.create(
35035 sema.gpa,
35036 s.srcLoc(sema.mod),
35037 "struct '{}' depends on itself",
35038 .{ty.fmt(sema.mod)},
35039 );
35040 try sema.addFieldErrNote(resolved_ty, i, msg, "while checking this field", .{});
35041 return sema.failWithOwnedErrorMsg(msg);
35126 .struct_type => |struct_type| {
35127 const resolved_ty = try sema.resolveTypeFields(ty);
35128 if (mod.structPtrUnwrap(struct_type.index)) |s| {
35129 const field_vals = try sema.arena.alloc(InternPool.Index, s.fields.count());
35130 for (field_vals, s.fields.values(), 0..) |*field_val, field, i| {
35131 if (field.is_comptime) {
35132 field_val.* = field.default_val;
35133 continue;
35134 }
35135 if (field.ty.eql(resolved_ty, sema.mod)) {
35136 const msg = try Module.ErrorMsg.create(
35137 sema.gpa,
35138 s.srcLoc(sema.mod),
35139 "struct '{}' depends on itself",
35140 .{ty.fmt(sema.mod)},
35141 );
35142 try sema.addFieldErrNote(resolved_ty, i, msg, "while checking this field", .{});
35143 return sema.failWithOwnedErrorMsg(msg);
35144 }
35145 if (try sema.typeHasOnePossibleValue(field.ty)) |field_opv| {
35146 field_val.* = try field_opv.intern(field.ty, mod);
35147 } else return null;
3504235148 }
35043 if (try sema.typeHasOnePossibleValue(field.ty)) |field_opv| {
35044 field_val.* = try field_opv.intern(field.ty, mod);
35045 } else return null;
35149
35150 // In this case the struct has no runtime-known fields and
35151 // therefore has one possible value.
35152 return (try mod.intern(.{ .aggregate = .{
35153 .ty = ty.toIntern(),
35154 .storage = .{ .elems = field_vals },
35155 } })).toValue();
3504635156 }
3504735157
35048 // In this case the struct has no runtime-known fields and
35158 // In this case the struct has no fields at all and
3504935159 // therefore has one possible value.
3505035160 return (try mod.intern(.{ .aggregate = .{
3505135161 .ty = ty.toIntern(),
35052 .storage = .{ .elems = field_vals },
35162 .storage = .{ .elems = &.{} },
3505335163 } })).toValue();
35054 }
35055
35056 // In this case the struct has no fields at all and
35057 // therefore has one possible value.
35058 return (try mod.intern(.{ .aggregate = .{
35059 .ty = ty.toIntern(),
35060 .storage = .{ .elems = &.{} },
35061 } })).toValue();
35062 },
35063
35064 .anon_struct_type => |tuple| {
35065 for (tuple.values) |val| {
35066 if (val == .none) return null;
35067 }
35068 // In this case the struct has all comptime-known fields and
35069 // therefore has one possible value.
35070 // TODO: write something like getCoercedInts to avoid needing to dupe
35071 return (try mod.intern(.{ .aggregate = .{
35072 .ty = ty.toIntern(),
35073 .storage = .{ .elems = try sema.arena.dupe(InternPool.Index, tuple.values) },
35074 } })).toValue();
35075 },
35164 },
3507635165
35077 .union_type => |union_type| {
35078 const resolved_ty = try sema.resolveTypeFields(ty);
35079 const union_obj = mod.unionPtr(union_type.index);
35080 const tag_val = (try sema.typeHasOnePossibleValue(union_obj.tag_ty)) orelse
35081 return null;
35082 const fields = union_obj.fields.values();
35083 if (fields.len == 0) {
35084 const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() });
35085 return only.toValue();
35086 }
35087 const only_field = fields[0];
35088 if (only_field.ty.eql(resolved_ty, sema.mod)) {
35089 const msg = try Module.ErrorMsg.create(
35090 sema.gpa,
35091 union_obj.srcLoc(sema.mod),
35092 "union '{}' depends on itself",
35093 .{ty.fmt(sema.mod)},
35094 );
35095 try sema.addFieldErrNote(resolved_ty, 0, msg, "while checking this field", .{});
35096 return sema.failWithOwnedErrorMsg(msg);
35097 }
35098 const val_val = (try sema.typeHasOnePossibleValue(only_field.ty)) orelse
35099 return null;
35100 const only = try mod.intern(.{ .un = .{
35101 .ty = resolved_ty.toIntern(),
35102 .tag = tag_val.toIntern(),
35103 .val = val_val.toIntern(),
35104 } });
35105 return only.toValue();
35106 },
35107 .opaque_type => null,
35108 .enum_type => |enum_type| switch (enum_type.tag_mode) {
35109 .nonexhaustive => {
35110 if (enum_type.tag_ty == .comptime_int_type) return null;
35166 .anon_struct_type => |tuple| {
35167 for (tuple.values) |val| {
35168 if (val == .none) return null;
35169 }
35170 // In this case the struct has all comptime-known fields and
35171 // therefore has one possible value.
35172 // TODO: write something like getCoercedInts to avoid needing to dupe
35173 return (try mod.intern(.{ .aggregate = .{
35174 .ty = ty.toIntern(),
35175 .storage = .{ .elems = try sema.arena.dupe(InternPool.Index, tuple.values) },
35176 } })).toValue();
35177 },
3511135178
35112 if (try sema.typeHasOnePossibleValue(enum_type.tag_ty.toType())) |int_opv| {
35113 const only = try mod.intern(.{ .enum_tag = .{
35114 .ty = ty.toIntern(),
35115 .int = int_opv.toIntern(),
35116 } });
35179 .union_type => |union_type| {
35180 const resolved_ty = try sema.resolveTypeFields(ty);
35181 const union_obj = mod.unionPtr(union_type.index);
35182 const tag_val = (try sema.typeHasOnePossibleValue(union_obj.tag_ty)) orelse
35183 return null;
35184 const fields = union_obj.fields.values();
35185 if (fields.len == 0) {
35186 const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() });
3511735187 return only.toValue();
3511835188 }
35119
35120 return null;
35189 const only_field = fields[0];
35190 if (only_field.ty.eql(resolved_ty, sema.mod)) {
35191 const msg = try Module.ErrorMsg.create(
35192 sema.gpa,
35193 union_obj.srcLoc(sema.mod),
35194 "union '{}' depends on itself",
35195 .{ty.fmt(sema.mod)},
35196 );
35197 try sema.addFieldErrNote(resolved_ty, 0, msg, "while checking this field", .{});
35198 return sema.failWithOwnedErrorMsg(msg);
35199 }
35200 const val_val = (try sema.typeHasOnePossibleValue(only_field.ty)) orelse
35201 return null;
35202 const only = try mod.intern(.{ .un = .{
35203 .ty = resolved_ty.toIntern(),
35204 .tag = tag_val.toIntern(),
35205 .val = val_val.toIntern(),
35206 } });
35207 return only.toValue();
3512135208 },
35122 .auto, .explicit => {
35123 if (enum_type.tag_ty.toType().hasRuntimeBits(mod)) return null;
3512435209
35125 switch (enum_type.names.len) {
35126 0 => {
35127 const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() });
35210 .enum_type => |enum_type| switch (enum_type.tag_mode) {
35211 .nonexhaustive => {
35212 if (enum_type.tag_ty == .comptime_int_type) return null;
35213
35214 if (try sema.typeHasOnePossibleValue(enum_type.tag_ty.toType())) |int_opv| {
35215 const only = try mod.intern(.{ .enum_tag = .{
35216 .ty = ty.toIntern(),
35217 .int = int_opv.toIntern(),
35218 } });
3512835219 return only.toValue();
35129 },
35130 1 => return try mod.getCoerced((if (enum_type.values.len == 0)
35131 try mod.intern(.{ .int = .{
35132 .ty = enum_type.tag_ty,
35133 .storage = .{ .u64 = 0 },
35134 } })
35135 else
35136 enum_type.values[0]).toValue(), ty),
35137 else => return null,
35138 }
35220 }
35221
35222 return null;
35223 },
35224 .auto, .explicit => {
35225 if (enum_type.tag_ty.toType().hasRuntimeBits(mod)) return null;
35226
35227 switch (enum_type.names.len) {
35228 0 => {
35229 const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() });
35230 return only.toValue();
35231 },
35232 1 => return try mod.getCoerced((if (enum_type.values.len == 0)
35233 try mod.intern(.{ .int = .{
35234 .ty = enum_type.tag_ty,
35235 .storage = .{ .u64 = 0 },
35236 } })
35237 else
35238 enum_type.values[0]).toValue(), ty),
35239 else => return null,
35240 }
35241 },
3513935242 },
35140 },
3514135243
35142 // values, not types
35143 .undef,
35144 .runtime_value,
35145 .simple_value,
35146 .variable,
35147 .extern_func,
35148 .func,
35149 .int,
35150 .err,
35151 .error_union,
35152 .enum_literal,
35153 .enum_tag,
35154 .empty_enum_value,
35155 .float,
35156 .ptr,
35157 .opt,
35158 .aggregate,
35159 .un,
35160 // memoization, not types
35161 .memoized_call,
35162 => unreachable,
35244 else => unreachable,
35245 },
3516335246 },
3516435247 };
3516535248}
src/Zir.zig+3
......@@ -2005,6 +2005,8 @@ pub const Inst = struct {
20052005 /// The tag type is specified so that it is safe to bitcast between `[]u32`
20062006 /// and `[]Ref`.
20072007 pub const Ref = enum(u32) {
2008 u0_type = @intFromEnum(InternPool.Index.u0_type),
2009 i0_type = @intFromEnum(InternPool.Index.i0_type),
20082010 u1_type = @intFromEnum(InternPool.Index.u1_type),
20092011 u8_type = @intFromEnum(InternPool.Index.u8_type),
20102012 i8_type = @intFromEnum(InternPool.Index.i8_type),
......@@ -2064,6 +2066,7 @@ pub const Inst = struct {
20642066 single_const_pointer_to_comptime_int_type = @intFromEnum(InternPool.Index.single_const_pointer_to_comptime_int_type),
20652067 slice_const_u8_type = @intFromEnum(InternPool.Index.slice_const_u8_type),
20662068 slice_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.slice_const_u8_sentinel_0_type),
2069 optional_noreturn_type = @intFromEnum(InternPool.Index.optional_noreturn_type),
20672070 anyerror_void_error_union_type = @intFromEnum(InternPool.Index.anyerror_void_error_union_type),
20682071 generic_poison_type = @intFromEnum(InternPool.Index.generic_poison_type),
20692072 empty_struct_type = @intFromEnum(InternPool.Index.empty_struct_type),