| author | |
| committer | |
| log | f41b9cdb6d7f954495ffca168108ddd38bf27353 |
| tree | 3e7855187364efa94d4492eb19b79599b8d46926 |
| parent | 629a54c711c0a71381ea1e5b1a62e5fcc986e048 |
3 files changed, 62 insertions(+), 59 deletions(-)
src/Sema.zig+7-1| ... | ... | @@ -1759,6 +1759,11 @@ fn zirEnumDecl( |
| 1759 | 1759 | const body = sema.code.extra[extra_index..][0..body_len]; |
| 1760 | 1760 | if (fields_len == 0) { |
| 1761 | 1761 | assert(body.len == 0); |
| 1762 | if (tag_type_ref != .none) { | |
| 1763 | // TODO better source location | |
| 1764 | const ty = try sema.resolveType(block, src, tag_type_ref); | |
| 1765 | enum_obj.tag_ty = try ty.copy(new_decl_arena_allocator); | |
| 1766 | } | |
| 1762 | 1767 | try new_decl.finalizeNewArena(&new_decl_arena); |
| 1763 | 1768 | return sema.analyzeDeclVal(block, src, new_decl); |
| 1764 | 1769 | } |
| ... | ... | @@ -1810,7 +1815,8 @@ fn zirEnumDecl( |
| 1810 | 1815 | const tag_ty = blk: { |
| 1811 | 1816 | if (tag_type_ref != .none) { |
| 1812 | 1817 | // TODO better source location |
| 1813 | break :blk try sema.resolveType(block, src, tag_type_ref); | |
| 1818 | const ty = try sema.resolveType(block, src, tag_type_ref); | |
| 1819 | break :blk try ty.copy(new_decl_arena_allocator); | |
| 1814 | 1820 | } |
| 1815 | 1821 | const bits = std.math.log2_int_ceil(usize, fields_len); |
| 1816 | 1822 | break :blk try Type.Tag.int_unsigned.create(new_decl_arena_allocator, bits); |
test/behavior/enum.zig+53| ... | ... | @@ -646,3 +646,56 @@ test "non-exhaustive enum" { |
| 646 | 646 | try S.doTheTest(52); |
| 647 | 647 | comptime try S.doTheTest(52); |
| 648 | 648 | } |
| 649 | ||
| 650 | test "empty non-exhaustive enum" { | |
| 651 | const S = struct { | |
| 652 | const E = enum(u8) { _ }; | |
| 653 | ||
| 654 | fn doTheTest(y: u8) !void { | |
| 655 | var e = @intToEnum(E, y); | |
| 656 | try expect(switch (e) { | |
| 657 | _ => true, | |
| 658 | }); | |
| 659 | try expect(@enumToInt(e) == y); | |
| 660 | ||
| 661 | try expect(@typeInfo(E).Enum.fields.len == 0); | |
| 662 | try expect(@typeInfo(E).Enum.is_exhaustive == false); | |
| 663 | } | |
| 664 | }; | |
| 665 | try S.doTheTest(42); | |
| 666 | comptime try S.doTheTest(42); | |
| 667 | } | |
| 668 | ||
| 669 | test "single field non-exhaustive enum" { | |
| 670 | const S = struct { | |
| 671 | const E = enum(u8) { a, _ }; | |
| 672 | fn doTheTest(y: u8) !void { | |
| 673 | var e: E = .a; | |
| 674 | try expect(switch (e) { | |
| 675 | .a => true, | |
| 676 | _ => false, | |
| 677 | }); | |
| 678 | e = @intToEnum(E, 12); | |
| 679 | try expect(switch (e) { | |
| 680 | .a => false, | |
| 681 | _ => true, | |
| 682 | }); | |
| 683 | ||
| 684 | try expect(switch (e) { | |
| 685 | .a => false, | |
| 686 | else => true, | |
| 687 | }); | |
| 688 | e = .a; | |
| 689 | try expect(switch (e) { | |
| 690 | .a => true, | |
| 691 | else => false, | |
| 692 | }); | |
| 693 | ||
| 694 | try expect(@enumToInt(@intToEnum(E, y)) == y); | |
| 695 | try expect(@typeInfo(E).Enum.fields.len == 1); | |
| 696 | try expect(@typeInfo(E).Enum.is_exhaustive == false); | |
| 697 | } | |
| 698 | }; | |
| 699 | try S.doTheTest(23); | |
| 700 | comptime try S.doTheTest(23); | |
| 701 | } |
test/behavior/enum_stage1.zig+2-58| ... | ... | @@ -2,64 +2,6 @@ const expect = @import("std").testing.expect; |
| 2 | 2 | const mem = @import("std").mem; |
| 3 | 3 | const Tag = @import("std").meta.Tag; |
| 4 | 4 | |
| 5 | test "empty non-exhaustive enum" { | |
| 6 | const S = struct { | |
| 7 | const E = enum(u8) { | |
| 8 | _, | |
| 9 | }; | |
| 10 | fn doTheTest(y: u8) !void { | |
| 11 | var e = @intToEnum(E, y); | |
| 12 | try expect(switch (e) { | |
| 13 | _ => true, | |
| 14 | }); | |
| 15 | try expect(@enumToInt(e) == y); | |
| 16 | ||
| 17 | try expect(@typeInfo(E).Enum.fields.len == 0); | |
| 18 | try expect(@typeInfo(E).Enum.is_exhaustive == false); | |
| 19 | } | |
| 20 | }; | |
| 21 | try S.doTheTest(42); | |
| 22 | comptime try S.doTheTest(42); | |
| 23 | } | |
| 24 | ||
| 25 | test "single field non-exhaustive enum" { | |
| 26 | const S = struct { | |
| 27 | const E = enum(u8) { a, _ }; | |
| 28 | fn doTheTest(y: u8) !void { | |
| 29 | var e: E = .a; | |
| 30 | try expect(switch (e) { | |
| 31 | .a => true, | |
| 32 | _ => false, | |
| 33 | }); | |
| 34 | e = @intToEnum(E, 12); | |
| 35 | try expect(switch (e) { | |
| 36 | .a => false, | |
| 37 | _ => true, | |
| 38 | }); | |
| 39 | ||
| 40 | try expect(switch (e) { | |
| 41 | .a => false, | |
| 42 | else => true, | |
| 43 | }); | |
| 44 | e = .a; | |
| 45 | try expect(switch (e) { | |
| 46 | .a => true, | |
| 47 | else => false, | |
| 48 | }); | |
| 49 | ||
| 50 | try expect(@enumToInt(@intToEnum(E, y)) == y); | |
| 51 | try expect(@typeInfo(E).Enum.fields.len == 1); | |
| 52 | try expect(@typeInfo(E).Enum.is_exhaustive == false); | |
| 53 | } | |
| 54 | }; | |
| 55 | try S.doTheTest(23); | |
| 56 | comptime try S.doTheTest(23); | |
| 57 | } | |
| 58 | ||
| 59 | const Bar = enum { A, B, C, D }; | |
| 60 | ||
| 61 | const Number = enum { Zero, One, Two, Three, Four }; | |
| 62 | ||
| 63 | 5 | test "@tagName" { |
| 64 | 6 | try expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three")); |
| 65 | 7 | comptime try expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three")); |
| ... | ... | @@ -304,6 +246,8 @@ test "enum with one member and custom tag type" { |
| 304 | 246 | try expect(@enumToInt(E2.One) == 2); |
| 305 | 247 | } |
| 306 | 248 | |
| 249 | const Bar = enum { A, B, C, D }; | |
| 250 | ||
| 307 | 251 | test "enum literal casting to optional" { |
| 308 | 252 | var bar: ?Bar = undefined; |
| 309 | 253 | bar = .B; |