Commit e70a0b2a6b

Veikka Tuominen <git@vexu.eu>
2023-03-20 23:27:33
Value: implement reinterpreting enum field index as integer
Closes #15019
1 parent 82133cd
Changed files (2)
src
test
behavior
src/value.zig
@@ -1113,6 +1113,10 @@ pub const Value = extern union {
             .bool_true,
             => return BigIntMutable.init(&space.limbs, 1).toConst(),
 
+            .enum_field_index => {
+                const index = val.castTag(.enum_field_index).?.data;
+                return BigIntMutable.init(&space.limbs, index).toConst();
+            },
             .runtime_value => {
                 const sub_val = val.castTag(.runtime_value).?.data;
                 return sub_val.toBigIntAdvanced(space, target, opt_sema);
@@ -1983,6 +1987,7 @@ pub const Value = extern union {
             .variable,
             => .gt,
 
+            .enum_field_index => return std.math.order(lhs.castTag(.enum_field_index).?.data, 0),
             .runtime_value => {
                 // This is needed to correctly handle hashing the value.
                 // Checks in Sema should prevent direct comparisons from reaching here.
test/behavior/union.zig
@@ -1513,3 +1513,23 @@ test "packed union with zero-bit field" {
     };
     try S.doTest(.{ .nested = .{ .zero = {} }, .bar = 42 });
 }
+
+test "reinterpreting enum value inside packed union" {
+    if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+
+    const U = packed union {
+        tag: enum { a, b },
+        val: u8,
+
+        fn doTest() !void {
+            var u: @This() = .{ .tag = .a };
+            u.val += 1;
+            try expect(u.tag == .b);
+        }
+    };
+    try U.doTest();
+    comptime try U.doTest();
+}