| author | |
| committer | |
| log | 941b2f0d5e50521c41e6db3912085a72b6c16813 |
| tree | fc02e0cf50fb78d42b2aa248c617565985adcb21 |
| parent | 9ed599b4e3f5c9f48089a3acd61d0338e27e88f6 |
tagged unions used to be called "enums" but now they are called
"tagged unions".3 files changed, 92 insertions(+), 221 deletions(-)
test/behavior/enum.zig+6-132| ... | ... | @@ -3,68 +3,20 @@ const expect = std.testing.expect; |
| 3 | 3 | const mem = std.mem; |
| 4 | 4 | const Tag = std.meta.Tag; |
| 5 | 5 | |
| 6 | const Point = struct { | |
| 7 | x: u64, | |
| 8 | y: u64, | |
| 9 | }; | |
| 10 | const Foo = union(enum) { | |
| 11 | One: i32, | |
| 12 | Two: Point, | |
| 13 | Three: void, | |
| 14 | }; | |
| 15 | const FooNoVoid = union(enum) { | |
| 16 | One: i32, | |
| 17 | Two: Point, | |
| 18 | }; | |
| 19 | const Bar = enum { | |
| 20 | A, | |
| 21 | B, | |
| 22 | C, | |
| 23 | D, | |
| 24 | }; | |
| 25 | ||
| 26 | fn returnAnInt(x: i32) Foo { | |
| 27 | return Foo{ .One = x }; | |
| 28 | } | |
| 29 | ||
| 30 | fn shouldBeEmpty(x: AnEnumWithPayload) void { | |
| 31 | switch (x) { | |
| 32 | AnEnumWithPayload.Empty => {}, | |
| 33 | else => unreachable, | |
| 34 | } | |
| 35 | } | |
| 36 | ||
| 37 | fn shouldBeNotEmpty(x: AnEnumWithPayload) void { | |
| 38 | switch (x) { | |
| 39 | AnEnumWithPayload.Empty => unreachable, | |
| 40 | else => {}, | |
| 41 | } | |
| 42 | } | |
| 43 | ||
| 44 | const AnEnumWithPayload = union(enum) { | |
| 45 | Empty: void, | |
| 46 | Full: i32, | |
| 47 | }; | |
| 48 | ||
| 49 | 6 | const Number = enum { Zero, One, Two, Three, Four }; |
| 50 | 7 | |
| 51 | 8 | fn shouldEqual(n: Number, expected: u3) !void { |
| 52 | 9 | try expect(@enumToInt(n) == expected); |
| 53 | 10 | } |
| 54 | 11 | |
| 55 | fn testEnumTagNameBare(n: anytype) []const u8 { | |
| 56 | return @tagName(n); | |
| 12 | test "enum to int" { | |
| 13 | try shouldEqual(Number.Zero, 0); | |
| 14 | try shouldEqual(Number.One, 1); | |
| 15 | try shouldEqual(Number.Two, 2); | |
| 16 | try shouldEqual(Number.Three, 3); | |
| 17 | try shouldEqual(Number.Four, 4); | |
| 57 | 18 | } |
| 58 | 19 | |
| 59 | const BareNumber = enum { One, Two, Three }; | |
| 60 | ||
| 61 | const NonExhaustive = enum(u8) { A, B, _ }; | |
| 62 | ||
| 63 | const AlignTestEnum = union(enum) { | |
| 64 | A: [9]u8, | |
| 65 | B: u64, | |
| 66 | }; | |
| 67 | ||
| 68 | 20 | const ValueCount1 = enum { |
| 69 | 21 | I0, |
| 70 | 22 | }; |
| ... | ... | @@ -590,84 +542,6 @@ const ValueCount257 = enum { |
| 590 | 542 | I256, |
| 591 | 543 | }; |
| 592 | 544 | |
| 593 | const Small2 = enum(u2) { One, Two }; | |
| 594 | const Small = enum(u2) { One, Two, Three, Four }; | |
| 595 | ||
| 596 | const A = enum(u3) { One, Two, Three, Four, One2, Two2, Three2, Four2 }; | |
| 597 | const B = enum(u3) { One3, Two3, Three3, Four3, One23, Two23, Three23, Four23 }; | |
| 598 | const C = enum(u2) { One4, Two4, Three4, Four4 }; | |
| 599 | ||
| 600 | const BitFieldOfEnums = packed struct { | |
| 601 | a: A, | |
| 602 | b: B, | |
| 603 | c: C, | |
| 604 | }; | |
| 605 | ||
| 606 | const bit_field_1 = BitFieldOfEnums{ | |
| 607 | .a = A.Two, | |
| 608 | .b = B.Three3, | |
| 609 | .c = C.Four4, | |
| 610 | }; | |
| 611 | ||
| 612 | fn getA(data: *const BitFieldOfEnums) A { | |
| 613 | return data.a; | |
| 614 | } | |
| 615 | ||
| 616 | fn getB(data: *const BitFieldOfEnums) B { | |
| 617 | return data.b; | |
| 618 | } | |
| 619 | ||
| 620 | fn getC(data: *const BitFieldOfEnums) C { | |
| 621 | return data.c; | |
| 622 | } | |
| 623 | ||
| 624 | const MultipleChoice = enum(u32) { | |
| 625 | A = 20, | |
| 626 | B = 40, | |
| 627 | C = 60, | |
| 628 | D = 1000, | |
| 629 | }; | |
| 630 | ||
| 631 | const MultipleChoice2 = enum(u32) { | |
| 632 | Unspecified1, | |
| 633 | A = 20, | |
| 634 | Unspecified2, | |
| 635 | B = 40, | |
| 636 | Unspecified3, | |
| 637 | C = 60, | |
| 638 | Unspecified4, | |
| 639 | D = 1000, | |
| 640 | Unspecified5, | |
| 641 | }; | |
| 642 | ||
| 643 | const EnumWithOneMember = enum { Eof }; | |
| 644 | ||
| 645 | fn doALoopThing(id: EnumWithOneMember) void { | |
| 646 | while (true) { | |
| 647 | if (id == EnumWithOneMember.Eof) { | |
| 648 | break; | |
| 649 | } | |
| 650 | @compileError("above if condition should be comptime"); | |
| 651 | } | |
| 652 | } | |
| 653 | ||
| 654 | const State = enum { Start }; | |
| 655 | ||
| 656 | const EnumWithTagValues = enum(u4) { | |
| 657 | A = 1 << 0, | |
| 658 | B = 1 << 1, | |
| 659 | C = 1 << 2, | |
| 660 | D = 1 << 3, | |
| 661 | }; | |
| 662 | ||
| 663 | test "enum to int" { | |
| 664 | try shouldEqual(Number.Zero, 0); | |
| 665 | try shouldEqual(Number.One, 1); | |
| 666 | try shouldEqual(Number.Two, 2); | |
| 667 | try shouldEqual(Number.Three, 3); | |
| 668 | try shouldEqual(Number.Four, 4); | |
| 669 | } | |
| 670 | ||
| 671 | 545 | test "enum sizes" { |
| 672 | 546 | comptime { |
| 673 | 547 | try expect(@sizeOf(ValueCount1) == 0); |
test/behavior/enum_stage1.zig+1-87| ... | ... | @@ -100,81 +100,7 @@ test "single field non-exhaustive enum" { |
| 100 | 100 | comptime try S.doTheTest(23); |
| 101 | 101 | } |
| 102 | 102 | |
| 103 | test "enum type" { | |
| 104 | const foo1 = Foo{ .One = 13 }; | |
| 105 | const foo2 = Foo{ | |
| 106 | .Two = Point{ | |
| 107 | .x = 1234, | |
| 108 | .y = 5678, | |
| 109 | }, | |
| 110 | }; | |
| 111 | try expect(foo1.One == 13); | |
| 112 | try expect(foo2.Two.x == 1234 and foo2.Two.y == 5678); | |
| 113 | const bar = Bar.B; | |
| 114 | ||
| 115 | try expect(bar == Bar.B); | |
| 116 | try expect(@typeInfo(Foo).Union.fields.len == 3); | |
| 117 | try expect(@typeInfo(Bar).Enum.fields.len == 4); | |
| 118 | try expect(@sizeOf(Foo) == @sizeOf(FooNoVoid)); | |
| 119 | try expect(@sizeOf(Bar) == 1); | |
| 120 | } | |
| 121 | ||
| 122 | test "enum as return value" { | |
| 123 | switch (returnAnInt(13)) { | |
| 124 | Foo.One => |value| try expect(value == 13), | |
| 125 | else => unreachable, | |
| 126 | } | |
| 127 | } | |
| 128 | ||
| 129 | const Point = struct { | |
| 130 | x: u64, | |
| 131 | y: u64, | |
| 132 | }; | |
| 133 | const Foo = union(enum) { | |
| 134 | One: i32, | |
| 135 | Two: Point, | |
| 136 | Three: void, | |
| 137 | }; | |
| 138 | const FooNoVoid = union(enum) { | |
| 139 | One: i32, | |
| 140 | Two: Point, | |
| 141 | }; | |
| 142 | const Bar = enum { | |
| 143 | A, | |
| 144 | B, | |
| 145 | C, | |
| 146 | D, | |
| 147 | }; | |
| 148 | ||
| 149 | fn returnAnInt(x: i32) Foo { | |
| 150 | return Foo{ .One = x }; | |
| 151 | } | |
| 152 | ||
| 153 | test "constant enum with payload" { | |
| 154 | var empty = AnEnumWithPayload{ .Empty = {} }; | |
| 155 | var full = AnEnumWithPayload{ .Full = 13 }; | |
| 156 | shouldBeEmpty(empty); | |
| 157 | shouldBeNotEmpty(full); | |
| 158 | } | |
| 159 | ||
| 160 | fn shouldBeEmpty(x: AnEnumWithPayload) void { | |
| 161 | switch (x) { | |
| 162 | AnEnumWithPayload.Empty => {}, | |
| 163 | else => unreachable, | |
| 164 | } | |
| 165 | } | |
| 166 | ||
| 167 | fn shouldBeNotEmpty(x: AnEnumWithPayload) void { | |
| 168 | switch (x) { | |
| 169 | AnEnumWithPayload.Empty => unreachable, | |
| 170 | else => {}, | |
| 171 | } | |
| 172 | } | |
| 173 | ||
| 174 | const AnEnumWithPayload = union(enum) { | |
| 175 | Empty: void, | |
| 176 | Full: i32, | |
| 177 | }; | |
| 103 | const Bar = enum { A, B, C, D }; | |
| 178 | 104 | |
| 179 | 105 | const Number = enum { Zero, One, Two, Three, Four }; |
| 180 | 106 | |
| ... | ... | @@ -208,18 +134,6 @@ const BareNumber = enum { One, Two, Three }; |
| 208 | 134 | |
| 209 | 135 | const NonExhaustive = enum(u8) { A, B, _ }; |
| 210 | 136 | |
| 211 | test "enum alignment" { | |
| 212 | comptime { | |
| 213 | try expect(@alignOf(AlignTestEnum) >= @alignOf([9]u8)); | |
| 214 | try expect(@alignOf(AlignTestEnum) >= @alignOf(u64)); | |
| 215 | } | |
| 216 | } | |
| 217 | ||
| 218 | const AlignTestEnum = union(enum) { | |
| 219 | A: [9]u8, | |
| 220 | B: u64, | |
| 221 | }; | |
| 222 | ||
| 223 | 137 | const ValueCount1 = enum { |
| 224 | 138 | I0, |
| 225 | 139 | }; |
test/behavior/union_stage1.zig+85-2| ... | ... | @@ -770,6 +770,89 @@ test "union enum type gets a separate scope" { |
| 770 | 770 | try S.doTheTest(); |
| 771 | 771 | } |
| 772 | 772 | test "anytype union field: issue #9233" { |
| 773 | const Baz = union(enum) { bar: anytype }; | |
| 774 | _ = Baz; | |
| 773 | const Quux = union(enum) { bar: anytype }; | |
| 774 | _ = Quux; | |
| 775 | 775 | } |
| 776 | ||
| 777 | const Point = struct { | |
| 778 | x: u64, | |
| 779 | y: u64, | |
| 780 | }; | |
| 781 | const TaggedFoo = union(enum) { | |
| 782 | One: i32, | |
| 783 | Two: Point, | |
| 784 | Three: void, | |
| 785 | }; | |
| 786 | const FooNoVoid = union(enum) { | |
| 787 | One: i32, | |
| 788 | Two: Point, | |
| 789 | }; | |
| 790 | const Baz = enum { A, B, C, D }; | |
| 791 | ||
| 792 | test "tagged union type" { | |
| 793 | const foo1 = TaggedFoo{ .One = 13 }; | |
| 794 | const foo2 = TaggedFoo{ | |
| 795 | .Two = Point{ | |
| 796 | .x = 1234, | |
| 797 | .y = 5678, | |
| 798 | }, | |
| 799 | }; | |
| 800 | try expect(foo1.One == 13); | |
| 801 | try expect(foo2.Two.x == 1234 and foo2.Two.y == 5678); | |
| 802 | const baz = Baz.B; | |
| 803 | ||
| 804 | try expect(baz == Baz.B); | |
| 805 | try expect(@typeInfo(TaggedFoo).Union.fields.len == 3); | |
| 806 | try expect(@typeInfo(Baz).Enum.fields.len == 4); | |
| 807 | try expect(@sizeOf(TaggedFoo) == @sizeOf(FooNoVoid)); | |
| 808 | try expect(@sizeOf(Baz) == 1); | |
| 809 | } | |
| 810 | ||
| 811 | test "tagged union as return value" { | |
| 812 | switch (returnAnInt(13)) { | |
| 813 | TaggedFoo.One => |value| try expect(value == 13), | |
| 814 | else => unreachable, | |
| 815 | } | |
| 816 | } | |
| 817 | ||
| 818 | fn returnAnInt(x: i32) TaggedFoo { | |
| 819 | return TaggedFoo{ .One = x }; | |
| 820 | } | |
| 821 | ||
| 822 | test "constant tagged union with payload" { | |
| 823 | var empty = TaggedUnionWithPayload{ .Empty = {} }; | |
| 824 | var full = TaggedUnionWithPayload{ .Full = 13 }; | |
| 825 | shouldBeEmpty(empty); | |
| 826 | shouldBeNotEmpty(full); | |
| 827 | } | |
| 828 | ||
| 829 | fn shouldBeEmpty(x: TaggedUnionWithPayload) void { | |
| 830 | switch (x) { | |
| 831 | TaggedUnionWithPayload.Empty => {}, | |
| 832 | else => unreachable, | |
| 833 | } | |
| 834 | } | |
| 835 | ||
| 836 | fn shouldBeNotEmpty(x: TaggedUnionWithPayload) void { | |
| 837 | switch (x) { | |
| 838 | TaggedUnionWithPayload.Empty => unreachable, | |
| 839 | else => {}, | |
| 840 | } | |
| 841 | } | |
| 842 | ||
| 843 | const TaggedUnionWithPayload = union(enum) { | |
| 844 | Empty: void, | |
| 845 | Full: i32, | |
| 846 | }; | |
| 847 | ||
| 848 | test "enum alignment" { | |
| 849 | comptime { | |
| 850 | try expect(@alignOf(AlignTestTaggedUnion) >= @alignOf([9]u8)); | |
| 851 | try expect(@alignOf(AlignTestTaggedUnion) >= @alignOf(u64)); | |
| 852 | } | |
| 853 | } | |
| 854 | ||
| 855 | const AlignTestTaggedUnion = union(enum) { | |
| 856 | A: [9]u8, | |
| 857 | B: u64, | |
| 858 | }; |