aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2022-06-28 17:15:10 +0300
committerJakub Konka <kubkon@jakubkonka.com>2022-06-30 09:57:38 +0200
commit6cadac18b8fb1775815fbb3f16f503c5de0e89d0 (patch)
tree2b02f39c02b1d0bad95ae2f3ae7db47c0862fa19 /src/Sema.zig
parent2e7dc5e15192431c64eca458ecfdce3d07b89f69 (diff)
downloadzig-6cadac18b8fb1775815fbb3f16f503c5de0e89d0.tar.gz
zig-6cadac18b8fb1775815fbb3f16f503c5de0e89d0.zip
Sema: improve auto generated union enum name
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig55
1 files changed, 43 insertions, 12 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 6f2cad3529..3015ac5d8e 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -14883,7 +14883,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
union_obj.tag_ty = if (tag_type_val.optionalValue()) |payload_val| blk: {
var buffer: Value.ToTypeBuffer = undefined;
break :blk try payload_val.toType(&buffer).copy(new_decl_arena_allocator);
- } else try sema.generateUnionTagTypeSimple(block, fields_len);
+ } else try sema.generateUnionTagTypeSimple(block, fields_len, null);
// Fields
if (fields_len > 0) {
@@ -24237,7 +24237,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
if (small.auto_enum_tag) {
// The provided type is an integer type and we must construct the enum tag type here.
int_tag_ty = provided_ty;
- union_obj.tag_ty = try sema.generateUnionTagTypeNumbered(&block_scope, fields_len, provided_ty);
+ union_obj.tag_ty = try sema.generateUnionTagTypeNumbered(&block_scope, fields_len, provided_ty, union_obj);
const enum_obj = union_obj.tag_ty.castTag(.enum_numbered).?.data;
enum_field_names = &enum_obj.fields;
enum_value_map = &enum_obj.values;
@@ -24253,7 +24253,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
// If auto_enum_tag is false, this is an untagged union. However, for semantic analysis
// purposes, we still auto-generate an enum tag type the same way. That the union is
// untagged is represented by the Type tag (union vs union_tagged).
- union_obj.tag_ty = try sema.generateUnionTagTypeSimple(&block_scope, fields_len);
+ union_obj.tag_ty = try sema.generateUnionTagTypeSimple(&block_scope, fields_len, union_obj);
enum_field_names = &union_obj.tag_ty.castTag(.enum_simple).?.data.fields;
}
@@ -24422,6 +24422,7 @@ fn generateUnionTagTypeNumbered(
block: *Block,
fields_len: u32,
int_ty: Type,
+ union_obj: *Module.Union,
) !Type {
const mod = sema.mod;
@@ -24437,13 +24438,24 @@ fn generateUnionTagTypeNumbered(
};
const enum_ty = Type.initPayload(&enum_ty_payload.base);
const enum_val = try Value.Tag.ty.create(new_decl_arena_allocator, enum_ty);
- // TODO better type name
- const new_decl_index = try mod.createAnonymousDecl(block, .{
+
+ const src_decl = mod.declPtr(block.src_decl);
+ const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);
+ errdefer mod.destroyDecl(new_decl_index);
+ const name = name: {
+ const fqn = try union_obj.getFullyQualifiedName(mod);
+ defer sema.gpa.free(fqn);
+ break :name try std.fmt.allocPrintZ(mod.gpa, "@typeInfo({s}).Union.tag_type.?", .{fqn});
+ };
+ try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, block.namespace, .{
.ty = Type.type,
.val = enum_val,
- });
+ }, name);
+ sema.mod.declPtr(new_decl_index).name_fully_qualified = true;
+
const new_decl = mod.declPtr(new_decl_index);
new_decl.owns_tv = true;
+ new_decl.name_fully_qualified = true;
errdefer mod.abortAnonDecl(new_decl_index);
enum_obj.* = .{
@@ -24463,7 +24475,7 @@ fn generateUnionTagTypeNumbered(
return enum_ty;
}
-fn generateUnionTagTypeSimple(sema: *Sema, block: *Block, fields_len: usize) !Type {
+fn generateUnionTagTypeSimple(sema: *Sema, block: *Block, fields_len: usize, maybe_union_obj: ?*Module.Union) !Type {
const mod = sema.mod;
var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
@@ -24478,11 +24490,30 @@ fn generateUnionTagTypeSimple(sema: *Sema, block: *Block, fields_len: usize) !Ty
};
const enum_ty = Type.initPayload(&enum_ty_payload.base);
const enum_val = try Value.Tag.ty.create(new_decl_arena_allocator, enum_ty);
- // TODO better type name
- const new_decl_index = try mod.createAnonymousDecl(block, .{
- .ty = Type.type,
- .val = enum_val,
- });
+
+ const new_decl_index = new_decl_index: {
+ const union_obj = maybe_union_obj orelse {
+ break :new_decl_index try mod.createAnonymousDecl(block, .{
+ .ty = Type.type,
+ .val = enum_val,
+ });
+ };
+ const src_decl = mod.declPtr(block.src_decl);
+ const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);
+ errdefer mod.destroyDecl(new_decl_index);
+ const name = name: {
+ const fqn = try union_obj.getFullyQualifiedName(mod);
+ defer sema.gpa.free(fqn);
+ break :name try std.fmt.allocPrintZ(mod.gpa, "@typeInfo({s}).Union.tag_type.?", .{fqn});
+ };
+ try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, block.namespace, .{
+ .ty = Type.type,
+ .val = enum_val,
+ }, name);
+ sema.mod.declPtr(new_decl_index).name_fully_qualified = true;
+ break :new_decl_index new_decl_index;
+ };
+
const new_decl = mod.declPtr(new_decl_index);
new_decl.owns_tv = true;
errdefer mod.abortAnonDecl(new_decl_index);