| author | |
| committer | |
| log | a0d4ef0acf50db06fdde8ff229d20d15afc7d402 |
| tree | 92b320040e5a979d569a5284e71c6fcdf7ee893f |
| parent | 99531b0d52392668fe9f86b5109fff74cd37aff3 |
This is a bit odd, because this value doesn't actually exist:
see #15909. This gets all the empty enum/union behavior tests passing.
Also adds an assertion to `Sema.analyzeBodyInner` which would have
helped figure out the issue here much more quickly.10 files changed, 66 insertions(+), 13 deletions(-)
src/InternPool.zig+23-1| ... | @@ -206,6 +206,10 @@ pub const Key = union(enum) { | ... | @@ -206,6 +206,10 @@ pub const Key = union(enum) { |
| 206 | enum_literal: NullTerminatedString, | 206 | enum_literal: NullTerminatedString, |
| 207 | /// A specific enum tag, indicated by the integer tag value. | 207 | /// A specific enum tag, indicated by the integer tag value. |
| 208 | enum_tag: Key.EnumTag, | 208 | enum_tag: Key.EnumTag, |
| 209 | /// An empty enum or union. TODO: this value's existence is strange, because such a type in | ||
| 210 | /// reality has no values. See #15909. | ||
| 211 | /// Payload is the type for which we are an empty value. | ||
| 212 | empty_enum_value: Index, | ||
| 209 | float: Key.Float, | 213 | float: Key.Float, |
| 210 | ptr: Ptr, | 214 | ptr: Ptr, |
| 211 | opt: Opt, | 215 | opt: Opt, |
| ... | @@ -670,6 +674,7 @@ pub const Key = union(enum) { | ... | @@ -670,6 +674,7 @@ pub const Key = union(enum) { |
| 670 | .error_union, | 674 | .error_union, |
| 671 | .enum_literal, | 675 | .enum_literal, |
| 672 | .enum_tag, | 676 | .enum_tag, |
| 677 | .empty_enum_value, | ||
| 673 | .inferred_error_set_type, | 678 | .inferred_error_set_type, |
| 674 | => |info| { | 679 | => |info| { |
| 675 | var hasher = std.hash.Wyhash.init(seed); | 680 | var hasher = std.hash.Wyhash.init(seed); |
| ... | @@ -957,6 +962,10 @@ pub const Key = union(enum) { | ... | @@ -957,6 +962,10 @@ pub const Key = union(enum) { |
| 957 | const b_info = b.enum_tag; | 962 | const b_info = b.enum_tag; |
| 958 | return std.meta.eql(a_info, b_info); | 963 | return std.meta.eql(a_info, b_info); |
| 959 | }, | 964 | }, |
| 965 | .empty_enum_value => |a_info| { | ||
| 966 | const b_info = b.empty_enum_value; | ||
| 967 | return a_info == b_info; | ||
| 968 | }, | ||
| 960 | 969 | ||
| 961 | .variable => |a_info| { | 970 | .variable => |a_info| { |
| 962 | const b_info = b.variable; | 971 | const b_info = b.variable; |
| ... | @@ -1192,6 +1201,7 @@ pub const Key = union(enum) { | ... | @@ -1192,6 +1201,7 @@ pub const Key = union(enum) { |
| 1192 | .enum_literal => .enum_literal_type, | 1201 | .enum_literal => .enum_literal_type, |
| 1193 | 1202 | ||
| 1194 | .undef => |x| x, | 1203 | .undef => |x| x, |
| 1204 | .empty_enum_value => |x| x, | ||
| 1195 | 1205 | ||
| 1196 | .simple_value => |s| switch (s) { | 1206 | .simple_value => |s| switch (s) { |
| 1197 | .undefined => .undefined_type, | 1207 | .undefined => .undefined_type, |
| ... | @@ -1980,6 +1990,7 @@ pub const Tag = enum(u8) { | ... | @@ -1980,6 +1990,7 @@ pub const Tag = enum(u8) { |
| 1980 | /// The set of values that are encoded this way is: | 1990 | /// The set of values that are encoded this way is: |
| 1981 | /// * An array or vector which has length 0. | 1991 | /// * An array or vector which has length 0. |
| 1982 | /// * A struct which has all fields comptime-known. | 1992 | /// * A struct which has all fields comptime-known. |
| 1993 | /// * An empty enum or union. TODO: this value's existence is strange, because such a type in reality has no values. See #15909 | ||
| 1983 | /// data is Index of the type, which is known to be zero bits at runtime. | 1994 | /// data is Index of the type, which is known to be zero bits at runtime. |
| 1984 | only_possible_value, | 1995 | only_possible_value, |
| 1985 | /// data is extra index to Key.Union. | 1996 | /// data is extra index to Key.Union. |
| ... | @@ -2952,6 +2963,13 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { | ... | @@ -2952,6 +2963,13 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 2952 | } }; | 2963 | } }; |
| 2953 | }, | 2964 | }, |
| 2954 | 2965 | ||
| 2966 | .type_enum_auto, | ||
| 2967 | .type_enum_explicit, | ||
| 2968 | .type_union_tagged, | ||
| 2969 | .type_union_untagged, | ||
| 2970 | .type_union_safety, | ||
| 2971 | => .{ .empty_enum_value = ty }, | ||
| 2972 | |||
| 2955 | else => unreachable, | 2973 | else => unreachable, |
| 2956 | }; | 2974 | }; |
| 2957 | }, | 2975 | }, |
| ... | @@ -3755,6 +3773,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -3755,6 +3773,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 3755 | }); | 3773 | }); |
| 3756 | }, | 3774 | }, |
| 3757 | 3775 | ||
| 3776 | .empty_enum_value => |enum_or_union_ty| ip.items.appendAssumeCapacity(.{ | ||
| 3777 | .tag = .only_possible_value, | ||
| 3778 | .data = @enumToInt(enum_or_union_ty), | ||
| 3779 | }), | ||
| 3780 | |||
| 3758 | .float => |float| { | 3781 | .float => |float| { |
| 3759 | switch (float.ty) { | 3782 | switch (float.ty) { |
| 3760 | .f16_type => ip.items.appendAssumeCapacity(.{ | 3783 | .f16_type => ip.items.appendAssumeCapacity(.{ |
| ... | @@ -5416,7 +5439,6 @@ pub fn isNoReturn(ip: *const InternPool, ty: Index) bool { | ... | @@ -5416,7 +5439,6 @@ pub fn isNoReturn(ip: *const InternPool, ty: Index) bool { |
| 5416 | .noreturn_type => true, | 5439 | .noreturn_type => true, |
| 5417 | else => switch (ip.indexToKey(ty)) { | 5440 | else => switch (ip.indexToKey(ty)) { |
| 5418 | .error_set_type => |error_set_type| error_set_type.names.len == 0, | 5441 | .error_set_type => |error_set_type| error_set_type.names.len == 0, |
| 5419 | .enum_type => |enum_type| enum_type.names.len == 0, | ||
| 5420 | else => false, | 5442 | else => false, |
| 5421 | }, | 5443 | }, |
| 5422 | }; | 5444 | }; |
src/Sema.zig+19-10| ... | @@ -1725,8 +1725,12 @@ fn analyzeBodyInner( | ... | @@ -1725,8 +1725,12 @@ fn analyzeBodyInner( |
| 1725 | break :blk Air.Inst.Ref.void_value; | 1725 | break :blk Air.Inst.Ref.void_value; |
| 1726 | }, | 1726 | }, |
| 1727 | }; | 1727 | }; |
| 1728 | if (sema.isNoReturn(air_inst)) | 1728 | if (sema.isNoReturn(air_inst)) { |
| 1729 | // We're going to assume that the body itself is noreturn, so let's ensure that now | ||
| 1730 | assert(block.instructions.items.len > 0); | ||
| 1731 | assert(sema.isNoReturn(Air.indexToRef(block.instructions.items[block.instructions.items.len - 1]))); | ||
| 1729 | break always_noreturn; | 1732 | break always_noreturn; |
| 1733 | } | ||
| 1730 | map.putAssumeCapacity(inst, air_inst); | 1734 | map.putAssumeCapacity(inst, air_inst); |
| 1731 | i += 1; | 1735 | i += 1; |
| 1732 | }; | 1736 | }; |
| ... | @@ -32150,6 +32154,7 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { | ... | @@ -32150,6 +32154,7 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { |
| 32150 | .error_union, | 32154 | .error_union, |
| 32151 | .enum_literal, | 32155 | .enum_literal, |
| 32152 | .enum_tag, | 32156 | .enum_tag, |
| 32157 | .empty_enum_value, | ||
| 32153 | .float, | 32158 | .float, |
| 32154 | .ptr, | 32159 | .ptr, |
| 32155 | .opt, | 32160 | .opt, |
| ... | @@ -33015,10 +33020,6 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -33015,10 +33020,6 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 33015 | enum_field_names = try sema.arena.alloc(InternPool.NullTerminatedString, fields_len); | 33020 | enum_field_names = try sema.arena.alloc(InternPool.NullTerminatedString, fields_len); |
| 33016 | } | 33021 | } |
| 33017 | 33022 | ||
| 33018 | if (fields_len == 0) { | ||
| 33019 | return; | ||
| 33020 | } | ||
| 33021 | |||
| 33022 | const bits_per_field = 4; | 33023 | const bits_per_field = 4; |
| 33023 | const fields_per_u32 = 32 / bits_per_field; | 33024 | const fields_per_u32 = 32 / bits_per_field; |
| 33024 | const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable; | 33025 | const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable; |
| ... | @@ -33301,7 +33302,7 @@ fn generateUnionTagTypeNumbered( | ... | @@ -33301,7 +33302,7 @@ fn generateUnionTagTypeNumbered( |
| 33301 | .decl = new_decl_index, | 33302 | .decl = new_decl_index, |
| 33302 | .namespace = .none, | 33303 | .namespace = .none, |
| 33303 | .tag_ty = if (enum_field_vals.len == 0) | 33304 | .tag_ty = if (enum_field_vals.len == 0) |
| 33304 | .noreturn_type | 33305 | (try mod.intType(.unsigned, 0)).toIntern() |
| 33305 | else | 33306 | else |
| 33306 | mod.intern_pool.typeOf(enum_field_vals[0]), | 33307 | mod.intern_pool.typeOf(enum_field_vals[0]), |
| 33307 | .names = enum_field_names, | 33308 | .names = enum_field_names, |
| ... | @@ -33351,7 +33352,7 @@ fn generateUnionTagTypeSimple( | ... | @@ -33351,7 +33352,7 @@ fn generateUnionTagTypeSimple( |
| 33351 | .decl = new_decl_index, | 33352 | .decl = new_decl_index, |
| 33352 | .namespace = .none, | 33353 | .namespace = .none, |
| 33353 | .tag_ty = if (enum_field_names.len == 0) | 33354 | .tag_ty = if (enum_field_names.len == 0) |
| 33354 | .noreturn_type | 33355 | (try mod.intType(.unsigned, 0)).toIntern() |
| 33355 | else | 33356 | else |
| 33356 | (try mod.smallestUnsignedInt(enum_field_names.len - 1)).toIntern(), | 33357 | (try mod.smallestUnsignedInt(enum_field_names.len - 1)).toIntern(), |
| 33357 | .names = enum_field_names, | 33358 | .names = enum_field_names, |
| ... | @@ -33590,7 +33591,10 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -33590,7 +33591,10 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 33590 | const tag_val = (try sema.typeHasOnePossibleValue(union_obj.tag_ty)) orelse | 33591 | const tag_val = (try sema.typeHasOnePossibleValue(union_obj.tag_ty)) orelse |
| 33591 | return null; | 33592 | return null; |
| 33592 | const fields = union_obj.fields.values(); | 33593 | const fields = union_obj.fields.values(); |
| 33593 | if (fields.len == 0) return Value.@"unreachable"; | 33594 | if (fields.len == 0) { |
| 33595 | const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() }); | ||
| 33596 | return only.toValue(); | ||
| 33597 | } | ||
| 33594 | const only_field = fields[0]; | 33598 | const only_field = fields[0]; |
| 33595 | if (only_field.ty.eql(resolved_ty, sema.mod)) { | 33599 | if (only_field.ty.eql(resolved_ty, sema.mod)) { |
| 33596 | const msg = try Module.ErrorMsg.create( | 33600 | const msg = try Module.ErrorMsg.create( |
| ... | @@ -33630,7 +33634,10 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -33630,7 +33634,10 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 33630 | if (enum_type.tag_ty.toType().hasRuntimeBits(mod)) return null; | 33634 | if (enum_type.tag_ty.toType().hasRuntimeBits(mod)) return null; |
| 33631 | 33635 | ||
| 33632 | switch (enum_type.names.len) { | 33636 | switch (enum_type.names.len) { |
| 33633 | 0 => return Value.@"unreachable", | 33637 | 0 => { |
| 33638 | const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() }); | ||
| 33639 | return only.toValue(); | ||
| 33640 | }, | ||
| 33634 | 1 => return try mod.getCoerced((if (enum_type.values.len == 0) | 33641 | 1 => return try mod.getCoerced((if (enum_type.values.len == 0) |
| 33635 | try mod.intern(.{ .int = .{ | 33642 | try mod.intern(.{ .int = .{ |
| 33636 | .ty = enum_type.tag_ty, | 33643 | .ty = enum_type.tag_ty, |
| ... | @@ -33655,6 +33662,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -33655,6 +33662,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 33655 | .error_union, | 33662 | .error_union, |
| 33656 | .enum_literal, | 33663 | .enum_literal, |
| 33657 | .enum_tag, | 33664 | .enum_tag, |
| 33665 | .empty_enum_value, | ||
| 33658 | .float, | 33666 | .float, |
| 33659 | .ptr, | 33667 | .ptr, |
| 33660 | .opt, | 33668 | .opt, |
| ... | @@ -34143,6 +34151,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { | ... | @@ -34143,6 +34151,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { |
| 34143 | .error_union, | 34151 | .error_union, |
| 34144 | .enum_literal, | 34152 | .enum_literal, |
| 34145 | .enum_tag, | 34153 | .enum_tag, |
| 34154 | .empty_enum_value, | ||
| 34146 | .float, | 34155 | .float, |
| 34147 | .ptr, | 34156 | .ptr, |
| 34148 | .opt, | 34157 | .opt, |
| ... | @@ -34848,7 +34857,7 @@ fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type { | ... | @@ -34848,7 +34857,7 @@ fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type { |
| 34848 | 34857 | ||
| 34849 | /// Avoids crashing the compiler when asking if inferred allocations are noreturn. | 34858 | /// Avoids crashing the compiler when asking if inferred allocations are noreturn. |
| 34850 | fn isNoReturn(sema: *Sema, ref: Air.Inst.Ref) bool { | 34859 | fn isNoReturn(sema: *Sema, ref: Air.Inst.Ref) bool { |
| 34851 | if (ref == .noreturn_type) return true; | 34860 | if (ref == .unreachable_value) return true; |
| 34852 | if (Air.refToIndex(ref)) |inst| switch (sema.air_instructions.items(.tag)[inst]) { | 34861 | if (Air.refToIndex(ref)) |inst| switch (sema.air_instructions.items(.tag)[inst]) { |
| 34853 | .inferred_alloc, .inferred_alloc_comptime => return false, | 34862 | .inferred_alloc, .inferred_alloc_comptime => return false, |
| 34854 | else => {}, | 34863 | else => {}, |
src/TypedValue.zig+1| ... | @@ -248,6 +248,7 @@ pub fn print( | ... | @@ -248,6 +248,7 @@ pub fn print( |
| 248 | try writer.writeAll(")"); | 248 | try writer.writeAll(")"); |
| 249 | return; | 249 | return; |
| 250 | }, | 250 | }, |
| 251 | .empty_enum_value => return writer.writeAll("(empty enum value)"), | ||
| 251 | .float => |float| switch (float.storage) { | 252 | .float => |float| switch (float.storage) { |
| 252 | inline else => |x| return writer.print("{}", .{x}), | 253 | inline else => |x| return writer.print("{}", .{x}), |
| 253 | }, | 254 | }, |
src/arch/wasm/CodeGen.zig+1| ... | @@ -3156,6 +3156,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue { | ... | @@ -3156,6 +3156,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue { |
| 3156 | .extern_func, | 3156 | .extern_func, |
| 3157 | .func, | 3157 | .func, |
| 3158 | .enum_literal, | 3158 | .enum_literal, |
| 3159 | .empty_enum_value, | ||
| 3159 | => unreachable, // non-runtime values | 3160 | => unreachable, // non-runtime values |
| 3160 | .int => { | 3161 | .int => { |
| 3161 | const int_info = ty.intInfo(mod); | 3162 | const int_info = ty.intInfo(mod); |
src/codegen.zig+1| ... | @@ -242,6 +242,7 @@ pub fn generateSymbol( | ... | @@ -242,6 +242,7 @@ pub fn generateSymbol( |
| 242 | .extern_func, | 242 | .extern_func, |
| 243 | .func, | 243 | .func, |
| 244 | .enum_literal, | 244 | .enum_literal, |
| 245 | .empty_enum_value, | ||
| 245 | => unreachable, // non-runtime values | 246 | => unreachable, // non-runtime values |
| 246 | .int => { | 247 | .int => { |
| 247 | const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow; | 248 | const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow; |
src/codegen/c.zig+1| ... | @@ -946,6 +946,7 @@ pub const DeclGen = struct { | ... | @@ -946,6 +946,7 @@ pub const DeclGen = struct { |
| 946 | .extern_func, | 946 | .extern_func, |
| 947 | .func, | 947 | .func, |
| 948 | .enum_literal, | 948 | .enum_literal, |
| 949 | .empty_enum_value, | ||
| 949 | => unreachable, // non-runtime values | 950 | => unreachable, // non-runtime values |
| 950 | .int => |int| switch (int.storage) { | 951 | .int => |int| switch (int.storage) { |
| 951 | .u64, .i64, .big_int => try writer.print("{}", .{try dg.fmtIntLiteral(ty, val, location)}), | 952 | .u64, .i64, .big_int => try writer.print("{}", .{try dg.fmtIntLiteral(ty, val, location)}), |
src/codegen/llvm.zig+1| ... | @@ -3246,6 +3246,7 @@ pub const DeclGen = struct { | ... | @@ -3246,6 +3246,7 @@ pub const DeclGen = struct { |
| 3246 | }, | 3246 | }, |
| 3247 | .variable, | 3247 | .variable, |
| 3248 | .enum_literal, | 3248 | .enum_literal, |
| 3249 | .empty_enum_value, | ||
| 3249 | => unreachable, // non-runtime values | 3250 | => unreachable, // non-runtime values |
| 3250 | .extern_func, .func => { | 3251 | .extern_func, .func => { |
| 3251 | const fn_decl_index = switch (val_key) { | 3252 | const fn_decl_index = switch (val_key) { |
src/codegen/spirv.zig+1| ... | @@ -660,6 +660,7 @@ pub const DeclGen = struct { | ... | @@ -660,6 +660,7 @@ pub const DeclGen = struct { |
| 660 | .extern_func, | 660 | .extern_func, |
| 661 | .func, | 661 | .func, |
| 662 | .enum_literal, | 662 | .enum_literal, |
| 663 | .empty_enum_value, | ||
| 663 | => unreachable, // non-runtime values | 664 | => unreachable, // non-runtime values |
| 664 | .int => try self.addInt(ty, val), | 665 | .int => try self.addInt(ty, val), |
| 665 | .err => |err| { | 666 | .err => |err| { |
src/type.zig+17-2| ... | @@ -439,6 +439,7 @@ pub const Type = struct { | ... | @@ -439,6 +439,7 @@ pub const Type = struct { |
| 439 | .error_union, | 439 | .error_union, |
| 440 | .enum_literal, | 440 | .enum_literal, |
| 441 | .enum_tag, | 441 | .enum_tag, |
| 442 | .empty_enum_value, | ||
| 442 | .float, | 443 | .float, |
| 443 | .ptr, | 444 | .ptr, |
| 444 | .opt, | 445 | .opt, |
| ... | @@ -655,6 +656,7 @@ pub const Type = struct { | ... | @@ -655,6 +656,7 @@ pub const Type = struct { |
| 655 | .error_union, | 656 | .error_union, |
| 656 | .enum_literal, | 657 | .enum_literal, |
| 657 | .enum_tag, | 658 | .enum_tag, |
| 659 | .empty_enum_value, | ||
| 658 | .float, | 660 | .float, |
| 659 | .ptr, | 661 | .ptr, |
| 660 | .opt, | 662 | .opt, |
| ... | @@ -764,6 +766,7 @@ pub const Type = struct { | ... | @@ -764,6 +766,7 @@ pub const Type = struct { |
| 764 | .error_union, | 766 | .error_union, |
| 765 | .enum_literal, | 767 | .enum_literal, |
| 766 | .enum_tag, | 768 | .enum_tag, |
| 769 | .empty_enum_value, | ||
| 767 | .float, | 770 | .float, |
| 768 | .ptr, | 771 | .ptr, |
| 769 | .opt, | 772 | .opt, |
| ... | @@ -1098,6 +1101,7 @@ pub const Type = struct { | ... | @@ -1098,6 +1101,7 @@ pub const Type = struct { |
| 1098 | .error_union, | 1101 | .error_union, |
| 1099 | .enum_literal, | 1102 | .enum_literal, |
| 1100 | .enum_tag, | 1103 | .enum_tag, |
| 1104 | .empty_enum_value, | ||
| 1101 | .float, | 1105 | .float, |
| 1102 | .ptr, | 1106 | .ptr, |
| 1103 | .opt, | 1107 | .opt, |
| ... | @@ -1515,6 +1519,7 @@ pub const Type = struct { | ... | @@ -1515,6 +1519,7 @@ pub const Type = struct { |
| 1515 | .error_union, | 1519 | .error_union, |
| 1516 | .enum_literal, | 1520 | .enum_literal, |
| 1517 | .enum_tag, | 1521 | .enum_tag, |
| 1522 | .empty_enum_value, | ||
| 1518 | .float, | 1523 | .float, |
| 1519 | .ptr, | 1524 | .ptr, |
| 1520 | .opt, | 1525 | .opt, |
| ... | @@ -1749,6 +1754,7 @@ pub const Type = struct { | ... | @@ -1749,6 +1754,7 @@ pub const Type = struct { |
| 1749 | .error_union, | 1754 | .error_union, |
| 1750 | .enum_literal, | 1755 | .enum_literal, |
| 1751 | .enum_tag, | 1756 | .enum_tag, |
| 1757 | .empty_enum_value, | ||
| 1752 | .float, | 1758 | .float, |
| 1753 | .ptr, | 1759 | .ptr, |
| 1754 | .opt, | 1760 | .opt, |
| ... | @@ -2302,6 +2308,7 @@ pub const Type = struct { | ... | @@ -2302,6 +2308,7 @@ pub const Type = struct { |
| 2302 | .error_union, | 2308 | .error_union, |
| 2303 | .enum_literal, | 2309 | .enum_literal, |
| 2304 | .enum_tag, | 2310 | .enum_tag, |
| 2311 | .empty_enum_value, | ||
| 2305 | .float, | 2312 | .float, |
| 2306 | .ptr, | 2313 | .ptr, |
| 2307 | .opt, | 2314 | .opt, |
| ... | @@ -2584,7 +2591,10 @@ pub const Type = struct { | ... | @@ -2584,7 +2591,10 @@ pub const Type = struct { |
| 2584 | .union_type => |union_type| { | 2591 | .union_type => |union_type| { |
| 2585 | const union_obj = mod.unionPtr(union_type.index); | 2592 | const union_obj = mod.unionPtr(union_type.index); |
| 2586 | const tag_val = (try union_obj.tag_ty.onePossibleValue(mod)) orelse return null; | 2593 | const tag_val = (try union_obj.tag_ty.onePossibleValue(mod)) orelse return null; |
| 2587 | if (union_obj.fields.count() == 0) return Value.@"unreachable"; | 2594 | if (union_obj.fields.count() == 0) { |
| 2595 | const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() }); | ||
| 2596 | return only.toValue(); | ||
| 2597 | } | ||
| 2588 | const only_field = union_obj.fields.values()[0]; | 2598 | const only_field = union_obj.fields.values()[0]; |
| 2589 | const val_val = (try only_field.ty.onePossibleValue(mod)) orelse return null; | 2599 | const val_val = (try only_field.ty.onePossibleValue(mod)) orelse return null; |
| 2590 | const only = try mod.intern(.{ .un = .{ | 2600 | const only = try mod.intern(.{ .un = .{ |
| ... | @@ -2613,7 +2623,10 @@ pub const Type = struct { | ... | @@ -2613,7 +2623,10 @@ pub const Type = struct { |
| 2613 | if (enum_type.tag_ty.toType().hasRuntimeBits(mod)) return null; | 2623 | if (enum_type.tag_ty.toType().hasRuntimeBits(mod)) return null; |
| 2614 | 2624 | ||
| 2615 | switch (enum_type.names.len) { | 2625 | switch (enum_type.names.len) { |
| 2616 | 0 => return Value.@"unreachable", | 2626 | 0 => { |
| 2627 | const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() }); | ||
| 2628 | return only.toValue(); | ||
| 2629 | }, | ||
| 2617 | 1 => { | 2630 | 1 => { |
| 2618 | if (enum_type.values.len == 0) { | 2631 | if (enum_type.values.len == 0) { |
| 2619 | const only = try mod.intern(.{ .enum_tag = .{ | 2632 | const only = try mod.intern(.{ .enum_tag = .{ |
| ... | @@ -2645,6 +2658,7 @@ pub const Type = struct { | ... | @@ -2645,6 +2658,7 @@ pub const Type = struct { |
| 2645 | .error_union, | 2658 | .error_union, |
| 2646 | .enum_literal, | 2659 | .enum_literal, |
| 2647 | .enum_tag, | 2660 | .enum_tag, |
| 2661 | .empty_enum_value, | ||
| 2648 | .float, | 2662 | .float, |
| 2649 | .ptr, | 2663 | .ptr, |
| 2650 | .opt, | 2664 | .opt, |
| ... | @@ -2790,6 +2804,7 @@ pub const Type = struct { | ... | @@ -2790,6 +2804,7 @@ pub const Type = struct { |
| 2790 | .error_union, | 2804 | .error_union, |
| 2791 | .enum_literal, | 2805 | .enum_literal, |
| 2792 | .enum_tag, | 2806 | .enum_tag, |
| 2807 | .empty_enum_value, | ||
| 2793 | .float, | 2808 | .float, |
| 2794 | .ptr, | 2809 | .ptr, |
| 2795 | .opt, | 2810 | .opt, |
src/value.zig+1| ... | @@ -441,6 +441,7 @@ pub const Value = struct { | ... | @@ -441,6 +441,7 @@ pub const Value = struct { |
| 441 | .err, | 441 | .err, |
| 442 | .enum_literal, | 442 | .enum_literal, |
| 443 | .enum_tag, | 443 | .enum_tag, |
| 444 | .empty_enum_value, | ||
| 444 | .float, | 445 | .float, |
| 445 | => val, | 446 | => val, |
| 446 | 447 |