Sema: fix handling of non-standard int types in empty non-exhaustive enums

Closes #12649
This commit is contained in:
Veikka Tuominen 2022-08-28 13:37:38 +03:00
parent 6aead18ab3
commit 776caaf999
3 changed files with 13 additions and 17 deletions

View File

@ -2497,18 +2497,6 @@ fn zirEnumDecl(
extra_index = try mod.scanNamespace(&enum_obj.namespace, extra_index, decls_len, new_decl);
const body = sema.code.extra[extra_index..][0..body_len];
if (fields_len == 0) {
assert(body.len == 0);
if (tag_type_ref != .none) {
const ty = try sema.resolveType(block, tag_ty_src, tag_type_ref);
if (ty.zigTypeTag() != .Int and ty.zigTypeTag() != .ComptimeInt) {
return sema.fail(block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(sema.mod)});
}
enum_obj.tag_ty = try ty.copy(new_decl_arena_allocator);
enum_obj.tag_ty_inferred = false;
}
return decl_val;
}
extra_index += body.len;
const bit_bags_count = std.math.divCeil(usize, fields_len, 32) catch unreachable;
@ -2566,6 +2554,9 @@ fn zirEnumDecl(
}
enum_obj.tag_ty = try ty.copy(decl_arena_allocator);
enum_obj.tag_ty_inferred = false;
} else if (fields_len == 0) {
enum_obj.tag_ty = try Type.Tag.int_unsigned.create(decl_arena_allocator, 0);
enum_obj.tag_ty_inferred = true;
} else {
const bits = std.math.log2_int_ceil(usize, fields_len);
enum_obj.tag_ty = try Type.Tag.int_unsigned.create(decl_arena_allocator, bits);

View File

@ -1721,13 +1721,13 @@ const Writer = struct {
const body = self.code.extra[extra_index..][0..body_len];
extra_index += body.len;
const prev_parent_decl_node = self.parent_decl_node;
if (src_node) |off| self.parent_decl_node = self.relativeToNodeIndex(off);
try self.writeBracedDecl(stream, body);
if (fields_len == 0) {
assert(body.len == 0);
try stream.writeAll("{}, {})");
try stream.writeAll(", {})");
self.parent_decl_node = prev_parent_decl_node;
} else {
const prev_parent_decl_node = self.parent_decl_node;
if (src_node) |off| self.parent_decl_node = self.relativeToNodeIndex(off);
try self.writeBracedDecl(stream, body);
try stream.writeAll(", {\n");
self.indent += 2;

View File

@ -1170,3 +1170,8 @@ test "switch on an extern enum with negative value" {
Foo.Bar => return,
}
}
test "Non-exhaustive enum with nonstandard int size behaves correctly" {
const E = enum(u15) { _ };
try expect(@sizeOf(E) == @sizeOf(u15));
}