authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-16 01:11:12+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-16 01:13:35+02:00
log28cbe5e92a36c81177dbcd2f33fc792468c08304
tree4c75818b2b300ece49cc43947f7b850dfb483007
parentfe6249348f615c975a2db53bb0c93f83bd2a281b

Sema+llvm: improve handling of namespace-like unions

Closes #13557

3 files changed, 26 insertions(+), 5 deletions(-)

src/Sema.zig+2-3
......@@ -22476,13 +22476,12 @@ fn fieldVal(
2247622476 );
2247722477 },
2247822478 .Union => {
22479 const union_ty = try sema.resolveTypeFields(child_type);
22480
22481 if (union_ty.getNamespace()) |namespace| {
22479 if (child_type.getNamespace()) |namespace| {
2248222480 if (try sema.namespaceLookupVal(block, src, namespace, field_name)) |inst| {
2248322481 return inst;
2248422482 }
2248522483 }
22484 const union_ty = try sema.resolveTypeFields(child_type);
2248622485 if (union_ty.unionTagType()) |enum_ty| {
2248722486 if (enum_ty.enumFieldIndex(field_name)) |field_index_usize| {
2248822487 const field_index = @intCast(u32, field_index_usize);
src/codegen/llvm.zig+2-2
......@@ -2137,7 +2137,8 @@ pub const Object = struct {
21372137 break :blk fwd_decl;
21382138 };
21392139
2140 if (!ty.hasRuntimeBitsIgnoreComptime()) {
2140 const union_obj = ty.cast(Type.Payload.Union).?.data;
2141 if (!union_obj.haveFieldTypes() or !ty.hasRuntimeBitsIgnoreComptime()) {
21412142 const union_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
21422143 dib.replaceTemporary(fwd_decl, union_di_ty);
21432144 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
......@@ -2147,7 +2148,6 @@ pub const Object = struct {
21472148 }
21482149
21492150 const layout = ty.unionGetLayout(target);
2150 const union_obj = ty.cast(Type.Payload.Union).?.data;
21512151
21522152 if (layout.payload_size == 0) {
21532153 const tag_di_ty = try o.lowerDebugType(union_obj.tag_ty, .full);
test/behavior/union.zig+22
......@@ -1388,3 +1388,25 @@ test "packed union in packed struct" {
13881388 const a: S = .{ .nested = .{ .foo = 123 }, .bar = 5 };
13891389 try expect(a.unpack() == 123);
13901390}
1391
1392test "Namespace-like union" {
1393 const DepType = enum {
1394 git,
1395 http,
1396 const DepType = @This();
1397 const Version = union(DepType) {
1398 git: Git,
1399 http: void,
1400 const Git = enum {
1401 branch,
1402 tag,
1403 commit,
1404 fn frozen(self: Git) bool {
1405 return self == .tag;
1406 }
1407 };
1408 };
1409 };
1410 var a: DepType.Version.Git = .tag;
1411 try expect(a.frozen());
1412}