diff --git a/src/Sema.zig b/src/Sema.zig index 257b50322b..3592cbf93d 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -1759,6 +1759,11 @@ fn zirEnumDecl( const body = sema.code.extra[extra_index..][0..body_len]; if (fields_len == 0) { assert(body.len == 0); + if (tag_type_ref != .none) { + // TODO better source location + const ty = try sema.resolveType(block, src, tag_type_ref); + enum_obj.tag_ty = try ty.copy(new_decl_arena_allocator); + } try new_decl.finalizeNewArena(&new_decl_arena); return sema.analyzeDeclVal(block, src, new_decl); } @@ -1810,7 +1815,8 @@ fn zirEnumDecl( const tag_ty = blk: { if (tag_type_ref != .none) { // TODO better source location - break :blk try sema.resolveType(block, src, tag_type_ref); + const ty = try sema.resolveType(block, src, tag_type_ref); + break :blk try ty.copy(new_decl_arena_allocator); } const bits = std.math.log2_int_ceil(usize, fields_len); break :blk try Type.Tag.int_unsigned.create(new_decl_arena_allocator, bits); diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig index 3429f62229..38a92de164 100644 --- a/test/behavior/enum.zig +++ b/test/behavior/enum.zig @@ -646,3 +646,56 @@ test "non-exhaustive enum" { try S.doTheTest(52); comptime try S.doTheTest(52); } + +test "empty non-exhaustive enum" { + const S = struct { + const E = enum(u8) { _ }; + + fn doTheTest(y: u8) !void { + var e = @intToEnum(E, y); + try expect(switch (e) { + _ => true, + }); + try expect(@enumToInt(e) == y); + + try expect(@typeInfo(E).Enum.fields.len == 0); + try expect(@typeInfo(E).Enum.is_exhaustive == false); + } + }; + try S.doTheTest(42); + comptime try S.doTheTest(42); +} + +test "single field non-exhaustive enum" { + const S = struct { + const E = enum(u8) { a, _ }; + fn doTheTest(y: u8) !void { + var e: E = .a; + try expect(switch (e) { + .a => true, + _ => false, + }); + e = @intToEnum(E, 12); + try expect(switch (e) { + .a => false, + _ => true, + }); + + try expect(switch (e) { + .a => false, + else => true, + }); + e = .a; + try expect(switch (e) { + .a => true, + else => false, + }); + + try expect(@enumToInt(@intToEnum(E, y)) == y); + try expect(@typeInfo(E).Enum.fields.len == 1); + try expect(@typeInfo(E).Enum.is_exhaustive == false); + } + }; + try S.doTheTest(23); + comptime try S.doTheTest(23); +} diff --git a/test/behavior/enum_stage1.zig b/test/behavior/enum_stage1.zig index 9d1770f446..ba0fcb58bc 100644 --- a/test/behavior/enum_stage1.zig +++ b/test/behavior/enum_stage1.zig @@ -2,64 +2,6 @@ const expect = @import("std").testing.expect; const mem = @import("std").mem; const Tag = @import("std").meta.Tag; -test "empty non-exhaustive enum" { - const S = struct { - const E = enum(u8) { - _, - }; - fn doTheTest(y: u8) !void { - var e = @intToEnum(E, y); - try expect(switch (e) { - _ => true, - }); - try expect(@enumToInt(e) == y); - - try expect(@typeInfo(E).Enum.fields.len == 0); - try expect(@typeInfo(E).Enum.is_exhaustive == false); - } - }; - try S.doTheTest(42); - comptime try S.doTheTest(42); -} - -test "single field non-exhaustive enum" { - const S = struct { - const E = enum(u8) { a, _ }; - fn doTheTest(y: u8) !void { - var e: E = .a; - try expect(switch (e) { - .a => true, - _ => false, - }); - e = @intToEnum(E, 12); - try expect(switch (e) { - .a => false, - _ => true, - }); - - try expect(switch (e) { - .a => false, - else => true, - }); - e = .a; - try expect(switch (e) { - .a => true, - else => false, - }); - - try expect(@enumToInt(@intToEnum(E, y)) == y); - try expect(@typeInfo(E).Enum.fields.len == 1); - try expect(@typeInfo(E).Enum.is_exhaustive == false); - } - }; - try S.doTheTest(23); - comptime try S.doTheTest(23); -} - -const Bar = enum { A, B, C, D }; - -const Number = enum { Zero, One, Two, Three, Four }; - test "@tagName" { try expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three")); comptime try expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three")); @@ -304,6 +246,8 @@ test "enum with one member and custom tag type" { try expect(@enumToInt(E2.One) == 2); } +const Bar = enum { A, B, C, D }; + test "enum literal casting to optional" { var bar: ?Bar = undefined; bar = .B;