Sema+llvm: improve handling of namespace-like unions

Closes #13557
This commit is contained in:
Veikka Tuominen 2022-11-16 01:11:12 +02:00
parent fe6249348f
commit 28cbe5e92a
3 changed files with 26 additions and 5 deletions

View File

@ -22476,13 +22476,12 @@ fn fieldVal(
);
},
.Union => {
const union_ty = try sema.resolveTypeFields(child_type);
if (union_ty.getNamespace()) |namespace| {
if (child_type.getNamespace()) |namespace| {
if (try sema.namespaceLookupVal(block, src, namespace, field_name)) |inst| {
return inst;
}
}
const union_ty = try sema.resolveTypeFields(child_type);
if (union_ty.unionTagType()) |enum_ty| {
if (enum_ty.enumFieldIndex(field_name)) |field_index_usize| {
const field_index = @intCast(u32, field_index_usize);

View File

@ -2137,7 +2137,8 @@ pub const Object = struct {
break :blk fwd_decl;
};
if (!ty.hasRuntimeBitsIgnoreComptime()) {
const union_obj = ty.cast(Type.Payload.Union).?.data;
if (!union_obj.haveFieldTypes() or !ty.hasRuntimeBitsIgnoreComptime()) {
const union_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
dib.replaceTemporary(fwd_decl, union_di_ty);
// The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
@ -2147,7 +2148,6 @@ pub const Object = struct {
}
const layout = ty.unionGetLayout(target);
const union_obj = ty.cast(Type.Payload.Union).?.data;
if (layout.payload_size == 0) {
const tag_di_ty = try o.lowerDebugType(union_obj.tag_ty, .full);

View File

@ -1388,3 +1388,25 @@ test "packed union in packed struct" {
const a: S = .{ .nested = .{ .foo = 123 }, .bar = 5 };
try expect(a.unpack() == 123);
}
test "Namespace-like union" {
const DepType = enum {
git,
http,
const DepType = @This();
const Version = union(DepType) {
git: Git,
http: void,
const Git = enum {
branch,
tag,
commit,
fn frozen(self: Git) bool {
return self == .tag;
}
};
};
};
var a: DepType.Version.Git = .tag;
try expect(a.frozen());
}