authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-16 22:48:01+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-16 22:52:10+02:00
log6c8f01dcde03380806338758d489c3f2a78e5b5b
tree138593beebb1e6712b56d3e35e7d299ce54ef962
parent6450736c5f9039565802e1f898a8fd402ba12c63
signaturelock-open Commit is signed but in an unrecognized format.

correct field count


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

src/analyze.cpp+31-29
...@@ -2569,16 +2569,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {...@@ -2569,16 +2569,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
2569 return ErrorSemanticAnalyzeFail;2569 return ErrorSemanticAnalyzeFail;
2570 }2570 }
25712571
2572 enum_type->data.enumeration.src_field_count = field_count;
2573 enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count);
2574 enum_type->data.enumeration.fields_by_name.init(field_count);
2575 enum_type->data.enumeration.non_exhaustive = false;
2576
2577 Scope *scope = &enum_type->data.enumeration.decls_scope->base;2572 Scope *scope = &enum_type->data.enumeration.decls_scope->base;
25782573
2579 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {};
2580 occupied_tag_values.init(field_count);
2581
2582 ZigType *tag_int_type;2574 ZigType *tag_int_type;
2583 if (enum_type->data.enumeration.layout == ContainerLayoutExtern) {2575 if (enum_type->data.enumeration.layout == ContainerLayoutExtern) {
2584 tag_int_type = get_c_int_type(g, CIntTypeInt);2576 tag_int_type = get_c_int_type(g, CIntTypeInt);
...@@ -2620,6 +2612,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {...@@ -2620,6 +2612,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
2620 }2612 }
2621 }2613 }
26222614
2615 enum_type->data.enumeration.non_exhaustive = false;
2623 enum_type->data.enumeration.tag_int_type = tag_int_type;2616 enum_type->data.enumeration.tag_int_type = tag_int_type;
2624 enum_type->size_in_bits = tag_int_type->size_in_bits;2617 enum_type->size_in_bits = tag_int_type->size_in_bits;
2625 enum_type->abi_size = tag_int_type->abi_size;2618 enum_type->abi_size = tag_int_type->abi_size;
...@@ -2628,6 +2621,31 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {...@@ -2628,6 +2621,31 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
2628 BigInt bi_one;2621 BigInt bi_one;
2629 bigint_init_unsigned(&bi_one, 1);2622 bigint_init_unsigned(&bi_one, 1);
26302623
2624 AstNode *last_field_node = decl_node->data.container_decl.fields.at(field_count - 1);
2625 if (buf_eql_str(last_field_node->data.struct_field.name, "_")) {
2626 field_count -= 1;
2627 if (field_count > 1 && log2_u64(field_count) == enum_type->size_in_bits) {
2628 add_node_error(g, last_field_node, buf_sprintf("non-exhaustive enum specifies every value"));
2629 enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2630 }
2631 if (decl_node->data.container_decl.init_arg_expr == nullptr) {
2632 add_node_error(g, last_field_node, buf_sprintf("non-exhaustive enum must specify size"));
2633 enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2634 }
2635 if (last_field_node->data.struct_field.value != nullptr) {
2636 add_node_error(g, last_field_node, buf_sprintf("value assigned to '_' field of non-exhaustive enum"));
2637 enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2638 }
2639 enum_type->data.enumeration.non_exhaustive = true;
2640 }
2641
2642 enum_type->data.enumeration.src_field_count = field_count;
2643 enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count);
2644 enum_type->data.enumeration.fields_by_name.init(field_count);
2645
2646 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {};
2647 occupied_tag_values.init(field_count);
2648
2631 TypeEnumField *last_enum_field = nullptr;2649 TypeEnumField *last_enum_field = nullptr;
26322650
2633 for (uint32_t field_i = 0; field_i < field_count; field_i += 1) {2651 for (uint32_t field_i = 0; field_i < field_count; field_i += 1) {
...@@ -2649,27 +2667,9 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {...@@ -2649,27 +2667,9 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
2649 buf_sprintf("consider 'union(enum)' here"));2667 buf_sprintf("consider 'union(enum)' here"));
2650 }2668 }
26512669
2652 AstNode *tag_value = field_node->data.struct_field.value;
2653
2654 if (buf_eql_str(type_enum_field->name, "_")) {2670 if (buf_eql_str(type_enum_field->name, "_")) {
2655 if (decl_node->data.container_decl.init_arg_expr == nullptr) {2671 add_node_error(g, field_node, buf_sprintf("'_' field of non-exhaustive enum must be last"));
2656 add_node_error(g, field_node, buf_sprintf("non-exhaustive enum must specify size"));2672 enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2657 enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2658 }
2659 if (field_count > 1 && log2_u64(field_count - 1) == enum_type->size_in_bits) {
2660 add_node_error(g, field_node, buf_sprintf("non-exhaustive enum specifies every value"));
2661 enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2662 }
2663 if (field_i != field_count - 1) {
2664 add_node_error(g, field_node, buf_sprintf("'_' field of non-exhaustive enum must be last"));
2665 enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2666 }
2667 if (tag_value != nullptr) {
2668 add_node_error(g, field_node, buf_sprintf("value assigned to '_' field of non-exhaustive enum"));
2669 enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2670 }
2671 enum_type->data.enumeration.non_exhaustive = true;
2672 continue;
2673 }2673 }
26742674
2675 auto field_entry = enum_type->data.enumeration.fields_by_name.put_unique(type_enum_field->name, type_enum_field);2675 auto field_entry = enum_type->data.enumeration.fields_by_name.put_unique(type_enum_field->name, type_enum_field);
...@@ -2681,6 +2681,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {...@@ -2681,6 +2681,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
2681 continue;2681 continue;
2682 }2682 }
26832683
2684 AstNode *tag_value = field_node->data.struct_field.value;
2685
2684 if (tag_value != nullptr) {2686 if (tag_value != nullptr) {
2685 // A user-specified value is available2687 // A user-specified value is available
2686 ZigValue *result = analyze_const_value(g, scope, tag_value, tag_int_type,2688 ZigValue *result = analyze_const_value(g, scope, tag_value, tag_int_type,
...@@ -3293,7 +3295,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {...@@ -3293,7 +3295,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
3293 } else if (enum_type_node != nullptr) {3295 } else if (enum_type_node != nullptr) {
3294 for (uint32_t i = 0; i < tag_type->data.enumeration.src_field_count; i += 1) {3296 for (uint32_t i = 0; i < tag_type->data.enumeration.src_field_count; i += 1) {
3295 TypeEnumField *enum_field = &tag_type->data.enumeration.fields[i];3297 TypeEnumField *enum_field = &tag_type->data.enumeration.fields[i];
3296 if (!covered_enum_fields[i] && !buf_eql_str(enum_field->name, "_")) {3298 if (!covered_enum_fields[i]) {
3297 AstNode *enum_decl_node = tag_type->data.enumeration.decl_node;3299 AstNode *enum_decl_node = tag_type->data.enumeration.decl_node;
3298 AstNode *field_node = enum_decl_node->data.container_decl.fields.at(i);3300 AstNode *field_node = enum_decl_node->data.container_decl.fields.at(i);
3299 ErrorMsg *msg = add_node_error(g, decl_node,3301 ErrorMsg *msg = add_node_error(g, decl_node,
test/compile_errors.zig+6
...@@ -13,9 +13,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -13,9 +13,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
13 \\ _,13 \\ _,
14 \\ b,14 \\ b,
15 \\};15 \\};
16 \\const C = enum(u1) {
17 \\ a,
18 \\ b,
19 \\ _,
20 \\};
16 \\pub export fn entry() void {21 \\pub export fn entry() void {
17 \\ _ = A;22 \\ _ = A;
18 \\ _ = B;23 \\ _ = B;
24 \\ _ = C;
19 \\}25 \\}
20 , &[_][]const u8{26 , &[_][]const u8{
21 "tmp.zig:4:5: error: non-exhaustive enum must specify size",27 "tmp.zig:4:5: error: non-exhaustive enum must specify size",
test/stage1/behavior/enum.zig+1
...@@ -41,6 +41,7 @@ test "non-exhaustive enum" {...@@ -41,6 +41,7 @@ test "non-exhaustive enum" {
41 .b => {},41 .b => {},
42 else => {},42 else => {},
43 }43 }
44 expect(@typeInfo(E).Enum.fields.len == 2);
44 expect(@enumToInt(e) == 1);45 expect(@enumToInt(e) == 1);
45 e = @intToEnum(E, 12);46 e = @intToEnum(E, 12);
46 expect(@enumToInt(e) == 12);47 expect(@enumToInt(e) == 12);