mirror of
https://github.com/ziglang/zig.git
synced 2026-02-15 13:58:27 +00:00
stage1: fix @Type(.Union) not resolving its tag type
Fixes https://github.com/ziglang/zig/issues/6339
This commit is contained in:
parent
281fc10ec5
commit
2962be8135
@ -3155,22 +3155,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
|
||||
tag_type->data.enumeration.fields_by_name.init(field_count);
|
||||
tag_type->data.enumeration.decls_scope = union_type->data.unionation.decls_scope;
|
||||
} else if (enum_type_node != nullptr) {
|
||||
ZigType *enum_type = analyze_type_expr(g, scope, enum_type_node);
|
||||
if (type_is_invalid(enum_type)) {
|
||||
union_type->data.unionation.resolve_status = ResolveStatusInvalid;
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
if (enum_type->id != ZigTypeIdEnum) {
|
||||
union_type->data.unionation.resolve_status = ResolveStatusInvalid;
|
||||
add_node_error(g, enum_type_node,
|
||||
buf_sprintf("expected enum tag type, found '%s'", buf_ptr(&enum_type->name)));
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
if ((err = type_resolve(g, enum_type, ResolveStatusAlignmentKnown))) {
|
||||
assert(g->errors.length != 0);
|
||||
return err;
|
||||
}
|
||||
tag_type = enum_type;
|
||||
tag_type = analyze_type_expr(g, scope, enum_type_node);
|
||||
} else {
|
||||
if (decl_node->type == NodeTypeContainerDecl) {
|
||||
tag_type = nullptr;
|
||||
@ -3179,6 +3164,20 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
|
||||
}
|
||||
}
|
||||
if (tag_type != nullptr) {
|
||||
if (type_is_invalid(tag_type)) {
|
||||
union_type->data.unionation.resolve_status = ResolveStatusInvalid;
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
if (tag_type->id != ZigTypeIdEnum) {
|
||||
union_type->data.unionation.resolve_status = ResolveStatusInvalid;
|
||||
add_node_error(g, enum_type_node != nullptr ? enum_type_node : decl_node,
|
||||
buf_sprintf("expected enum tag type, found '%s'", buf_ptr(&tag_type->name)));
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
if ((err = type_resolve(g, tag_type, ResolveStatusAlignmentKnown))) {
|
||||
assert(g->errors.length != 0);
|
||||
return err;
|
||||
}
|
||||
covered_enum_fields = heap::c_allocator.allocate<bool>(tag_type->data.enumeration.src_field_count);
|
||||
}
|
||||
union_type->data.unionation.tag_type = tag_type;
|
||||
|
||||
@ -374,3 +374,45 @@ test "Type.Union" {
|
||||
tagged = .{ .unsigned = 1 };
|
||||
testing.expectEqual(Tag.unsigned, tagged);
|
||||
}
|
||||
|
||||
test "Type.Union from Type.Enum" {
|
||||
const Tag = @Type(.{
|
||||
.Enum = .{
|
||||
.layout = .Auto,
|
||||
.tag_type = u0,
|
||||
.fields = &[_]TypeInfo.EnumField{
|
||||
.{ .name = "working_as_expected", .value = 0 },
|
||||
},
|
||||
.decls = &[_]TypeInfo.Declaration{},
|
||||
.is_exhaustive = true,
|
||||
},
|
||||
});
|
||||
const T = @Type(.{
|
||||
.Union = .{
|
||||
.layout = .Auto,
|
||||
.tag_type = Tag,
|
||||
.fields = &[_]TypeInfo.UnionField{
|
||||
.{ .name = "working_as_expected", .field_type = u32 },
|
||||
},
|
||||
.decls = &[_]TypeInfo.Declaration{},
|
||||
},
|
||||
});
|
||||
_ = T;
|
||||
_ = @typeInfo(T).Union;
|
||||
}
|
||||
|
||||
test "Type.Union from regular enum" {
|
||||
const E = enum { working_as_expected = 0 };
|
||||
const T = @Type(.{
|
||||
.Union = .{
|
||||
.layout = .Auto,
|
||||
.tag_type = E,
|
||||
.fields = &[_]TypeInfo.UnionField{
|
||||
.{ .name = "working_as_expected", .field_type = u32 },
|
||||
},
|
||||
.decls = &[_]TypeInfo.Declaration{},
|
||||
},
|
||||
});
|
||||
_ = T;
|
||||
_ = @typeInfo(T).Union;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user