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
signature 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) {
25692569 return ErrorSemanticAnalyzeFail;
25702570 }
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
25772572 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
25822574 ZigType *tag_int_type;
25832575 if (enum_type->data.enumeration.layout == ContainerLayoutExtern) {
25842576 tag_int_type = get_c_int_type(g, CIntTypeInt);
......@@ -2620,6 +2612,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
26202612 }
26212613 }
26222614
2615 enum_type->data.enumeration.non_exhaustive = false;
26232616 enum_type->data.enumeration.tag_int_type = tag_int_type;
26242617 enum_type->size_in_bits = tag_int_type->size_in_bits;
26252618 enum_type->abi_size = tag_int_type->abi_size;
......@@ -2628,6 +2621,31 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
26282621 BigInt bi_one;
26292622 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
26312649 TypeEnumField *last_enum_field = nullptr;
26322650
26332651 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) {
26492667 buf_sprintf("consider 'union(enum)' here"));
26502668 }
26512669
2652 AstNode *tag_value = field_node->data.struct_field.value;
2653
26542670 if (buf_eql_str(type_enum_field->name, "_")) {
2655 if (decl_node->data.container_decl.init_arg_expr == nullptr) {
2656 add_node_error(g, field_node, buf_sprintf("non-exhaustive enum must specify size"));
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;
2671 add_node_error(g, field_node, buf_sprintf("'_' field of non-exhaustive enum must be last"));
2672 enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
26732673 }
26742674
26752675 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) {
26812681 continue;
26822682 }
26832683
2684 AstNode *tag_value = field_node->data.struct_field.value;
2685
26842686 if (tag_value != nullptr) {
26852687 // A user-specified value is available
26862688 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) {
32933295 } else if (enum_type_node != nullptr) {
32943296 for (uint32_t i = 0; i < tag_type->data.enumeration.src_field_count; i += 1) {
32953297 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]) {
32973299 AstNode *enum_decl_node = tag_type->data.enumeration.decl_node;
32983300 AstNode *field_node = enum_decl_node->data.container_decl.fields.at(i);
32993301 ErrorMsg *msg = add_node_error(g, decl_node,
test/compile_errors.zig+6
......@@ -13,9 +13,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1313 \\ _,
1414 \\ b,
1515 \\};
16 \\const C = enum(u1) {
17 \\ a,
18 \\ b,
19 \\ _,
20 \\};
1621 \\pub export fn entry() void {
1722 \\ _ = A;
1823 \\ _ = B;
24 \\ _ = C;
1925 \\}
2026 , &[_][]const u8{
2127 "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" {
4141 .b => {},
4242 else => {},
4343 }
44 expect(@typeInfo(E).Enum.fields.len == 2);
4445 expect(@enumToInt(e) == 1);
4546 e = @intToEnum(E, 12);
4647 expect(@enumToInt(e) == 12);