Sema: fix enum tag type not initialized when 0 fields
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user