diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-10-19 20:14:10 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-10-19 20:22:47 -0700 |
| commit | dfb3231959bb340d260ddbec2b8eabfb5063c1bf (patch) | |
| tree | 1f91b36fc9ed4b0aaa35fd8f8657efb365f3ec74 /test/behavior/union.zig | |
| parent | 4a76523b92bcf0e9b48438cb22f49e67e0ab3fa1 (diff) | |
| download | zig-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.zig | 31 |
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, + } +} |
