aboutsummaryrefslogtreecommitdiff
path: root/test/behavior/union.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-10-19 20:14:10 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-10-19 20:22:47 -0700
commitdfb3231959bb340d260ddbec2b8eabfb5063c1bf (patch)
tree1f91b36fc9ed4b0aaa35fd8f8657efb365f3ec74 /test/behavior/union.zig
parent4a76523b92bcf0e9b48438cb22f49e67e0ab3fa1 (diff)
downloadzig-dfb3231959bb340d260ddbec2b8eabfb5063c1bf.tar.gz
zig-dfb3231959bb340d260ddbec2b8eabfb5063c1bf.zip
stage2: implement switching on unions
* AstGen: Move `refToIndex` and `indexToRef` to Zir * ZIR: the switch_block_*_* instruction tags are collapsed into one switch_block tag which uses 4 bits for flags, and reduces the scalar_cases_len field from 32 to 28 bits. This freed up more ZIR tags, 2 of which are now used for `switch_cond` and `switch_cond_ref` for producing the switch condition value. For example, for union values it returns the corresponding enum value. * switching with multiple cases and ranges is not yet supported because I want to change the ZIR encoding to store index pointers into the extra array rather than storing prong indexes. This will avoid O(N^2) iteration over prongs. * AstGen now adds a `switch_cond` on the operand and then passes the result of that to the `switch_block` instruction. * Sema: partially implement `switch_capture_*` instructions. * Sema: `unionToTag` notices if the enum type has only one possible value.
Diffstat (limited to 'test/behavior/union.zig')
-rw-r--r--test/behavior/union.zig31
1 files changed, 31 insertions, 0 deletions
diff --git a/test/behavior/union.zig b/test/behavior/union.zig
index e296f6bbb8..b528dc8730 100644
--- a/test/behavior/union.zig
+++ b/test/behavior/union.zig
@@ -71,3 +71,34 @@ test "0-sized extern union definition" {
try expect(U.f == 1);
}
+
+const Value = union(enum) {
+ Int: u64,
+ Array: [9]u8,
+};
+
+const Agg = struct {
+ val1: Value,
+ val2: Value,
+};
+
+const v1 = Value{ .Int = 1234 };
+const v2 = Value{ .Array = [_]u8{3} ** 9 };
+
+const err = @as(anyerror!Agg, Agg{
+ .val1 = v1,
+ .val2 = v2,
+});
+
+const array = [_]Value{ v1, v2, v1, v2 };
+
+test "unions embedded in aggregate types" {
+ switch (array[1]) {
+ Value.Array => |arr| try expect(arr[4] == 3),
+ else => unreachable,
+ }
+ switch ((err catch unreachable).val1) {
+ Value.Int => |x| try expect(x == 1234),
+ else => unreachable,
+ }
+}