Commit 501a2350ab
Changed files (4)
src
test
behavior
src/Sema.zig
@@ -20888,7 +20888,7 @@ fn zirReify(
enum_field_names[i] = field_name;
}
- if (explicit_tags_seen.len > 0) {
+ if (enum_tag_ty != .none) {
const tag_info = ip.indexToKey(enum_tag_ty).enum_type;
const enum_index = tag_info.nameIndex(ip, field_name) orelse {
const msg = msg: {
@@ -20902,6 +20902,7 @@ fn zirReify(
};
return sema.failWithOwnedErrorMsg(block, msg);
};
+ assert(explicit_tags_seen.len == tag_info.names.len);
// No check for duplicate because the check already happened in order
// to create the enum type in the first place.
assert(!explicit_tags_seen[enum_index]);
@@ -20967,13 +20968,14 @@ fn zirReify(
}
}
- if (explicit_tags_seen.len > 0) {
+ if (enum_tag_ty != .none) {
const tag_info = ip.indexToKey(enum_tag_ty).enum_type;
if (tag_info.names.len > fields_len) {
const msg = msg: {
const msg = try sema.errMsg(block, src, "enum field(s) missing in union", .{});
errdefer msg.destroy(gpa);
+ assert(explicit_tags_seen.len == tag_info.names.len);
for (tag_info.names.get(ip), 0..) |field_name, field_index| {
if (explicit_tags_seen[field_index]) continue;
try sema.addFieldErrNote(Type.fromInterned(enum_tag_ty), field_index, msg, "field '{}' missing, declared here", .{
test/behavior/type.zig
@@ -482,6 +482,39 @@ test "Type.Union from regular enum" {
_ = @typeInfo(T).Union;
}
+test "Type.Union from empty regular enum" {
+ const E = enum {};
+ const U = @Type(.{
+ .Union = .{
+ .layout = .Auto,
+ .tag_type = E,
+ .fields = &.{},
+ .decls = &.{},
+ },
+ });
+ try testing.expectEqual(@sizeOf(U), 0);
+}
+
+test "Type.Union from empty Type.Enum" {
+ const E = @Type(.{
+ .Enum = .{
+ .tag_type = u0,
+ .fields = &.{},
+ .decls = &.{},
+ .is_exhaustive = true,
+ },
+ });
+ const U = @Type(.{
+ .Union = .{
+ .layout = .Auto,
+ .tag_type = E,
+ .fields = &.{},
+ .decls = &.{},
+ },
+ });
+ try testing.expectEqual(@sizeOf(U), 0);
+}
+
test "Type.Fn" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
test/cases/compile_errors/reify_type_for_tagged_union_with_no_enum_fields.zig
@@ -0,0 +1,30 @@
+const Tag = @Type(.{
+ .Enum = .{
+ .tag_type = u0,
+ .fields = &.{},
+ .decls = &.{},
+ .is_exhaustive = true,
+ },
+});
+const Tagged = @Type(.{
+ .Union = .{
+ .layout = .Auto,
+ .tag_type = Tag,
+ .fields = &.{
+ .{ .name = "signed", .type = i32, .alignment = @alignOf(i32) },
+ .{ .name = "unsigned", .type = u32, .alignment = @alignOf(u32) },
+ },
+ .decls = &.{},
+ },
+});
+export fn entry() void {
+ const tagged: Tagged = undefined;
+ _ = tagged;
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :9:16: error: no field named 'signed' in enum 'tmp.Tag'
+// :1:13: note: enum declared here
test/cases/compile_errors/reify_type_for_tagged_union_with_no_union_fields.zig
@@ -0,0 +1,32 @@
+const Tag = @Type(.{
+ .Enum = .{
+ .tag_type = u1,
+ .fields = &.{
+ .{ .name = "signed", .value = 0 },
+ .{ .name = "unsigned", .value = 1 },
+ },
+ .decls = &.{},
+ .is_exhaustive = true,
+ },
+});
+const Tagged = @Type(.{
+ .Union = .{
+ .layout = .Auto,
+ .tag_type = Tag,
+ .fields = &.{},
+ .decls = &.{},
+ },
+});
+export fn entry() void {
+ const tagged: Tagged = undefined;
+ _ = tagged;
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :12:16: error: enum field(s) missing in union
+// :1:13: note: field 'signed' missing, declared here
+// :1:13: note: field 'unsigned' missing, declared here
+// :1:13: note: enum declared here