Commit f41b9cdb6d
Changed files (3)
src
test
behavior
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);
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);
+}
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;