diff --git a/src/Sema.zig b/src/Sema.zig index 2483f313a8..63c39b3bb6 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -20630,6 +20630,16 @@ fn zirReify( } const layout = try sema.interpretBuiltinType(block, operand_src, layout_val, std.builtin.Type.ContainerLayout); + const has_tag = tag_type_val.optionalValue(zcu) != null; + + if (has_tag) { + switch (layout) { + .@"extern" => return sema.fail(block, src, "extern union does not support enum tag type", .{}), + .@"packed" => return sema.fail(block, src, "packed union does not support enum tag type", .{}), + .auto => {}, + } + } + const fields_arr = try sema.derefSliceAsArray(block, operand_src, fields_val, .{ .simple = .union_fields }); return sema.reifyUnion(block, inst, src, layout, tag_type_val, fields_arr, name_strategy); diff --git a/test/cases/compile_errors/reify_type_for_tagged_extern_union.zig b/test/cases/compile_errors/reify_type_for_tagged_extern_union.zig new file mode 100644 index 0000000000..24169e2ff3 --- /dev/null +++ b/test/cases/compile_errors/reify_type_for_tagged_extern_union.zig @@ -0,0 +1,34 @@ +const Tag = @Type(.{ + .@"enum" = .{ + .tag_type = u2, + .fields = &.{ + .{ .name = "signed", .value = 0 }, + .{ .name = "unsigned", .value = 1 }, + }, + .decls = &.{}, + .is_exhaustive = true, + }, +}); + +const Extern = @Type(.{ + .@"union" = .{ + .layout = .@"extern", + .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: Extern = .{ .signed = -1 }; + _ = tagged; +} + +// error +// backend=stage2 +// target=native +// +// :13:16: error: extern union does not support enum tag type diff --git a/test/cases/compile_errors/reify_type_for_tagged_packed_union.zig b/test/cases/compile_errors/reify_type_for_tagged_packed_union.zig new file mode 100644 index 0000000000..ee085b07b3 --- /dev/null +++ b/test/cases/compile_errors/reify_type_for_tagged_packed_union.zig @@ -0,0 +1,34 @@ +const Tag = @Type(.{ + .@"enum" = .{ + .tag_type = u2, + .fields = &.{ + .{ .name = "signed", .value = 0 }, + .{ .name = "unsigned", .value = 1 }, + }, + .decls = &.{}, + .is_exhaustive = true, + }, +}); + +const Packed = @Type(.{ + .@"union" = .{ + .layout = .@"packed", + .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: Packed = .{ .signed = -1 }; + _ = tagged; +} + +// error +// backend=stage2 +// target=native +// +// :13:16: error: packed union does not support enum tag type