mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
Sema: improve auto generated union enum name
This commit is contained in:
parent
2e7dc5e151
commit
6cadac18b8
@ -503,6 +503,8 @@ pub const Decl = struct {
|
||||
alive: bool,
|
||||
/// Whether the Decl is a `usingnamespace` declaration.
|
||||
is_usingnamespace: bool,
|
||||
/// If true `name` is already fully qualified.
|
||||
name_fully_qualified: bool = false,
|
||||
|
||||
/// Represents the position of the code in the output file.
|
||||
/// This is populated regardless of semantic analysis and code generation.
|
||||
@ -686,6 +688,9 @@ pub const Decl = struct {
|
||||
|
||||
pub fn renderFullyQualifiedName(decl: Decl, mod: *Module, writer: anytype) !void {
|
||||
const unqualified_name = mem.sliceTo(decl.name, 0);
|
||||
if (decl.name_fully_qualified) {
|
||||
return writer.writeAll(unqualified_name);
|
||||
}
|
||||
return decl.src_namespace.renderFullyQualifiedName(mod, unqualified_name, writer);
|
||||
}
|
||||
|
||||
|
||||
55
src/Sema.zig
55
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);
|
||||
|
||||
@ -13,8 +13,7 @@ const InvalidToken = struct {};
|
||||
const ExpectedVarDeclOrFn = struct {};
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
// is_test=1
|
||||
//
|
||||
// tmp.zig:4:9: error: expected type '@typeInfo(Error).Union.tag_type.?', found 'type'
|
||||
// :4:9: error: expected type '@typeInfo(tmp.Error).Union.tag_type.?', found 'type'
|
||||
Loading…
x
Reference in New Issue
Block a user