authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-09-13 12:12:12+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-09-13 15:13:10-04:00
logeb7d36ae0d240b8ef5421703e613d164cf691d8d
tree8ff235e5c307160217500b7ed7e51906dc06f3b5
parent742abc71c75a3448526c14980d0daae1c6ff8f96

Make single-element enum default to u0

* Allow comptime_int as explicit enum tag type Closes #2997

3 files changed, 38 insertions(+), 9 deletions(-)

src/analyze.cpp+3-6
...@@ -2406,8 +2406,6 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {...@@ -2406,8 +2406,6 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
2406 ZigType *tag_int_type;2406 ZigType *tag_int_type;
2407 if (enum_type->data.enumeration.layout == ContainerLayoutExtern) {2407 if (enum_type->data.enumeration.layout == ContainerLayoutExtern) {
2408 tag_int_type = get_c_int_type(g, CIntTypeInt);2408 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;
2411 } else {2409 } else {
2412 tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);2410 tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
2413 }2411 }
...@@ -2420,7 +2418,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {...@@ -2420,7 +2418,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
2420 ZigType *wanted_tag_int_type = analyze_type_expr(g, scope, decl_node->data.container_decl.init_arg_expr);2418 ZigType *wanted_tag_int_type = analyze_type_expr(g, scope, decl_node->data.container_decl.init_arg_expr);
2421 if (type_is_invalid(wanted_tag_int_type)) {2419 if (type_is_invalid(wanted_tag_int_type)) {
2422 enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;2420 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) {
2424 enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;2423 enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2425 add_node_error(g, decl_node->data.container_decl.init_arg_expr,2424 add_node_error(g, decl_node->data.container_decl.init_arg_expr,
2426 buf_sprintf("expected integer, found '%s'", buf_ptr(&wanted_tag_int_type->name)));2425 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) {...@@ -2806,14 +2805,12 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
2806 union_type->data.unionation.resolve_status = ResolveStatusInvalid;2805 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2807 return ErrorSemanticAnalyzeFail;2806 return ErrorSemanticAnalyzeFail;
2808 }2807 }
2809 if (tag_int_type->id != ZigTypeIdInt) {2808 if (tag_int_type->id != ZigTypeIdInt && tag_int_type->id != ZigTypeIdComptimeInt) {
2810 add_node_error(g, enum_type_node,2809 add_node_error(g, enum_type_node,
2811 buf_sprintf("expected integer tag type, found '%s'", buf_ptr(&tag_int_type->name)));2810 buf_sprintf("expected integer tag type, found '%s'", buf_ptr(&tag_int_type->name)));
2812 union_type->data.unionation.resolve_status = ResolveStatusInvalid;2811 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2813 return ErrorSemanticAnalyzeFail;2812 return ErrorSemanticAnalyzeFail;
2814 }2813 }
2815 } else if (auto_layout && field_count == 1) {
2816 tag_int_type = g->builtin_types.entry_num_lit_int;
2817 } else {2814 } else {
2818 tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);2815 tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
2819 }2816 }
test/stage1/behavior/enum.zig+16
...@@ -1014,3 +1014,19 @@ test "enum with one member and u1 tag type @enumToInt" {...@@ -1014,3 +1014,19 @@ test "enum with one member and u1 tag type @enumToInt" {
1014 };1014 };
1015 expect(@enumToInt(Enum.Test) == 0);1015 expect(@enumToInt(Enum.Test) == 0);
1016}1016}
1017
1018test "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
1027test "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+19-3
...@@ -324,7 +324,7 @@ test "union with only 1 field casted to its enum type" {...@@ -324,7 +324,7 @@ test "union with only 1 field casted to its enum type" {
324324
325 var e = Expr{ .Literal = Literal{ .Bool = true } };325 var e = Expr{ .Literal = Literal{ .Bool = true } };
326 const Tag = @TagType(Expr);326 const Tag = @TagType(Expr);
327 comptime expect(@TagType(Tag) == comptime_int);327 comptime expect(@TagType(Tag) == u0);
328 var t = Tag(e);328 var t = Tag(e);
329 expect(t == Expr.Literal);329 expect(t == Expr.Literal);
330}330}
...@@ -335,7 +335,7 @@ test "union with only 1 field casted to its enum type which has enum value speci...@@ -335,7 +335,7 @@ test "union with only 1 field casted to its enum type which has enum value speci
335 Bool: bool,335 Bool: bool,
336 };336 };
337337
338 const Tag = enum {338 const Tag = enum(comptime_int) {
339 Literal = 33,339 Literal = 33,
340 };340 };
341341
...@@ -469,7 +469,7 @@ test "union no tag with struct member" {...@@ -469,7 +469,7 @@ test "union no tag with struct member" {
469}469}
470470
471fn testComparison() void {471fn testComparison() void {
472 var x = Payload{.A = 42};472 var x = Payload{ .A = 42 };
473 expect(x == .A);473 expect(x == .A);
474 expect(x != .B);474 expect(x != .B);
475 expect(x != .C);475 expect(x != .C);
...@@ -494,3 +494,19 @@ test "packed union generates correctly aligned LLVM type" {...@@ -494,3 +494,19 @@ test "packed union generates correctly aligned LLVM type" {
494 };494 };
495 foo[0].f1();495 foo[0].f1();
496}496}
497
498test "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
505test "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}