Skip to content

Commit eb7d36a

Browse files
LemonBoyandrewrk
authored andcommitted
Make single-element enum default to u0
* Allow comptime_int as explicit enum tag type Closes #2997
1 parent 742abc7 commit eb7d36a

File tree

3 files changed

+38
-9
lines changed

3 files changed

+38
-9
lines changed

src/analyze.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2406,8 +2406,6 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
24062406
ZigType *tag_int_type;
24072407
if (enum_type->data.enumeration.layout == ContainerLayoutExtern) {
24082408
tag_int_type = get_c_int_type(g, CIntTypeInt);
2409-
} else if (enum_type->data.enumeration.layout == ContainerLayoutAuto && field_count == 1) {
2410-
tag_int_type = g->builtin_types.entry_num_lit_int;
24112409
} else {
24122410
tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
24132411
}
@@ -2420,7 +2418,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
24202418
ZigType *wanted_tag_int_type = analyze_type_expr(g, scope, decl_node->data.container_decl.init_arg_expr);
24212419
if (type_is_invalid(wanted_tag_int_type)) {
24222420
enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2423-
} else if (wanted_tag_int_type->id != ZigTypeIdInt) {
2421+
} else if (wanted_tag_int_type->id != ZigTypeIdInt &&
2422+
wanted_tag_int_type->id != ZigTypeIdComptimeInt) {
24242423
enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
24252424
add_node_error(g, decl_node->data.container_decl.init_arg_expr,
24262425
buf_sprintf("expected integer, found '%s'", buf_ptr(&wanted_tag_int_type->name)));
@@ -2806,14 +2805,12 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
28062805
union_type->data.unionation.resolve_status = ResolveStatusInvalid;
28072806
return ErrorSemanticAnalyzeFail;
28082807
}
2809-
if (tag_int_type->id != ZigTypeIdInt) {
2808+
if (tag_int_type->id != ZigTypeIdInt && tag_int_type->id != ZigTypeIdComptimeInt) {
28102809
add_node_error(g, enum_type_node,
28112810
buf_sprintf("expected integer tag type, found '%s'", buf_ptr(&tag_int_type->name)));
28122811
union_type->data.unionation.resolve_status = ResolveStatusInvalid;
28132812
return ErrorSemanticAnalyzeFail;
28142813
}
2815-
} else if (auto_layout && field_count == 1) {
2816-
tag_int_type = g->builtin_types.entry_num_lit_int;
28172814
} else {
28182815
tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
28192816
}

test/stage1/behavior/enum.zig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,3 +1014,19 @@ test "enum with one member and u1 tag type @enumToInt" {
10141014
};
10151015
expect(@enumToInt(Enum.Test) == 0);
10161016
}
1017+
1018+
test "enum with comptime_int tag type" {
1019+
const Enum = enum(comptime_int) {
1020+
One = 3,
1021+
Two = 2,
1022+
Three = 1,
1023+
};
1024+
comptime expect(@TagType(Enum) == comptime_int);
1025+
}
1026+
1027+
test "enum with one member default to u0 tag type" {
1028+
const E0 = enum {
1029+
X,
1030+
};
1031+
comptime expect(@TagType(E0) == u0);
1032+
}

test/stage1/behavior/union.zig

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ test "union with only 1 field casted to its enum type" {
324324

325325
var e = Expr{ .Literal = Literal{ .Bool = true } };
326326
const Tag = @TagType(Expr);
327-
comptime expect(@TagType(Tag) == comptime_int);
327+
comptime expect(@TagType(Tag) == u0);
328328
var t = Tag(e);
329329
expect(t == Expr.Literal);
330330
}
@@ -335,7 +335,7 @@ test "union with only 1 field casted to its enum type which has enum value speci
335335
Bool: bool,
336336
};
337337

338-
const Tag = enum {
338+
const Tag = enum(comptime_int) {
339339
Literal = 33,
340340
};
341341

@@ -469,7 +469,7 @@ test "union no tag with struct member" {
469469
}
470470

471471
fn testComparison() void {
472-
var x = Payload{.A = 42};
472+
var x = Payload{ .A = 42 };
473473
expect(x == .A);
474474
expect(x != .B);
475475
expect(x != .C);
@@ -494,3 +494,19 @@ test "packed union generates correctly aligned LLVM type" {
494494
};
495495
foo[0].f1();
496496
}
497+
498+
test "union with one member defaults to u0 tag type" {
499+
const U0 = union(enum) {
500+
X: u32,
501+
};
502+
comptime expect(@TagType(@TagType(U0)) == u0);
503+
}
504+
505+
test "union with comptime_int tag" {
506+
const Union = union(enum(comptime_int)) {
507+
X: u32,
508+
Y: u16,
509+
Z: u8,
510+
};
511+
comptime expect(@TagType(@TagType(Union)) == comptime_int);
512+
}

0 commit comments

Comments
 (0)